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