forked from mirrors/gecko-dev
		
	 ae9bf670e5
			
		
	
	
		ae9bf670e5
		
	
	
	
	
		
			
			Previously, we checked this but only if there was a texture bound to the tex unit. However technically we're supposed to check regardless. ANGLE and Mesa both do, which causes this error. Differential Revision: https://phabricator.services.mozilla.com/D153422
		
			
				
	
	
		
			601 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			601 lines
		
	
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- 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 (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
 |