1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "WebGLContextUtils.h"
7 #include "WebGLContext.h"
8 #include "HostWebGLContext.h"
9 #include "GLContext.h"
10 #include "jsapi.h"
11 #include "js/Warnings.h"  // JS::WarnASCII
12 #include "mozilla/dom/ScriptSettings.h"
13 #include "mozilla/gfx/Logging.h"
14 #include "mozilla/Preferences.h"
15 #include "mozilla/Sprintf.h"
16 #include "nsPrintfCString.h"
17 #include "nsServiceManagerUtils.h"
18 #include <stdarg.h>
19 #include "WebGLBuffer.h"
20 #include "WebGLExtensions.h"
21 #include "WebGLFramebuffer.h"
22 #include "WebGLProgram.h"
23 #include "WebGLTexture.h"
24 #include "WebGLVertexArray.h"
25 
26 namespace mozilla {
27 
TexImageTargetToTexTarget(TexImageTarget texImageTarget)28 TexTarget TexImageTargetToTexTarget(TexImageTarget texImageTarget) {
29   switch (texImageTarget.get()) {
30     case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
31     case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
32     case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
33     case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
34     case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
35     case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
36       return LOCAL_GL_TEXTURE_CUBE_MAP;
37 
38     default:
39       return texImageTarget.get();
40   }
41 }
42 
ErrorName(GLenum error)43 /*static*/ const char* WebGLContext::ErrorName(GLenum error) {
44   switch (error) {
45     case LOCAL_GL_INVALID_ENUM:
46       return "INVALID_ENUM";
47     case LOCAL_GL_INVALID_OPERATION:
48       return "INVALID_OPERATION";
49     case LOCAL_GL_INVALID_VALUE:
50       return "INVALID_VALUE";
51     case LOCAL_GL_OUT_OF_MEMORY:
52       return "OUT_OF_MEMORY";
53     case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION:
54       return "INVALID_FRAMEBUFFER_OPERATION";
55     case LOCAL_GL_NO_ERROR:
56       return "NO_ERROR";
57     default:
58       MOZ_ASSERT(false);
59       return "[unknown WebGL error]";
60   }
61 }
62 
63 // This version is fallible and will return nullptr if unrecognized.
GetEnumName(const GLenum val,const char * const defaultRet)64 const char* GetEnumName(const GLenum val, const char* const defaultRet) {
65   switch (val) {
66     case 0:
67       return "0";
68 #define XX(x)        \
69   case LOCAL_GL_##x: \
70     return #x;
71       // XX(NONE)
72       XX(ALPHA)
73       XX(COMPRESSED_RGBA_PVRTC_2BPPV1)
74       XX(COMPRESSED_RGBA_PVRTC_4BPPV1)
75       XX(COMPRESSED_RGBA_S3TC_DXT1_EXT)
76       XX(COMPRESSED_RGBA_S3TC_DXT3_EXT)
77       XX(COMPRESSED_RGBA_S3TC_DXT5_EXT)
78       XX(COMPRESSED_RGB_PVRTC_2BPPV1)
79       XX(COMPRESSED_RGB_PVRTC_4BPPV1)
80       XX(COMPRESSED_RGB_S3TC_DXT1_EXT)
81       XX(DEPTH_ATTACHMENT)
82       XX(DEPTH_COMPONENT)
83       XX(DEPTH_COMPONENT16)
84       XX(DEPTH_COMPONENT32)
85       XX(DEPTH_STENCIL)
86       XX(DEPTH24_STENCIL8)
87       XX(DRAW_FRAMEBUFFER)
88       XX(ETC1_RGB8_OES)
89       XX(FLOAT)
90       XX(INT)
91       XX(FRAMEBUFFER)
92       XX(HALF_FLOAT)
93       XX(LUMINANCE)
94       XX(LUMINANCE_ALPHA)
95       XX(READ_FRAMEBUFFER)
96       XX(RGB)
97       XX(RGB16F)
98       XX(RGB32F)
99       XX(RGBA)
100       XX(RGBA16F)
101       XX(RGBA32F)
102       XX(SRGB)
103       XX(SRGB_ALPHA)
104       XX(TEXTURE_2D)
105       XX(TEXTURE_3D)
106       XX(TEXTURE_CUBE_MAP)
107       XX(TEXTURE_CUBE_MAP_NEGATIVE_X)
108       XX(TEXTURE_CUBE_MAP_NEGATIVE_Y)
109       XX(TEXTURE_CUBE_MAP_NEGATIVE_Z)
110       XX(TEXTURE_CUBE_MAP_POSITIVE_X)
111       XX(TEXTURE_CUBE_MAP_POSITIVE_Y)
112       XX(TEXTURE_CUBE_MAP_POSITIVE_Z)
113       XX(UNSIGNED_BYTE)
114       XX(UNSIGNED_INT)
115       XX(UNSIGNED_INT_24_8)
116       XX(UNSIGNED_SHORT)
117       XX(UNSIGNED_SHORT_4_4_4_4)
118       XX(UNSIGNED_SHORT_5_5_5_1)
119       XX(UNSIGNED_SHORT_5_6_5)
120       XX(READ_BUFFER)
121       XX(UNPACK_ROW_LENGTH)
122       XX(UNPACK_SKIP_ROWS)
123       XX(UNPACK_SKIP_PIXELS)
124       XX(PACK_ROW_LENGTH)
125       XX(PACK_SKIP_ROWS)
126       XX(PACK_SKIP_PIXELS)
127       XX(COLOR)
128       XX(DEPTH)
129       XX(STENCIL)
130       XX(RED)
131       XX(RGB8)
132       XX(RGBA8)
133       XX(RGB10_A2)
134       XX(TEXTURE_BINDING_3D)
135       XX(UNPACK_SKIP_IMAGES)
136       XX(UNPACK_IMAGE_HEIGHT)
137       XX(TEXTURE_WRAP_R)
138       XX(MAX_3D_TEXTURE_SIZE)
139       XX(UNSIGNED_INT_2_10_10_10_REV)
140       XX(MAX_ELEMENTS_VERTICES)
141       XX(MAX_ELEMENTS_INDICES)
142       XX(TEXTURE_MIN_LOD)
143       XX(TEXTURE_MAX_LOD)
144       XX(TEXTURE_BASE_LEVEL)
145       XX(TEXTURE_MAX_LEVEL)
146       XX(MIN)
147       XX(MAX)
148       XX(DEPTH_COMPONENT24)
149       XX(MAX_TEXTURE_LOD_BIAS)
150       XX(TEXTURE_COMPARE_MODE)
151       XX(TEXTURE_COMPARE_FUNC)
152       XX(CURRENT_QUERY)
153       XX(QUERY_RESULT)
154       XX(QUERY_RESULT_AVAILABLE)
155       XX(STREAM_READ)
156       XX(STREAM_COPY)
157       XX(STATIC_READ)
158       XX(STATIC_COPY)
159       XX(DYNAMIC_READ)
160       XX(DYNAMIC_COPY)
161       XX(MAX_DRAW_BUFFERS)
162       XX(DRAW_BUFFER0)
163       XX(DRAW_BUFFER1)
164       XX(DRAW_BUFFER2)
165       XX(DRAW_BUFFER3)
166       XX(DRAW_BUFFER4)
167       XX(DRAW_BUFFER5)
168       XX(DRAW_BUFFER6)
169       XX(DRAW_BUFFER7)
170       XX(DRAW_BUFFER8)
171       XX(DRAW_BUFFER9)
172       XX(DRAW_BUFFER10)
173       XX(DRAW_BUFFER11)
174       XX(DRAW_BUFFER12)
175       XX(DRAW_BUFFER13)
176       XX(DRAW_BUFFER14)
177       XX(DRAW_BUFFER15)
178       XX(MAX_FRAGMENT_UNIFORM_COMPONENTS)
179       XX(MAX_VERTEX_UNIFORM_COMPONENTS)
180       XX(SAMPLER_3D)
181       XX(SAMPLER_2D_SHADOW)
182       XX(FRAGMENT_SHADER_DERIVATIVE_HINT)
183       XX(PIXEL_PACK_BUFFER)
184       XX(PIXEL_UNPACK_BUFFER)
185       XX(PIXEL_PACK_BUFFER_BINDING)
186       XX(PIXEL_UNPACK_BUFFER_BINDING)
187       XX(FLOAT_MAT2x3)
188       XX(FLOAT_MAT2x4)
189       XX(FLOAT_MAT3x2)
190       XX(FLOAT_MAT3x4)
191       XX(FLOAT_MAT4x2)
192       XX(FLOAT_MAT4x3)
193       XX(SRGB8)
194       XX(SRGB8_ALPHA8)
195       XX(COMPARE_REF_TO_TEXTURE)
196       XX(VERTEX_ATTRIB_ARRAY_INTEGER)
197       XX(MAX_ARRAY_TEXTURE_LAYERS)
198       XX(MIN_PROGRAM_TEXEL_OFFSET)
199       XX(MAX_PROGRAM_TEXEL_OFFSET)
200       XX(MAX_VARYING_COMPONENTS)
201       XX(TEXTURE_2D_ARRAY)
202       XX(TEXTURE_BINDING_2D_ARRAY)
203       XX(R11F_G11F_B10F)
204       XX(UNSIGNED_INT_10F_11F_11F_REV)
205       XX(RGB9_E5)
206       XX(UNSIGNED_INT_5_9_9_9_REV)
207       XX(TRANSFORM_FEEDBACK_BUFFER_MODE)
208       XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS)
209       XX(TRANSFORM_FEEDBACK_VARYINGS)
210       XX(TRANSFORM_FEEDBACK_BUFFER_START)
211       XX(TRANSFORM_FEEDBACK_BUFFER_SIZE)
212       XX(TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN)
213       XX(RASTERIZER_DISCARD)
214       XX(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)
215       XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS)
216       XX(INTERLEAVED_ATTRIBS)
217       XX(SEPARATE_ATTRIBS)
218       XX(TRANSFORM_FEEDBACK_BUFFER)
219       XX(TRANSFORM_FEEDBACK_BUFFER_BINDING)
220       XX(RGBA32UI)
221       XX(RGB32UI)
222       XX(RGBA16UI)
223       XX(RGB16UI)
224       XX(RGBA8UI)
225       XX(RGB8UI)
226       XX(RGBA32I)
227       XX(RGB32I)
228       XX(RGBA16I)
229       XX(RGB16I)
230       XX(RGBA8I)
231       XX(RGB8I)
232       XX(RED_INTEGER)
233       XX(RGB_INTEGER)
234       XX(RGBA_INTEGER)
235       XX(SAMPLER_2D_ARRAY)
236       XX(SAMPLER_2D_ARRAY_SHADOW)
237       XX(SAMPLER_CUBE_SHADOW)
238       XX(UNSIGNED_INT_VEC2)
239       XX(UNSIGNED_INT_VEC3)
240       XX(UNSIGNED_INT_VEC4)
241       XX(INT_SAMPLER_2D)
242       XX(INT_SAMPLER_3D)
243       XX(INT_SAMPLER_CUBE)
244       XX(INT_SAMPLER_2D_ARRAY)
245       XX(UNSIGNED_INT_SAMPLER_2D)
246       XX(UNSIGNED_INT_SAMPLER_3D)
247       XX(UNSIGNED_INT_SAMPLER_CUBE)
248       XX(UNSIGNED_INT_SAMPLER_2D_ARRAY)
249       XX(DEPTH_COMPONENT32F)
250       XX(DEPTH32F_STENCIL8)
251       XX(FLOAT_32_UNSIGNED_INT_24_8_REV)
252       XX(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING)
253       XX(FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE)
254       XX(FRAMEBUFFER_ATTACHMENT_RED_SIZE)
255       XX(FRAMEBUFFER_ATTACHMENT_GREEN_SIZE)
256       XX(FRAMEBUFFER_ATTACHMENT_BLUE_SIZE)
257       XX(FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE)
258       XX(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE)
259       XX(FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE)
260       XX(FRAMEBUFFER_DEFAULT)
261       XX(DEPTH_STENCIL_ATTACHMENT)
262       XX(UNSIGNED_NORMALIZED)
263       XX(DRAW_FRAMEBUFFER_BINDING)
264       XX(READ_FRAMEBUFFER_BINDING)
265       XX(RENDERBUFFER_SAMPLES)
266       XX(FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER)
267       XX(MAX_COLOR_ATTACHMENTS)
268       XX(COLOR_ATTACHMENT0)
269       XX(COLOR_ATTACHMENT1)
270       XX(COLOR_ATTACHMENT2)
271       XX(COLOR_ATTACHMENT3)
272       XX(COLOR_ATTACHMENT4)
273       XX(COLOR_ATTACHMENT5)
274       XX(COLOR_ATTACHMENT6)
275       XX(COLOR_ATTACHMENT7)
276       XX(COLOR_ATTACHMENT8)
277       XX(COLOR_ATTACHMENT9)
278       XX(COLOR_ATTACHMENT10)
279       XX(COLOR_ATTACHMENT11)
280       XX(COLOR_ATTACHMENT12)
281       XX(COLOR_ATTACHMENT13)
282       XX(COLOR_ATTACHMENT14)
283       XX(COLOR_ATTACHMENT15)
284       XX(FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
285       XX(MAX_SAMPLES)
286       XX(RG)
287       XX(RG_INTEGER)
288       XX(R8)
289       XX(RG8)
290       XX(R16F)
291       XX(R32F)
292       XX(RG16F)
293       XX(RG32F)
294       XX(R8I)
295       XX(R8UI)
296       XX(R16I)
297       XX(R16UI)
298       XX(R32I)
299       XX(R32UI)
300       XX(RG8I)
301       XX(RG8UI)
302       XX(RG16I)
303       XX(RG16UI)
304       XX(RG32I)
305       XX(RG32UI)
306       XX(VERTEX_ARRAY_BINDING)
307       XX(R8_SNORM)
308       XX(RG8_SNORM)
309       XX(RGB8_SNORM)
310       XX(RGBA8_SNORM)
311       XX(SIGNED_NORMALIZED)
312       XX(PRIMITIVE_RESTART_FIXED_INDEX)
313       XX(COPY_READ_BUFFER)
314       XX(COPY_WRITE_BUFFER)
315       XX(UNIFORM_BUFFER)
316       XX(UNIFORM_BUFFER_BINDING)
317       XX(UNIFORM_BUFFER_START)
318       XX(UNIFORM_BUFFER_SIZE)
319       XX(MAX_VERTEX_UNIFORM_BLOCKS)
320       XX(MAX_FRAGMENT_UNIFORM_BLOCKS)
321       XX(MAX_COMBINED_UNIFORM_BLOCKS)
322       XX(MAX_UNIFORM_BUFFER_BINDINGS)
323       XX(MAX_UNIFORM_BLOCK_SIZE)
324       XX(MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS)
325       XX(MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS)
326       XX(UNIFORM_BUFFER_OFFSET_ALIGNMENT)
327       XX(ACTIVE_UNIFORM_BLOCKS)
328       XX(UNIFORM_TYPE)
329       XX(UNIFORM_SIZE)
330       XX(UNIFORM_BLOCK_INDEX)
331       XX(UNIFORM_OFFSET)
332       XX(UNIFORM_ARRAY_STRIDE)
333       XX(UNIFORM_MATRIX_STRIDE)
334       XX(UNIFORM_IS_ROW_MAJOR)
335       XX(UNIFORM_BLOCK_BINDING)
336       XX(UNIFORM_BLOCK_DATA_SIZE)
337       XX(UNIFORM_BLOCK_ACTIVE_UNIFORMS)
338       XX(UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
339       XX(UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER)
340       XX(UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER)
341       XX(MAX_VERTEX_OUTPUT_COMPONENTS)
342       XX(MAX_FRAGMENT_INPUT_COMPONENTS)
343       XX(MAX_SERVER_WAIT_TIMEOUT)
344       XX(OBJECT_TYPE)
345       XX(SYNC_CONDITION)
346       XX(SYNC_STATUS)
347       XX(SYNC_FLAGS)
348       XX(SYNC_FENCE)
349       XX(SYNC_GPU_COMMANDS_COMPLETE)
350       XX(UNSIGNALED)
351       XX(SIGNALED)
352       XX(ALREADY_SIGNALED)
353       XX(TIMEOUT_EXPIRED)
354       XX(CONDITION_SATISFIED)
355       XX(WAIT_FAILED)
356       XX(VERTEX_ATTRIB_ARRAY_DIVISOR)
357       XX(ANY_SAMPLES_PASSED)
358       XX(ANY_SAMPLES_PASSED_CONSERVATIVE)
359       XX(SAMPLER_BINDING)
360       XX(RGB10_A2UI)
361       XX(TEXTURE_SWIZZLE_R)
362       XX(TEXTURE_SWIZZLE_G)
363       XX(TEXTURE_SWIZZLE_B)
364       XX(TEXTURE_SWIZZLE_A)
365       XX(GREEN)
366       XX(BLUE)
367       XX(INT_2_10_10_10_REV)
368       XX(TRANSFORM_FEEDBACK)
369       XX(TRANSFORM_FEEDBACK_PAUSED)
370       XX(TRANSFORM_FEEDBACK_ACTIVE)
371       XX(TRANSFORM_FEEDBACK_BINDING)
372       XX(COMPRESSED_R11_EAC)
373       XX(COMPRESSED_SIGNED_R11_EAC)
374       XX(COMPRESSED_RG11_EAC)
375       XX(COMPRESSED_SIGNED_RG11_EAC)
376       XX(COMPRESSED_RGB8_ETC2)
377       XX(COMPRESSED_SRGB8_ETC2)
378       XX(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2)
379       XX(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2)
380       XX(COMPRESSED_RGBA8_ETC2_EAC)
381       XX(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)
382       XX(TEXTURE_IMMUTABLE_FORMAT)
383       XX(MAX_ELEMENT_INDEX)
384       XX(NUM_SAMPLE_COUNTS)
385       XX(TEXTURE_IMMUTABLE_LEVELS)
386 #undef XX
387   }
388 
389   return defaultRet;
390 }
391 
392 /*static*/
EnumName(GLenum val,nsCString * out_name)393 void WebGLContext::EnumName(GLenum val, nsCString* out_name) {
394   const char* name = GetEnumName(val, nullptr);
395   if (name) {
396     *out_name = name;
397     return;
398   }
399 
400   *out_name = nsPrintfCString("<enum 0x%04x>", val);
401 }
402 
EnumString(const GLenum val)403 std::string EnumString(const GLenum val) {
404   const char* name = GetEnumName(val, nullptr);
405   if (name) {
406     return name;
407   }
408 
409   const nsPrintfCString hex("<enum 0x%04x>", val);
410   return hex.BeginReading();
411 }
412 
ErrorInvalidEnumArg(const char * const argName,const GLenum val) const413 void WebGLContext::ErrorInvalidEnumArg(const char* const argName,
414                                        const GLenum val) const {
415   const auto info = nsPrintfCString("Bad `%s`", argName);
416   ErrorInvalidEnumInfo(info.BeginReading(), val);
417 }
418 
ErrorInvalidEnumInfo(const char * const info,const GLenum enumValue) const419 void WebGLContext::ErrorInvalidEnumInfo(const char* const info,
420                                         const GLenum enumValue) const {
421   nsCString name;
422   EnumName(enumValue, &name);
423 
424   const char* hint = "";
425   if (!enumValue) {
426     hint = " (Did you typo `gl.SOMETHINGG` and pass `undefined`?)";
427   }
428 
429   ErrorInvalidEnum("%s: Invalid enum value %s%s", info, name.BeginReading(),
430                    hint);
431 }
432 
433 #ifdef DEBUG
434 // For NaNs, etc.
IsCacheCorrect(float cached,float actual)435 static bool IsCacheCorrect(float cached, float actual) {
436   if (IsNaN(cached)) {
437     // GL is allowed to do anything it wants for NaNs, so if we're shadowing
438     // a NaN, then whatever `actual` is might be correct.
439     return true;
440   }
441 
442   return cached == actual;
443 }
444 
AssertUintParamCorrect(gl::GLContext * gl,GLenum pname,GLuint shadow)445 void AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow) {
446   GLuint val = 0;
447   gl->GetUIntegerv(pname, &val);
448   if (val != shadow) {
449     printf_stderr("Failed 0x%04x shadow: Cached 0x%x/%u, should be 0x%x/%u.\n",
450                   pname, shadow, shadow, val, val);
451     MOZ_ASSERT(false, "Bad cached value.");
452   }
453 }
454 
AssertMaskedUintParamCorrect(gl::GLContext * gl,GLenum pname,GLuint mask,GLuint shadow)455 void AssertMaskedUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint mask,
456                                   GLuint shadow) {
457   GLuint val = 0;
458   gl->GetUIntegerv(pname, &val);
459 
460   const GLuint valMasked = val & mask;
461   const GLuint shadowMasked = shadow & mask;
462 
463   if (valMasked != shadowMasked) {
464     printf_stderr("Failed 0x%04x shadow: Cached 0x%x/%u, should be 0x%x/%u.\n",
465                   pname, shadowMasked, shadowMasked, valMasked, valMasked);
466     MOZ_ASSERT(false, "Bad cached value.");
467   }
468 }
469 #else
AssertUintParamCorrect(gl::GLContext *,GLenum,GLuint)470 void AssertUintParamCorrect(gl::GLContext*, GLenum, GLuint) {}
471 #endif
472 
AssertCachedBindings() const473 void WebGLContext::AssertCachedBindings() const {
474 #ifdef DEBUG
475   gl::GLContext::LocalErrorScope errorScope(*gl);
476 
477   GLint stencilBits = 0;
478   if (GetStencilBits(&stencilBits)) {  // Depends on current draw framebuffer.
479     const GLuint stencilRefMask = (1 << stencilBits) - 1;
480 
481     AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask,
482                                  mStencilRefFront);
483     AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask,
484                                  mStencilRefBack);
485   }
486 
487   // Program
488   GLuint bound = mCurrentProgram ? mCurrentProgram->mGLName : 0;
489   AssertUintParamCorrect(gl, LOCAL_GL_CURRENT_PROGRAM, bound);
490 
491   // Buffers
492   bound = mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0;
493   AssertUintParamCorrect(gl, LOCAL_GL_ARRAY_BUFFER_BINDING, bound);
494 
495   MOZ_ASSERT(mBoundVertexArray);
496   WebGLBuffer* curBuff = mBoundVertexArray->mElementArrayBuffer;
497   bound = curBuff ? curBuff->mGLName : 0;
498   AssertUintParamCorrect(gl, LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING, bound);
499 
500   MOZ_ASSERT(!gl::GLContext::IsBadCallError(errorScope.GetError()));
501 #endif
502 
503   // We do not check the renderbuffer binding, because we never rely on it
504   // matching.
505 }
506 
AssertCachedGlobalState() const507 void WebGLContext::AssertCachedGlobalState() const {
508 #ifdef DEBUG
509   gl::GLContext::LocalErrorScope errorScope(*gl);
510 
511   ////////////////
512 
513   // Draw state
514   MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DITHER) == mDitherEnabled);
515   MOZ_ASSERT_IF(IsWebGL2(), gl->fIsEnabled(LOCAL_GL_RASTERIZER_DISCARD) ==
516                                 mRasterizerDiscardEnabled);
517   MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled);
518 
519   // Cannot trivially check COLOR_CLEAR_VALUE, since in old GL versions glGet
520   // may clamp based on whether the current framebuffer is floating-point or
521   // not. This also means COLOR_CLEAR_VALUE save+restore is dangerous!
522 
523   realGLboolean depthWriteMask = 0;
524   gl->fGetBooleanv(LOCAL_GL_DEPTH_WRITEMASK, &depthWriteMask);
525   MOZ_ASSERT(depthWriteMask == mDepthWriteMask);
526 
527   GLfloat depthClearValue = 0.0f;
528   gl->fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue);
529   MOZ_ASSERT(IsCacheCorrect(mDepthClearValue, depthClearValue));
530 
531   const int maxStencilBits = 8;
532   const GLuint maxStencilBitsMask = (1 << maxStencilBits) - 1;
533   AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE,
534                                maxStencilBitsMask, mStencilClearValue);
535 
536   // GLES 3.0.4, $4.1.4, p177:
537   //   [...] the front and back stencil mask are both set to the value `2^s -
538   //   1`, where `s` is greater than or equal to the number of bits in the
539   //   deepest stencil buffer supported by the GL implementation.
540   AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK,
541                                maxStencilBitsMask, mStencilValueMaskFront);
542   AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK,
543                                maxStencilBitsMask, mStencilValueMaskBack);
544 
545   AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK,
546                                maxStencilBitsMask, mStencilWriteMaskFront);
547   AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK,
548                                maxStencilBitsMask, mStencilWriteMaskBack);
549 
550   // Viewport
551   GLint int4[4] = {0, 0, 0, 0};
552   gl->fGetIntegerv(LOCAL_GL_VIEWPORT, int4);
553   MOZ_ASSERT(int4[0] == mViewportX && int4[1] == mViewportY &&
554              int4[2] == mViewportWidth && int4[3] == mViewportHeight);
555 
556   MOZ_ASSERT(!gl::GLContext::IsBadCallError(errorScope.GetError()));
557 #endif
558 }
559 
InfoFrom(WebGLTexImageFunc func,WebGLTexDimensions dims)560 const char* InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims) {
561   switch (dims) {
562     case WebGLTexDimensions::Tex2D:
563       switch (func) {
564         case WebGLTexImageFunc::TexImage:
565           return "texImage2D";
566         case WebGLTexImageFunc::TexSubImage:
567           return "texSubImage2D";
568         case WebGLTexImageFunc::CopyTexImage:
569           return "copyTexImage2D";
570         case WebGLTexImageFunc::CopyTexSubImage:
571           return "copyTexSubImage2D";
572         case WebGLTexImageFunc::CompTexImage:
573           return "compressedTexImage2D";
574         case WebGLTexImageFunc::CompTexSubImage:
575           return "compressedTexSubImage2D";
576         default:
577           MOZ_CRASH("GFX: invalid 2D TexDimensions");
578       }
579     case WebGLTexDimensions::Tex3D:
580       switch (func) {
581         case WebGLTexImageFunc::TexImage:
582           return "texImage3D";
583         case WebGLTexImageFunc::TexSubImage:
584           return "texSubImage3D";
585         case WebGLTexImageFunc::CopyTexSubImage:
586           return "copyTexSubImage3D";
587         case WebGLTexImageFunc::CompTexSubImage:
588           return "compressedTexSubImage3D";
589         default:
590           MOZ_CRASH("GFX: invalid 3D TexDimensions");
591       }
592     default:
593       MOZ_CRASH("GFX: invalid TexDimensions");
594   }
595 }
596 
597 ////
598 
599 }  // namespace mozilla
600