diff options
Diffstat (limited to 'dom/canvas/WebGLContextUtils.cpp')
-rw-r--r-- | dom/canvas/WebGLContextUtils.cpp | 601 |
1 files changed, 601 insertions, 0 deletions
diff --git a/dom/canvas/WebGLContextUtils.cpp b/dom/canvas/WebGLContextUtils.cpp new file mode 100644 index 0000000000..5fb1d9907e --- /dev/null +++ b/dom/canvas/WebGLContextUtils.cpp @@ -0,0 +1,601 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLContextUtils.h" +#include "WebGLContext.h" +#include "HostWebGLContext.h" +#include "GLContext.h" +#include "jsapi.h" +#include "js/Warnings.h" // JS::WarnASCII +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/gfx/Logging.h" +#include "mozilla/Preferences.h" +#include "mozilla/Sprintf.h" +#include "nsPrintfCString.h" +#include "nsServiceManagerUtils.h" +#include <stdarg.h> +#include "WebGLBuffer.h" +#include "WebGLExtensions.h" +#include "WebGLFramebuffer.h" +#include "WebGLProgram.h" +#include "WebGLTexture.h" +#include "WebGLVertexArray.h" + +namespace mozilla { + +TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget) { + switch (texImageTarget.get()) { + case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return LOCAL_GL_TEXTURE_CUBE_MAP; + + default: + return texImageTarget.get(); + } +} + +/*static*/ const char* WebGLContext::ErrorName(GLenum error) { + switch (error) { + case LOCAL_GL_INVALID_ENUM: + return "INVALID_ENUM"; + case LOCAL_GL_INVALID_OPERATION: + return "INVALID_OPERATION"; + case LOCAL_GL_INVALID_VALUE: + return "INVALID_VALUE"; + case LOCAL_GL_OUT_OF_MEMORY: + return "OUT_OF_MEMORY"; + case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION: + return "INVALID_FRAMEBUFFER_OPERATION"; + case LOCAL_GL_NO_ERROR: + return "NO_ERROR"; + default: + MOZ_ASSERT(false); + return "[unknown WebGL error]"; + } +} + +// This version is fallible and will return nullptr if unrecognized. +const char* GetEnumName(const GLenum val, const char* const defaultRet) { + switch (val) { + case 0: + return "0"; +#define XX(x) \ + case LOCAL_GL_##x: \ + return #x; + // XX(NONE) + XX(ALPHA) + XX(COMPRESSED_RGBA_PVRTC_2BPPV1) + XX(COMPRESSED_RGBA_PVRTC_4BPPV1) + XX(COMPRESSED_RGBA_S3TC_DXT1_EXT) + XX(COMPRESSED_RGBA_S3TC_DXT3_EXT) + XX(COMPRESSED_RGBA_S3TC_DXT5_EXT) + XX(COMPRESSED_RGB_PVRTC_2BPPV1) + XX(COMPRESSED_RGB_PVRTC_4BPPV1) + XX(COMPRESSED_RGB_S3TC_DXT1_EXT) + XX(DEPTH_ATTACHMENT) + XX(DEPTH_COMPONENT) + XX(DEPTH_COMPONENT16) + XX(DEPTH_COMPONENT32) + XX(DEPTH_STENCIL) + XX(DEPTH24_STENCIL8) + XX(DRAW_FRAMEBUFFER) + XX(ETC1_RGB8_OES) + XX(FLOAT) + XX(INT) + XX(FRAMEBUFFER) + XX(HALF_FLOAT) + XX(LUMINANCE) + XX(LUMINANCE_ALPHA) + XX(READ_FRAMEBUFFER) + XX(RGB) + XX(RGB16F) + XX(RGB32F) + XX(RGBA) + XX(RGBA16F) + XX(RGBA32F) + XX(SRGB) + XX(SRGB_ALPHA) + XX(TEXTURE_2D) + XX(TEXTURE_3D) + XX(TEXTURE_CUBE_MAP) + XX(TEXTURE_CUBE_MAP_NEGATIVE_X) + XX(TEXTURE_CUBE_MAP_NEGATIVE_Y) + XX(TEXTURE_CUBE_MAP_NEGATIVE_Z) + XX(TEXTURE_CUBE_MAP_POSITIVE_X) + XX(TEXTURE_CUBE_MAP_POSITIVE_Y) + XX(TEXTURE_CUBE_MAP_POSITIVE_Z) + XX(UNSIGNED_BYTE) + XX(UNSIGNED_INT) + XX(UNSIGNED_INT_24_8) + XX(UNSIGNED_SHORT) + XX(UNSIGNED_SHORT_4_4_4_4) + XX(UNSIGNED_SHORT_5_5_5_1) + XX(UNSIGNED_SHORT_5_6_5) + XX(READ_BUFFER) + XX(UNPACK_ROW_LENGTH) + XX(UNPACK_SKIP_ROWS) + XX(UNPACK_SKIP_PIXELS) + XX(PACK_ROW_LENGTH) + XX(PACK_SKIP_ROWS) + XX(PACK_SKIP_PIXELS) + XX(COLOR) + XX(DEPTH) + XX(STENCIL) + XX(RED) + XX(RGB8) + XX(RGBA8) + XX(RGB10_A2) + XX(TEXTURE_BINDING_3D) + XX(UNPACK_SKIP_IMAGES) + XX(UNPACK_IMAGE_HEIGHT) + XX(TEXTURE_WRAP_R) + XX(MAX_3D_TEXTURE_SIZE) + XX(UNSIGNED_INT_2_10_10_10_REV) + XX(MAX_ELEMENTS_VERTICES) + XX(MAX_ELEMENTS_INDICES) + XX(TEXTURE_MIN_LOD) + XX(TEXTURE_MAX_LOD) + XX(TEXTURE_BASE_LEVEL) + XX(TEXTURE_MAX_LEVEL) + XX(MIN) + XX(MAX) + XX(DEPTH_COMPONENT24) + XX(MAX_TEXTURE_LOD_BIAS) + XX(TEXTURE_COMPARE_MODE) + XX(TEXTURE_COMPARE_FUNC) + XX(CURRENT_QUERY) + XX(QUERY_RESULT) + XX(QUERY_RESULT_AVAILABLE) + XX(STREAM_READ) + XX(STREAM_COPY) + XX(STATIC_READ) + XX(STATIC_COPY) + XX(DYNAMIC_READ) + XX(DYNAMIC_COPY) + XX(MAX_DRAW_BUFFERS) + XX(DRAW_BUFFER0) + XX(DRAW_BUFFER1) + XX(DRAW_BUFFER2) + XX(DRAW_BUFFER3) + XX(DRAW_BUFFER4) + XX(DRAW_BUFFER5) + XX(DRAW_BUFFER6) + XX(DRAW_BUFFER7) + XX(DRAW_BUFFER8) + XX(DRAW_BUFFER9) + XX(DRAW_BUFFER10) + XX(DRAW_BUFFER11) + XX(DRAW_BUFFER12) + XX(DRAW_BUFFER13) + XX(DRAW_BUFFER14) + XX(DRAW_BUFFER15) + XX(MAX_FRAGMENT_UNIFORM_COMPONENTS) + XX(MAX_VERTEX_UNIFORM_COMPONENTS) + XX(FRAGMENT_SHADER_DERIVATIVE_HINT) + XX(PIXEL_PACK_BUFFER) + XX(PIXEL_UNPACK_BUFFER) + XX(PIXEL_PACK_BUFFER_BINDING) + XX(PIXEL_UNPACK_BUFFER_BINDING) + XX(FLOAT_MAT2x3) + XX(FLOAT_MAT2x4) + XX(FLOAT_MAT3x2) + XX(FLOAT_MAT3x4) + XX(FLOAT_MAT4x2) + XX(FLOAT_MAT4x3) + XX(SRGB8) + XX(SRGB8_ALPHA8) + XX(COMPARE_REF_TO_TEXTURE) + XX(VERTEX_ATTRIB_ARRAY_INTEGER) + XX(MAX_ARRAY_TEXTURE_LAYERS) + XX(MIN_PROGRAM_TEXEL_OFFSET) + XX(MAX_PROGRAM_TEXEL_OFFSET) + XX(MAX_VARYING_COMPONENTS) + XX(TEXTURE_2D_ARRAY) + XX(TEXTURE_BINDING_2D_ARRAY) + XX(R11F_G11F_B10F) + XX(UNSIGNED_INT_10F_11F_11F_REV) + XX(RGB9_E5) + XX(UNSIGNED_INT_5_9_9_9_REV) + XX(TRANSFORM_FEEDBACK_BUFFER_MODE) + XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS) + XX(TRANSFORM_FEEDBACK_VARYINGS) + XX(TRANSFORM_FEEDBACK_BUFFER_START) + XX(TRANSFORM_FEEDBACK_BUFFER_SIZE) + XX(TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) + XX(RASTERIZER_DISCARD) + XX(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) + XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS) + XX(INTERLEAVED_ATTRIBS) + XX(SEPARATE_ATTRIBS) + XX(TRANSFORM_FEEDBACK_BUFFER) + XX(TRANSFORM_FEEDBACK_BUFFER_BINDING) + XX(RGBA32UI) + XX(RGB32UI) + XX(RGBA16UI) + XX(RGB16UI) + XX(RGBA8UI) + XX(RGB8UI) + XX(RGBA32I) + XX(RGB32I) + XX(RGBA16I) + XX(RGB16I) + XX(RGBA8I) + XX(RGB8I) + XX(RED_INTEGER) + XX(RGB_INTEGER) + XX(RGBA_INTEGER) + XX(SAMPLER_2D) + XX(SAMPLER_2D_SHADOW) + XX(SAMPLER_CUBE) + XX(SAMPLER_CUBE_SHADOW) + XX(SAMPLER_3D) + XX(SAMPLER_2D_ARRAY) + XX(SAMPLER_2D_ARRAY_SHADOW) + XX(UNSIGNED_INT_VEC2) + XX(UNSIGNED_INT_VEC3) + XX(UNSIGNED_INT_VEC4) + XX(INT_SAMPLER_2D) + XX(INT_SAMPLER_3D) + XX(INT_SAMPLER_CUBE) + XX(INT_SAMPLER_2D_ARRAY) + XX(UNSIGNED_INT_SAMPLER_2D) + XX(UNSIGNED_INT_SAMPLER_3D) + XX(UNSIGNED_INT_SAMPLER_CUBE) + XX(UNSIGNED_INT_SAMPLER_2D_ARRAY) + XX(DEPTH_COMPONENT32F) + XX(DEPTH32F_STENCIL8) + XX(FLOAT_32_UNSIGNED_INT_24_8_REV) + XX(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) + XX(FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE) + XX(FRAMEBUFFER_ATTACHMENT_RED_SIZE) + XX(FRAMEBUFFER_ATTACHMENT_GREEN_SIZE) + XX(FRAMEBUFFER_ATTACHMENT_BLUE_SIZE) + XX(FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE) + XX(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) + XX(FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE) + XX(FRAMEBUFFER_DEFAULT) + XX(DEPTH_STENCIL_ATTACHMENT) + XX(UNSIGNED_NORMALIZED) + XX(DRAW_FRAMEBUFFER_BINDING) + XX(READ_FRAMEBUFFER_BINDING) + XX(RENDERBUFFER_SAMPLES) + XX(FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER) + XX(MAX_COLOR_ATTACHMENTS) + XX(COLOR_ATTACHMENT0) + XX(COLOR_ATTACHMENT1) + XX(COLOR_ATTACHMENT2) + XX(COLOR_ATTACHMENT3) + XX(COLOR_ATTACHMENT4) + XX(COLOR_ATTACHMENT5) + XX(COLOR_ATTACHMENT6) + XX(COLOR_ATTACHMENT7) + XX(COLOR_ATTACHMENT8) + XX(COLOR_ATTACHMENT9) + XX(COLOR_ATTACHMENT10) + XX(COLOR_ATTACHMENT11) + XX(COLOR_ATTACHMENT12) + XX(COLOR_ATTACHMENT13) + XX(COLOR_ATTACHMENT14) + XX(COLOR_ATTACHMENT15) + XX(FRAMEBUFFER_INCOMPLETE_MULTISAMPLE) + XX(MAX_SAMPLES) + XX(RG) + XX(RG_INTEGER) + XX(R8) + XX(RG8) + XX(R16F) + XX(R32F) + XX(RG16F) + XX(RG32F) + XX(R8I) + XX(R8UI) + XX(R16I) + XX(R16UI) + XX(R32I) + XX(R32UI) + XX(RG8I) + XX(RG8UI) + XX(RG16I) + XX(RG16UI) + XX(RG32I) + XX(RG32UI) + XX(VERTEX_ARRAY_BINDING) + XX(R8_SNORM) + XX(RG8_SNORM) + XX(RGB8_SNORM) + XX(RGBA8_SNORM) + XX(SIGNED_NORMALIZED) + XX(PRIMITIVE_RESTART_FIXED_INDEX) + XX(COPY_READ_BUFFER) + XX(COPY_WRITE_BUFFER) + XX(UNIFORM_BUFFER) + XX(UNIFORM_BUFFER_BINDING) + XX(UNIFORM_BUFFER_START) + XX(UNIFORM_BUFFER_SIZE) + XX(MAX_VERTEX_UNIFORM_BLOCKS) + XX(MAX_FRAGMENT_UNIFORM_BLOCKS) + XX(MAX_COMBINED_UNIFORM_BLOCKS) + XX(MAX_UNIFORM_BUFFER_BINDINGS) + XX(MAX_UNIFORM_BLOCK_SIZE) + XX(MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS) + XX(MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS) + XX(UNIFORM_BUFFER_OFFSET_ALIGNMENT) + XX(ACTIVE_UNIFORM_BLOCKS) + XX(UNIFORM_TYPE) + XX(UNIFORM_SIZE) + XX(UNIFORM_BLOCK_INDEX) + XX(UNIFORM_OFFSET) + XX(UNIFORM_ARRAY_STRIDE) + XX(UNIFORM_MATRIX_STRIDE) + XX(UNIFORM_IS_ROW_MAJOR) + XX(UNIFORM_BLOCK_BINDING) + XX(UNIFORM_BLOCK_DATA_SIZE) + XX(UNIFORM_BLOCK_ACTIVE_UNIFORMS) + XX(UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) + XX(UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER) + XX(UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER) + XX(MAX_VERTEX_OUTPUT_COMPONENTS) + XX(MAX_FRAGMENT_INPUT_COMPONENTS) + XX(MAX_SERVER_WAIT_TIMEOUT) + XX(OBJECT_TYPE) + XX(SYNC_CONDITION) + XX(SYNC_STATUS) + XX(SYNC_FLAGS) + XX(SYNC_FENCE) + XX(SYNC_GPU_COMMANDS_COMPLETE) + XX(UNSIGNALED) + XX(SIGNALED) + XX(ALREADY_SIGNALED) + XX(TIMEOUT_EXPIRED) + XX(CONDITION_SATISFIED) + XX(WAIT_FAILED) + XX(VERTEX_ATTRIB_ARRAY_DIVISOR) + XX(ANY_SAMPLES_PASSED) + XX(ANY_SAMPLES_PASSED_CONSERVATIVE) + XX(SAMPLER_BINDING) + XX(RGB10_A2UI) + XX(TEXTURE_SWIZZLE_R) + XX(TEXTURE_SWIZZLE_G) + XX(TEXTURE_SWIZZLE_B) + XX(TEXTURE_SWIZZLE_A) + XX(GREEN) + XX(BLUE) + XX(INT_2_10_10_10_REV) + XX(TRANSFORM_FEEDBACK) + XX(TRANSFORM_FEEDBACK_PAUSED) + XX(TRANSFORM_FEEDBACK_ACTIVE) + XX(TRANSFORM_FEEDBACK_BINDING) + XX(COMPRESSED_R11_EAC) + XX(COMPRESSED_SIGNED_R11_EAC) + XX(COMPRESSED_RG11_EAC) + XX(COMPRESSED_SIGNED_RG11_EAC) + XX(COMPRESSED_RGB8_ETC2) + XX(COMPRESSED_SRGB8_ETC2) + XX(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) + XX(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) + XX(COMPRESSED_RGBA8_ETC2_EAC) + XX(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) + XX(TEXTURE_IMMUTABLE_FORMAT) + XX(MAX_ELEMENT_INDEX) + XX(NUM_SAMPLE_COUNTS) + XX(TEXTURE_IMMUTABLE_LEVELS) +#undef XX + } + + return defaultRet; +} + +/*static*/ +void WebGLContext::EnumName(GLenum val, nsCString* out_name) { + const char* name = GetEnumName(val, nullptr); + if (name) { + *out_name = name; + return; + } + + *out_name = nsPrintfCString("<enum 0x%04x>", val); +} + +std::string EnumString(const GLenum val) { + const char* name = GetEnumName(val, nullptr); + if (name) { + return name; + } + + const nsPrintfCString hex("<enum 0x%04x>", val); + return hex.BeginReading(); +} + +void WebGLContext::ErrorInvalidEnumArg(const char* const argName, + const GLenum val) const { + const auto info = nsPrintfCString("Bad `%s`", argName); + ErrorInvalidEnumInfo(info.BeginReading(), val); +} + +void WebGLContext::ErrorInvalidEnumInfo(const char* const info, + const GLenum enumValue) const { + nsCString name; + EnumName(enumValue, &name); + + const char* hint = ""; + if (!enumValue) { + hint = " (Did you typo `gl.SOMETHINGG` and pass `undefined`?)"; + } + + ErrorInvalidEnum("%s: Invalid enum value %s%s", info, name.BeginReading(), + hint); +} + +#ifdef DEBUG +// For NaNs, etc. +static bool IsCacheCorrect(float cached, float actual) { + if (std::isnan(cached)) { + // GL is allowed to do anything it wants for NaNs, so if we're shadowing + // a NaN, then whatever `actual` is might be correct. + return true; + } + + return cached == actual; +} + +void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow) { + GLuint val = 0; + gl->GetUIntegerv(pname, &val); + if (val != shadow) { + printf_stderr("Failed 0x%04x shadow: Cached 0x%x/%u, should be 0x%x/%u.\n", + pname, shadow, shadow, val, val); + MOZ_ASSERT(false, "Bad cached value."); + } +} + +void AssertMaskedUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint mask, + GLuint shadow) { + GLuint val = 0; + gl->GetUIntegerv(pname, &val); + + const GLuint valMasked = val & mask; + const GLuint shadowMasked = shadow & mask; + + if (valMasked != shadowMasked) { + printf_stderr("Failed 0x%04x shadow: Cached 0x%x/%u, should be 0x%x/%u.\n", + pname, shadowMasked, shadowMasked, valMasked, valMasked); + MOZ_ASSERT(false, "Bad cached value."); + } +} +#else +void AssertUintParamCorrect(gl::GLContext*, GLenum, GLuint) {} +#endif + +void WebGLContext::AssertCachedBindings() const { +#ifdef DEBUG + gl::GLContext::LocalErrorScope errorScope(*gl); + + GLint stencilBits = 0; + if (GetStencilBits(&stencilBits)) { // Depends on current draw framebuffer. + const GLuint stencilRefMask = (1 << stencilBits) - 1; + + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, + mStencilRefFront); + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, + mStencilRefBack); + } + + // Program + GLuint bound = mCurrentProgram ? mCurrentProgram->mGLName : 0; + AssertUintParamCorrect(gl, LOCAL_GL_CURRENT_PROGRAM, bound); + + // Buffers + bound = mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0; + AssertUintParamCorrect(gl, LOCAL_GL_ARRAY_BUFFER_BINDING, bound); + + MOZ_ASSERT(mBoundVertexArray); + WebGLBuffer* curBuff = mBoundVertexArray->mElementArrayBuffer; + bound = curBuff ? curBuff->mGLName : 0; + AssertUintParamCorrect(gl, LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING, bound); + + MOZ_ASSERT(!gl::GLContext::IsBadCallError(errorScope.GetError())); +#endif + + // We do not check the renderbuffer binding, because we never rely on it + // matching. +} + +void WebGLContext::AssertCachedGlobalState() const { +#ifdef DEBUG + gl::GLContext::LocalErrorScope errorScope(*gl); + + //////////////// + + // Draw state + MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DITHER) == mDitherEnabled); + MOZ_ASSERT_IF(IsWebGL2(), gl->fIsEnabled(LOCAL_GL_RASTERIZER_DISCARD) == + mRasterizerDiscardEnabled); + MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled); + + // Cannot trivially check COLOR_CLEAR_VALUE, since in old GL versions glGet + // may clamp based on whether the current framebuffer is floating-point or + // not. This also means COLOR_CLEAR_VALUE save+restore is dangerous! + + realGLboolean depthWriteMask = 0; + gl->fGetBooleanv(LOCAL_GL_DEPTH_WRITEMASK, &depthWriteMask); + MOZ_ASSERT(depthWriteMask == mDepthWriteMask); + + GLfloat depthClearValue = 0.0f; + gl->fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue); + MOZ_ASSERT(IsCacheCorrect(mDepthClearValue, depthClearValue)); + + const int maxStencilBits = 8; + const GLuint maxStencilBitsMask = (1 << maxStencilBits) - 1; + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE, + maxStencilBitsMask, mStencilClearValue); + + // GLES 3.0.4, $4.1.4, p177: + // [...] the front and back stencil mask are both set to the value `2^s - + // 1`, where `s` is greater than or equal to the number of bits in the + // deepest stencil buffer supported by the GL implementation. + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK, + maxStencilBitsMask, mStencilValueMaskFront); + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK, + maxStencilBitsMask, mStencilValueMaskBack); + + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK, + maxStencilBitsMask, mStencilWriteMaskFront); + AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK, + maxStencilBitsMask, mStencilWriteMaskBack); + + // Viewport + GLint int4[4] = {0, 0, 0, 0}; + gl->fGetIntegerv(LOCAL_GL_VIEWPORT, int4); + MOZ_ASSERT(int4[0] == mViewportX && int4[1] == mViewportY && + int4[2] == mViewportWidth && int4[3] == mViewportHeight); + + MOZ_ASSERT(!gl::GLContext::IsBadCallError(errorScope.GetError())); +#endif +} + +const char* InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims) { + switch (dims) { + case WebGLTexDimensions::Tex2D: + switch (func) { + case WebGLTexImageFunc::TexImage: + return "texImage2D"; + case WebGLTexImageFunc::TexSubImage: + return "texSubImage2D"; + case WebGLTexImageFunc::CopyTexImage: + return "copyTexImage2D"; + case WebGLTexImageFunc::CopyTexSubImage: + return "copyTexSubImage2D"; + case WebGLTexImageFunc::CompTexImage: + return "compressedTexImage2D"; + case WebGLTexImageFunc::CompTexSubImage: + return "compressedTexSubImage2D"; + default: + MOZ_CRASH("GFX: invalid 2D TexDimensions"); + } + case WebGLTexDimensions::Tex3D: + switch (func) { + case WebGLTexImageFunc::TexImage: + return "texImage3D"; + case WebGLTexImageFunc::TexSubImage: + return "texSubImage3D"; + case WebGLTexImageFunc::CopyTexSubImage: + return "copyTexSubImage3D"; + case WebGLTexImageFunc::CompTexSubImage: + return "compressedTexSubImage3D"; + default: + MOZ_CRASH("GFX: invalid 3D TexDimensions"); + } + default: + MOZ_CRASH("GFX: invalid TexDimensions"); + } +} + +//// + +} // namespace mozilla |