/src/mozilla-central/dom/canvas/WebGLContextUtils.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
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 | | |
9 | | #include "GLContext.h" |
10 | | #include "jsapi.h" |
11 | | #include "mozilla/dom/ScriptSettings.h" |
12 | | #include "mozilla/gfx/Logging.h" |
13 | | #include "mozilla/Preferences.h" |
14 | | #include "mozilla/Sprintf.h" |
15 | | #include "nsIScriptSecurityManager.h" |
16 | | #include "nsIVariant.h" |
17 | | #include "nsPrintfCString.h" |
18 | | #include "nsServiceManagerUtils.h" |
19 | | #include <stdarg.h> |
20 | | #include "WebGLBuffer.h" |
21 | | #include "WebGLExtensions.h" |
22 | | #include "WebGLFramebuffer.h" |
23 | | #include "WebGLProgram.h" |
24 | | #include "WebGLTexture.h" |
25 | | #include "WebGLVertexArray.h" |
26 | | |
27 | | namespace mozilla { |
28 | | |
29 | | TexTarget |
30 | | TexImageTargetToTexTarget(TexImageTarget texImageTarget) |
31 | 0 | { |
32 | 0 | switch (texImageTarget.get()) { |
33 | 0 | case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X: |
34 | 0 | case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X: |
35 | 0 | case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y: |
36 | 0 | case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: |
37 | 0 | case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z: |
38 | 0 | case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: |
39 | 0 | return LOCAL_GL_TEXTURE_CUBE_MAP; |
40 | 0 |
|
41 | 0 | default: |
42 | 0 | return texImageTarget.get(); |
43 | 0 | } |
44 | 0 | } |
45 | | |
46 | | JS::Value |
47 | | StringValue(JSContext* cx, const char* chars, ErrorResult& rv) |
48 | 0 | { |
49 | 0 | JSString* str = JS_NewStringCopyZ(cx, chars); |
50 | 0 | if (!str) { |
51 | 0 | rv.Throw(NS_ERROR_OUT_OF_MEMORY); |
52 | 0 | return JS::NullValue(); |
53 | 0 | } |
54 | 0 | |
55 | 0 | return JS::StringValue(str); |
56 | 0 | } |
57 | | |
58 | | void |
59 | | WebGLContext::GenerateWarning(const char* fmt, ...) const |
60 | 0 | { |
61 | 0 | va_list ap; |
62 | 0 | va_start(ap, fmt); |
63 | 0 |
|
64 | 0 | GenerateWarning(fmt, ap); |
65 | 0 |
|
66 | 0 | va_end(ap); |
67 | 0 | } |
68 | | |
69 | | void |
70 | | WebGLContext::GenerateWarning(const char* fmt, va_list ap) const |
71 | 0 | { |
72 | 0 | if (!ShouldGenerateWarnings()) |
73 | 0 | return; |
74 | 0 | |
75 | 0 | mAlreadyGeneratedWarnings++; |
76 | 0 |
|
77 | 0 | char buf[1024]; |
78 | 0 | VsprintfLiteral(buf, fmt, ap); |
79 | 0 |
|
80 | 0 | // no need to print to stderr, as JS_ReportWarning takes care of this for us. |
81 | 0 |
|
82 | 0 | if (!mCanvasElement) { |
83 | 0 | return; |
84 | 0 | } |
85 | 0 | |
86 | 0 | dom::AutoJSAPI api; |
87 | 0 | if (!api.Init(mCanvasElement->OwnerDoc()->GetScopeObject())) { |
88 | 0 | return; |
89 | 0 | } |
90 | 0 | |
91 | 0 | JSContext* cx = api.cx(); |
92 | 0 | const auto funcName = FuncName(); |
93 | 0 | JS_ReportWarningASCII(cx, "WebGL warning: %s: %s", funcName, buf); |
94 | 0 | if (!ShouldGenerateWarnings()) { |
95 | 0 | JS_ReportWarningASCII(cx, |
96 | 0 | "WebGL: No further warnings will be reported for" |
97 | 0 | " this WebGL context." |
98 | 0 | " (already reported %d warnings)", |
99 | 0 | mAlreadyGeneratedWarnings); |
100 | 0 | } |
101 | 0 | } |
102 | | |
103 | | bool |
104 | | WebGLContext::ShouldGenerateWarnings() const |
105 | 0 | { |
106 | 0 | if (mMaxWarnings == -1) |
107 | 0 | return true; |
108 | 0 | |
109 | 0 | return mAlreadyGeneratedWarnings < mMaxWarnings; |
110 | 0 | } |
111 | | |
112 | | void |
113 | | WebGLContext::GeneratePerfWarning(const char* fmt, ...) const |
114 | 0 | { |
115 | 0 | if (!ShouldGeneratePerfWarnings()) |
116 | 0 | return; |
117 | 0 | |
118 | 0 | if (!mCanvasElement) |
119 | 0 | return; |
120 | 0 | |
121 | 0 | dom::AutoJSAPI api; |
122 | 0 | if (!api.Init(mCanvasElement->OwnerDoc()->GetScopeObject())) |
123 | 0 | return; |
124 | 0 | JSContext* cx = api.cx(); |
125 | 0 |
|
126 | 0 | //// |
127 | 0 |
|
128 | 0 | va_list ap; |
129 | 0 | va_start(ap, fmt); |
130 | 0 |
|
131 | 0 | char buf[1024]; |
132 | 0 | VsprintfLiteral(buf, fmt, ap); |
133 | 0 |
|
134 | 0 | va_end(ap); |
135 | 0 |
|
136 | 0 | //// |
137 | 0 |
|
138 | 0 | const auto funcName = FuncName(); |
139 | 0 | JS_ReportWarningASCII(cx, "WebGL perf warning: %s: %s", funcName, buf); |
140 | 0 | mNumPerfWarnings++; |
141 | 0 |
|
142 | 0 | if (!ShouldGeneratePerfWarnings()) { |
143 | 0 | JS_ReportWarningASCII(cx, |
144 | 0 | "WebGL: After reporting %u, no further perf warnings will" |
145 | 0 | " be reported for this WebGL context.", |
146 | 0 | uint32_t(mNumPerfWarnings)); |
147 | 0 | } |
148 | 0 | } |
149 | | |
150 | | void |
151 | | WebGLContext::SynthesizeGLError(GLenum err) const |
152 | 0 | { |
153 | 0 | /* ES2 section 2.5 "GL Errors" states that implementations can have |
154 | 0 | * multiple 'flags', as errors might be caught in different parts of |
155 | 0 | * a distributed implementation. |
156 | 0 | * We're signing up as a distributed implementation here, with |
157 | 0 | * separate flags for WebGL and the underlying GLContext. |
158 | 0 | */ |
159 | 0 | if (!mWebGLError) |
160 | 0 | mWebGLError = err; |
161 | 0 | } |
162 | | |
163 | | void |
164 | | WebGLContext::SynthesizeGLError(GLenum err, const char* fmt, ...) const |
165 | 0 | { |
166 | 0 | va_list va; |
167 | 0 | va_start(va, fmt); |
168 | 0 | GenerateWarning(fmt, va); |
169 | 0 | va_end(va); |
170 | 0 |
|
171 | 0 | return SynthesizeGLError(err); |
172 | 0 | } |
173 | | |
174 | | void |
175 | | WebGLContext::ErrorInvalidEnum(const char* fmt, ...) const |
176 | 0 | { |
177 | 0 | va_list va; |
178 | 0 | va_start(va, fmt); |
179 | 0 | GenerateWarning(fmt, va); |
180 | 0 | va_end(va); |
181 | 0 |
|
182 | 0 | return SynthesizeGLError(LOCAL_GL_INVALID_ENUM); |
183 | 0 | } |
184 | | |
185 | | void |
186 | | WebGLContext::ErrorInvalidEnumInfo(const char* info, GLenum enumValue) const |
187 | 0 | { |
188 | 0 | nsCString name; |
189 | 0 | EnumName(enumValue, &name); |
190 | 0 |
|
191 | 0 | return ErrorInvalidEnum("%s: invalid enum value %s", info, name.BeginReading()); |
192 | 0 | } |
193 | | |
194 | | void |
195 | | WebGLContext::ErrorInvalidOperation(const char* fmt, ...) const |
196 | 0 | { |
197 | 0 | va_list va; |
198 | 0 | va_start(va, fmt); |
199 | 0 | GenerateWarning(fmt, va); |
200 | 0 | va_end(va); |
201 | 0 |
|
202 | 0 | return SynthesizeGLError(LOCAL_GL_INVALID_OPERATION); |
203 | 0 | } |
204 | | |
205 | | void |
206 | | WebGLContext::ErrorInvalidValue(const char* fmt, ...) const |
207 | 0 | { |
208 | 0 | va_list va; |
209 | 0 | va_start(va, fmt); |
210 | 0 | GenerateWarning(fmt, va); |
211 | 0 | va_end(va); |
212 | 0 |
|
213 | 0 | return SynthesizeGLError(LOCAL_GL_INVALID_VALUE); |
214 | 0 | } |
215 | | |
216 | | void |
217 | | WebGLContext::ErrorInvalidFramebufferOperation(const char* fmt, ...) const |
218 | 0 | { |
219 | 0 | va_list va; |
220 | 0 | va_start(va, fmt); |
221 | 0 | GenerateWarning(fmt, va); |
222 | 0 | va_end(va); |
223 | 0 |
|
224 | 0 | return SynthesizeGLError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION); |
225 | 0 | } |
226 | | |
227 | | void |
228 | | WebGLContext::ErrorOutOfMemory(const char* fmt, ...) const |
229 | 0 | { |
230 | 0 | va_list va; |
231 | 0 | va_start(va, fmt); |
232 | 0 | GenerateWarning(fmt, va); |
233 | 0 | va_end(va); |
234 | 0 |
|
235 | 0 | return SynthesizeGLError(LOCAL_GL_OUT_OF_MEMORY); |
236 | 0 | } |
237 | | |
238 | | void |
239 | | WebGLContext::ErrorImplementationBug(const char* fmt, ...) const |
240 | 0 | { |
241 | 0 | const nsPrintfCString warning("Implementation bug, please file at %s! %s", |
242 | 0 | "https://bugzilla.mozilla.org/", fmt); |
243 | 0 |
|
244 | 0 | va_list va; |
245 | 0 | va_start(va, fmt); |
246 | 0 | GenerateWarning(warning.BeginReading(), va); |
247 | 0 | va_end(va); |
248 | 0 |
|
249 | 0 | MOZ_ASSERT(false, "WebGLContext::ErrorImplementationBug"); |
250 | 0 | NS_ERROR("WebGLContext::ErrorImplementationBug"); |
251 | 0 | return SynthesizeGLError(LOCAL_GL_OUT_OF_MEMORY); |
252 | 0 | } |
253 | | |
254 | | /*static*/ const char* |
255 | | WebGLContext::ErrorName(GLenum error) |
256 | 0 | { |
257 | 0 | switch(error) { |
258 | 0 | case LOCAL_GL_INVALID_ENUM: |
259 | 0 | return "INVALID_ENUM"; |
260 | 0 | case LOCAL_GL_INVALID_OPERATION: |
261 | 0 | return "INVALID_OPERATION"; |
262 | 0 | case LOCAL_GL_INVALID_VALUE: |
263 | 0 | return "INVALID_VALUE"; |
264 | 0 | case LOCAL_GL_OUT_OF_MEMORY: |
265 | 0 | return "OUT_OF_MEMORY"; |
266 | 0 | case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION: |
267 | 0 | return "INVALID_FRAMEBUFFER_OPERATION"; |
268 | 0 | case LOCAL_GL_NO_ERROR: |
269 | 0 | return "NO_ERROR"; |
270 | 0 | default: |
271 | 0 | MOZ_ASSERT(false); |
272 | 0 | return "[unknown WebGL error]"; |
273 | 0 | } |
274 | 0 | } |
275 | | |
276 | | // This version is fallible and will return nullptr if unrecognized. |
277 | | const char* |
278 | | GetEnumName(const GLenum val, const char* const defaultRet) |
279 | 0 | { |
280 | 0 | switch (val) { |
281 | 0 | #define XX(x) case LOCAL_GL_##x: return #x |
282 | 0 | XX(NONE); |
283 | 0 | XX(ALPHA); |
284 | 0 | XX(ATC_RGB); |
285 | 0 | XX(ATC_RGBA_EXPLICIT_ALPHA); |
286 | 0 | XX(ATC_RGBA_INTERPOLATED_ALPHA); |
287 | 0 | XX(COMPRESSED_RGBA_PVRTC_2BPPV1); |
288 | 0 | XX(COMPRESSED_RGBA_PVRTC_4BPPV1); |
289 | 0 | XX(COMPRESSED_RGBA_S3TC_DXT1_EXT); |
290 | 0 | XX(COMPRESSED_RGBA_S3TC_DXT3_EXT); |
291 | 0 | XX(COMPRESSED_RGBA_S3TC_DXT5_EXT); |
292 | 0 | XX(COMPRESSED_RGB_PVRTC_2BPPV1); |
293 | 0 | XX(COMPRESSED_RGB_PVRTC_4BPPV1); |
294 | 0 | XX(COMPRESSED_RGB_S3TC_DXT1_EXT); |
295 | 0 | XX(DEPTH_ATTACHMENT); |
296 | 0 | XX(DEPTH_COMPONENT); |
297 | 0 | XX(DEPTH_COMPONENT16); |
298 | 0 | XX(DEPTH_COMPONENT32); |
299 | 0 | XX(DEPTH_STENCIL); |
300 | 0 | XX(DEPTH24_STENCIL8); |
301 | 0 | XX(DRAW_FRAMEBUFFER); |
302 | 0 | XX(ETC1_RGB8_OES); |
303 | 0 | XX(FLOAT); |
304 | 0 | XX(INT); |
305 | 0 | XX(FRAMEBUFFER); |
306 | 0 | XX(HALF_FLOAT); |
307 | 0 | XX(LUMINANCE); |
308 | 0 | XX(LUMINANCE_ALPHA); |
309 | 0 | XX(READ_FRAMEBUFFER); |
310 | 0 | XX(RGB); |
311 | 0 | XX(RGB16F); |
312 | 0 | XX(RGB32F); |
313 | 0 | XX(RGBA); |
314 | 0 | XX(RGBA16F); |
315 | 0 | XX(RGBA32F); |
316 | 0 | XX(SRGB); |
317 | 0 | XX(SRGB_ALPHA); |
318 | 0 | XX(TEXTURE_2D); |
319 | 0 | XX(TEXTURE_3D); |
320 | 0 | XX(TEXTURE_CUBE_MAP); |
321 | 0 | XX(TEXTURE_CUBE_MAP_NEGATIVE_X); |
322 | 0 | XX(TEXTURE_CUBE_MAP_NEGATIVE_Y); |
323 | 0 | XX(TEXTURE_CUBE_MAP_NEGATIVE_Z); |
324 | 0 | XX(TEXTURE_CUBE_MAP_POSITIVE_X); |
325 | 0 | XX(TEXTURE_CUBE_MAP_POSITIVE_Y); |
326 | 0 | XX(TEXTURE_CUBE_MAP_POSITIVE_Z); |
327 | 0 | XX(UNSIGNED_BYTE); |
328 | 0 | XX(UNSIGNED_INT); |
329 | 0 | XX(UNSIGNED_INT_24_8); |
330 | 0 | XX(UNSIGNED_SHORT); |
331 | 0 | XX(UNSIGNED_SHORT_4_4_4_4); |
332 | 0 | XX(UNSIGNED_SHORT_5_5_5_1); |
333 | 0 | XX(UNSIGNED_SHORT_5_6_5); |
334 | 0 | XX(READ_BUFFER); |
335 | 0 | XX(UNPACK_ROW_LENGTH); |
336 | 0 | XX(UNPACK_SKIP_ROWS); |
337 | 0 | XX(UNPACK_SKIP_PIXELS); |
338 | 0 | XX(PACK_ROW_LENGTH); |
339 | 0 | XX(PACK_SKIP_ROWS); |
340 | 0 | XX(PACK_SKIP_PIXELS); |
341 | 0 | XX(COLOR); |
342 | 0 | XX(DEPTH); |
343 | 0 | XX(STENCIL); |
344 | 0 | XX(RED); |
345 | 0 | XX(RGB8); |
346 | 0 | XX(RGBA8); |
347 | 0 | XX(RGB10_A2); |
348 | 0 | XX(TEXTURE_BINDING_3D); |
349 | 0 | XX(UNPACK_SKIP_IMAGES); |
350 | 0 | XX(UNPACK_IMAGE_HEIGHT); |
351 | 0 | XX(TEXTURE_WRAP_R); |
352 | 0 | XX(MAX_3D_TEXTURE_SIZE); |
353 | 0 | XX(UNSIGNED_INT_2_10_10_10_REV); |
354 | 0 | XX(MAX_ELEMENTS_VERTICES); |
355 | 0 | XX(MAX_ELEMENTS_INDICES); |
356 | 0 | XX(TEXTURE_MIN_LOD); |
357 | 0 | XX(TEXTURE_MAX_LOD); |
358 | 0 | XX(TEXTURE_BASE_LEVEL); |
359 | 0 | XX(TEXTURE_MAX_LEVEL); |
360 | 0 | XX(MIN); |
361 | 0 | XX(MAX); |
362 | 0 | XX(DEPTH_COMPONENT24); |
363 | 0 | XX(MAX_TEXTURE_LOD_BIAS); |
364 | 0 | XX(TEXTURE_COMPARE_MODE); |
365 | 0 | XX(TEXTURE_COMPARE_FUNC); |
366 | 0 | XX(CURRENT_QUERY); |
367 | 0 | XX(QUERY_RESULT); |
368 | 0 | XX(QUERY_RESULT_AVAILABLE); |
369 | 0 | XX(STREAM_READ); |
370 | 0 | XX(STREAM_COPY); |
371 | 0 | XX(STATIC_READ); |
372 | 0 | XX(STATIC_COPY); |
373 | 0 | XX(DYNAMIC_READ); |
374 | 0 | XX(DYNAMIC_COPY); |
375 | 0 | XX(MAX_DRAW_BUFFERS); |
376 | 0 | XX(DRAW_BUFFER0); |
377 | 0 | XX(DRAW_BUFFER1); |
378 | 0 | XX(DRAW_BUFFER2); |
379 | 0 | XX(DRAW_BUFFER3); |
380 | 0 | XX(DRAW_BUFFER4); |
381 | 0 | XX(DRAW_BUFFER5); |
382 | 0 | XX(DRAW_BUFFER6); |
383 | 0 | XX(DRAW_BUFFER7); |
384 | 0 | XX(DRAW_BUFFER8); |
385 | 0 | XX(DRAW_BUFFER9); |
386 | 0 | XX(DRAW_BUFFER10); |
387 | 0 | XX(DRAW_BUFFER11); |
388 | 0 | XX(DRAW_BUFFER12); |
389 | 0 | XX(DRAW_BUFFER13); |
390 | 0 | XX(DRAW_BUFFER14); |
391 | 0 | XX(DRAW_BUFFER15); |
392 | 0 | XX(MAX_FRAGMENT_UNIFORM_COMPONENTS); |
393 | 0 | XX(MAX_VERTEX_UNIFORM_COMPONENTS); |
394 | 0 | XX(SAMPLER_3D); |
395 | 0 | XX(SAMPLER_2D_SHADOW); |
396 | 0 | XX(FRAGMENT_SHADER_DERIVATIVE_HINT); |
397 | 0 | XX(PIXEL_PACK_BUFFER); |
398 | 0 | XX(PIXEL_UNPACK_BUFFER); |
399 | 0 | XX(PIXEL_PACK_BUFFER_BINDING); |
400 | 0 | XX(PIXEL_UNPACK_BUFFER_BINDING); |
401 | 0 | XX(FLOAT_MAT2x3); |
402 | 0 | XX(FLOAT_MAT2x4); |
403 | 0 | XX(FLOAT_MAT3x2); |
404 | 0 | XX(FLOAT_MAT3x4); |
405 | 0 | XX(FLOAT_MAT4x2); |
406 | 0 | XX(FLOAT_MAT4x3); |
407 | 0 | XX(SRGB8); |
408 | 0 | XX(SRGB8_ALPHA8); |
409 | 0 | XX(COMPARE_REF_TO_TEXTURE); |
410 | 0 | XX(VERTEX_ATTRIB_ARRAY_INTEGER); |
411 | 0 | XX(MAX_ARRAY_TEXTURE_LAYERS); |
412 | 0 | XX(MIN_PROGRAM_TEXEL_OFFSET); |
413 | 0 | XX(MAX_PROGRAM_TEXEL_OFFSET); |
414 | 0 | XX(MAX_VARYING_COMPONENTS); |
415 | 0 | XX(TEXTURE_2D_ARRAY); |
416 | 0 | XX(TEXTURE_BINDING_2D_ARRAY); |
417 | 0 | XX(R11F_G11F_B10F); |
418 | 0 | XX(UNSIGNED_INT_10F_11F_11F_REV); |
419 | 0 | XX(RGB9_E5); |
420 | 0 | XX(UNSIGNED_INT_5_9_9_9_REV); |
421 | 0 | XX(TRANSFORM_FEEDBACK_BUFFER_MODE); |
422 | 0 | XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS); |
423 | 0 | XX(TRANSFORM_FEEDBACK_VARYINGS); |
424 | 0 | XX(TRANSFORM_FEEDBACK_BUFFER_START); |
425 | 0 | XX(TRANSFORM_FEEDBACK_BUFFER_SIZE); |
426 | 0 | XX(TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); |
427 | 0 | XX(RASTERIZER_DISCARD); |
428 | 0 | XX(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS); |
429 | 0 | XX(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS); |
430 | 0 | XX(INTERLEAVED_ATTRIBS); |
431 | 0 | XX(SEPARATE_ATTRIBS); |
432 | 0 | XX(TRANSFORM_FEEDBACK_BUFFER); |
433 | 0 | XX(TRANSFORM_FEEDBACK_BUFFER_BINDING); |
434 | 0 | XX(RGBA32UI); |
435 | 0 | XX(RGB32UI); |
436 | 0 | XX(RGBA16UI); |
437 | 0 | XX(RGB16UI); |
438 | 0 | XX(RGBA8UI); |
439 | 0 | XX(RGB8UI); |
440 | 0 | XX(RGBA32I); |
441 | 0 | XX(RGB32I); |
442 | 0 | XX(RGBA16I); |
443 | 0 | XX(RGB16I); |
444 | 0 | XX(RGBA8I); |
445 | 0 | XX(RGB8I); |
446 | 0 | XX(RED_INTEGER); |
447 | 0 | XX(RGB_INTEGER); |
448 | 0 | XX(RGBA_INTEGER); |
449 | 0 | XX(SAMPLER_2D_ARRAY); |
450 | 0 | XX(SAMPLER_2D_ARRAY_SHADOW); |
451 | 0 | XX(SAMPLER_CUBE_SHADOW); |
452 | 0 | XX(UNSIGNED_INT_VEC2); |
453 | 0 | XX(UNSIGNED_INT_VEC3); |
454 | 0 | XX(UNSIGNED_INT_VEC4); |
455 | 0 | XX(INT_SAMPLER_2D); |
456 | 0 | XX(INT_SAMPLER_3D); |
457 | 0 | XX(INT_SAMPLER_CUBE); |
458 | 0 | XX(INT_SAMPLER_2D_ARRAY); |
459 | 0 | XX(UNSIGNED_INT_SAMPLER_2D); |
460 | 0 | XX(UNSIGNED_INT_SAMPLER_3D); |
461 | 0 | XX(UNSIGNED_INT_SAMPLER_CUBE); |
462 | 0 | XX(UNSIGNED_INT_SAMPLER_2D_ARRAY); |
463 | 0 | XX(DEPTH_COMPONENT32F); |
464 | 0 | XX(DEPTH32F_STENCIL8); |
465 | 0 | XX(FLOAT_32_UNSIGNED_INT_24_8_REV); |
466 | 0 | XX(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING); |
467 | 0 | XX(FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE); |
468 | 0 | XX(FRAMEBUFFER_ATTACHMENT_RED_SIZE); |
469 | 0 | XX(FRAMEBUFFER_ATTACHMENT_GREEN_SIZE); |
470 | 0 | XX(FRAMEBUFFER_ATTACHMENT_BLUE_SIZE); |
471 | 0 | XX(FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE); |
472 | 0 | XX(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE); |
473 | 0 | XX(FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE); |
474 | 0 | XX(FRAMEBUFFER_DEFAULT); |
475 | 0 | XX(DEPTH_STENCIL_ATTACHMENT); |
476 | 0 | XX(UNSIGNED_NORMALIZED); |
477 | 0 | XX(DRAW_FRAMEBUFFER_BINDING); |
478 | 0 | XX(READ_FRAMEBUFFER_BINDING); |
479 | 0 | XX(RENDERBUFFER_SAMPLES); |
480 | 0 | XX(FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER); |
481 | 0 | XX(MAX_COLOR_ATTACHMENTS); |
482 | 0 | XX(COLOR_ATTACHMENT0); |
483 | 0 | XX(COLOR_ATTACHMENT1); |
484 | 0 | XX(COLOR_ATTACHMENT2); |
485 | 0 | XX(COLOR_ATTACHMENT3); |
486 | 0 | XX(COLOR_ATTACHMENT4); |
487 | 0 | XX(COLOR_ATTACHMENT5); |
488 | 0 | XX(COLOR_ATTACHMENT6); |
489 | 0 | XX(COLOR_ATTACHMENT7); |
490 | 0 | XX(COLOR_ATTACHMENT8); |
491 | 0 | XX(COLOR_ATTACHMENT9); |
492 | 0 | XX(COLOR_ATTACHMENT10); |
493 | 0 | XX(COLOR_ATTACHMENT11); |
494 | 0 | XX(COLOR_ATTACHMENT12); |
495 | 0 | XX(COLOR_ATTACHMENT13); |
496 | 0 | XX(COLOR_ATTACHMENT14); |
497 | 0 | XX(COLOR_ATTACHMENT15); |
498 | 0 | XX(FRAMEBUFFER_INCOMPLETE_MULTISAMPLE); |
499 | 0 | XX(MAX_SAMPLES); |
500 | 0 | XX(RG); |
501 | 0 | XX(RG_INTEGER); |
502 | 0 | XX(R8); |
503 | 0 | XX(RG8); |
504 | 0 | XX(R16F); |
505 | 0 | XX(R32F); |
506 | 0 | XX(RG16F); |
507 | 0 | XX(RG32F); |
508 | 0 | XX(R8I); |
509 | 0 | XX(R8UI); |
510 | 0 | XX(R16I); |
511 | 0 | XX(R16UI); |
512 | 0 | XX(R32I); |
513 | 0 | XX(R32UI); |
514 | 0 | XX(RG8I); |
515 | 0 | XX(RG8UI); |
516 | 0 | XX(RG16I); |
517 | 0 | XX(RG16UI); |
518 | 0 | XX(RG32I); |
519 | 0 | XX(RG32UI); |
520 | 0 | XX(VERTEX_ARRAY_BINDING); |
521 | 0 | XX(R8_SNORM); |
522 | 0 | XX(RG8_SNORM); |
523 | 0 | XX(RGB8_SNORM); |
524 | 0 | XX(RGBA8_SNORM); |
525 | 0 | XX(SIGNED_NORMALIZED); |
526 | 0 | XX(PRIMITIVE_RESTART_FIXED_INDEX); |
527 | 0 | XX(COPY_READ_BUFFER); |
528 | 0 | XX(COPY_WRITE_BUFFER); |
529 | 0 | XX(UNIFORM_BUFFER); |
530 | 0 | XX(UNIFORM_BUFFER_BINDING); |
531 | 0 | XX(UNIFORM_BUFFER_START); |
532 | 0 | XX(UNIFORM_BUFFER_SIZE); |
533 | 0 | XX(MAX_VERTEX_UNIFORM_BLOCKS); |
534 | 0 | XX(MAX_FRAGMENT_UNIFORM_BLOCKS); |
535 | 0 | XX(MAX_COMBINED_UNIFORM_BLOCKS); |
536 | 0 | XX(MAX_UNIFORM_BUFFER_BINDINGS); |
537 | 0 | XX(MAX_UNIFORM_BLOCK_SIZE); |
538 | 0 | XX(MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS); |
539 | 0 | XX(MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS); |
540 | 0 | XX(UNIFORM_BUFFER_OFFSET_ALIGNMENT); |
541 | 0 | XX(ACTIVE_UNIFORM_BLOCKS); |
542 | 0 | XX(UNIFORM_TYPE); |
543 | 0 | XX(UNIFORM_SIZE); |
544 | 0 | XX(UNIFORM_BLOCK_INDEX); |
545 | 0 | XX(UNIFORM_OFFSET); |
546 | 0 | XX(UNIFORM_ARRAY_STRIDE); |
547 | 0 | XX(UNIFORM_MATRIX_STRIDE); |
548 | 0 | XX(UNIFORM_IS_ROW_MAJOR); |
549 | 0 | XX(UNIFORM_BLOCK_BINDING); |
550 | 0 | XX(UNIFORM_BLOCK_DATA_SIZE); |
551 | 0 | XX(UNIFORM_BLOCK_ACTIVE_UNIFORMS); |
552 | 0 | XX(UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES); |
553 | 0 | XX(UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER); |
554 | 0 | XX(UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER); |
555 | 0 | XX(MAX_VERTEX_OUTPUT_COMPONENTS); |
556 | 0 | XX(MAX_FRAGMENT_INPUT_COMPONENTS); |
557 | 0 | XX(MAX_SERVER_WAIT_TIMEOUT); |
558 | 0 | XX(OBJECT_TYPE); |
559 | 0 | XX(SYNC_CONDITION); |
560 | 0 | XX(SYNC_STATUS); |
561 | 0 | XX(SYNC_FLAGS); |
562 | 0 | XX(SYNC_FENCE); |
563 | 0 | XX(SYNC_GPU_COMMANDS_COMPLETE); |
564 | 0 | XX(UNSIGNALED); |
565 | 0 | XX(SIGNALED); |
566 | 0 | XX(ALREADY_SIGNALED); |
567 | 0 | XX(TIMEOUT_EXPIRED); |
568 | 0 | XX(CONDITION_SATISFIED); |
569 | 0 | XX(WAIT_FAILED); |
570 | 0 | XX(VERTEX_ATTRIB_ARRAY_DIVISOR); |
571 | 0 | XX(ANY_SAMPLES_PASSED); |
572 | 0 | XX(ANY_SAMPLES_PASSED_CONSERVATIVE); |
573 | 0 | XX(SAMPLER_BINDING); |
574 | 0 | XX(RGB10_A2UI); |
575 | 0 | XX(TEXTURE_SWIZZLE_R); |
576 | 0 | XX(TEXTURE_SWIZZLE_G); |
577 | 0 | XX(TEXTURE_SWIZZLE_B); |
578 | 0 | XX(TEXTURE_SWIZZLE_A); |
579 | 0 | XX(GREEN); |
580 | 0 | XX(BLUE); |
581 | 0 | XX(INT_2_10_10_10_REV); |
582 | 0 | XX(TRANSFORM_FEEDBACK); |
583 | 0 | XX(TRANSFORM_FEEDBACK_PAUSED); |
584 | 0 | XX(TRANSFORM_FEEDBACK_ACTIVE); |
585 | 0 | XX(TRANSFORM_FEEDBACK_BINDING); |
586 | 0 | XX(COMPRESSED_R11_EAC); |
587 | 0 | XX(COMPRESSED_SIGNED_R11_EAC); |
588 | 0 | XX(COMPRESSED_RG11_EAC); |
589 | 0 | XX(COMPRESSED_SIGNED_RG11_EAC); |
590 | 0 | XX(COMPRESSED_RGB8_ETC2); |
591 | 0 | XX(COMPRESSED_SRGB8_ETC2); |
592 | 0 | XX(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2); |
593 | 0 | XX(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2); |
594 | 0 | XX(COMPRESSED_RGBA8_ETC2_EAC); |
595 | 0 | XX(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC); |
596 | 0 | XX(TEXTURE_IMMUTABLE_FORMAT); |
597 | 0 | XX(MAX_ELEMENT_INDEX); |
598 | 0 | XX(NUM_SAMPLE_COUNTS); |
599 | 0 | XX(TEXTURE_IMMUTABLE_LEVELS); |
600 | 0 | #undef XX |
601 | 0 | } |
602 | 0 |
|
603 | 0 | return defaultRet; |
604 | 0 | } |
605 | | |
606 | | /*static*/ void |
607 | | WebGLContext::EnumName(GLenum val, nsCString* out_name) |
608 | 0 | { |
609 | 0 | const char* name = GetEnumName(val, nullptr); |
610 | 0 | if (name) { |
611 | 0 | *out_name = name; |
612 | 0 | return; |
613 | 0 | } |
614 | 0 | |
615 | 0 | *out_name = nsPrintfCString("<enum 0x%04x>", val); |
616 | 0 | } |
617 | | |
618 | | std::string |
619 | | EnumString(const GLenum val) |
620 | 0 | { |
621 | 0 | const char* name = GetEnumName(val, nullptr); |
622 | 0 | if (name) { |
623 | 0 | return name; |
624 | 0 | } |
625 | 0 | |
626 | 0 | const nsPrintfCString hex("<enum 0x%04x>", val); |
627 | 0 | return hex.BeginReading(); |
628 | 0 | } |
629 | | |
630 | | void |
631 | | WebGLContext::ErrorInvalidEnumArg(const char* argName, GLenum val) const |
632 | 0 | { |
633 | 0 | nsCString enumName; |
634 | 0 | EnumName(val, &enumName); |
635 | 0 | ErrorInvalidEnum("Bad `%s`: %s", argName, enumName.BeginReading()); |
636 | 0 | } |
637 | | |
638 | | bool |
639 | | IsCompressedTextureFormat(GLenum format) |
640 | 0 | { |
641 | 0 | switch (format) { |
642 | 0 | case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT: |
643 | 0 | case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: |
644 | 0 | case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
645 | 0 | case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: |
646 | 0 | case LOCAL_GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: |
647 | 0 | case LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: |
648 | 0 | case LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: |
649 | 0 | case LOCAL_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: |
650 | 0 | case LOCAL_GL_ATC_RGB: |
651 | 0 | case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA: |
652 | 0 | case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA: |
653 | 0 | case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1: |
654 | 0 | case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1: |
655 | 0 | case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1: |
656 | 0 | case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1: |
657 | 0 | case LOCAL_GL_ETC1_RGB8_OES: |
658 | 0 | case LOCAL_GL_COMPRESSED_R11_EAC: |
659 | 0 | case LOCAL_GL_COMPRESSED_SIGNED_R11_EAC: |
660 | 0 | case LOCAL_GL_COMPRESSED_RG11_EAC: |
661 | 0 | case LOCAL_GL_COMPRESSED_SIGNED_RG11_EAC: |
662 | 0 | case LOCAL_GL_COMPRESSED_RGB8_ETC2: |
663 | 0 | case LOCAL_GL_COMPRESSED_SRGB8_ETC2: |
664 | 0 | case LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
665 | 0 | case LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
666 | 0 | case LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC: |
667 | 0 | case LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: |
668 | 0 | return true; |
669 | 0 | default: |
670 | 0 | return false; |
671 | 0 | } |
672 | 0 | } |
673 | | |
674 | | |
675 | | bool |
676 | | IsTextureFormatCompressed(TexInternalFormat format) |
677 | 0 | { |
678 | 0 | return IsCompressedTextureFormat(format.get()); |
679 | 0 | } |
680 | | |
681 | | GLenum |
682 | | WebGLContext::GetAndFlushUnderlyingGLErrors() const |
683 | 0 | { |
684 | 0 | // Get and clear GL error in ALL cases. |
685 | 0 | GLenum error = gl->fGetError(); |
686 | 0 |
|
687 | 0 | // Only store in mUnderlyingGLError if is hasn't already recorded an |
688 | 0 | // error. |
689 | 0 | if (!mUnderlyingGLError) |
690 | 0 | mUnderlyingGLError = error; |
691 | 0 |
|
692 | 0 | return error; |
693 | 0 | } |
694 | | |
695 | | #ifdef DEBUG |
696 | | // For NaNs, etc. |
697 | | static bool |
698 | | IsCacheCorrect(float cached, float actual) |
699 | | { |
700 | | if (IsNaN(cached)) { |
701 | | // GL is allowed to do anything it wants for NaNs, so if we're shadowing |
702 | | // a NaN, then whatever `actual` is might be correct. |
703 | | return true; |
704 | | } |
705 | | |
706 | | return cached == actual; |
707 | | } |
708 | | |
709 | | void |
710 | | AssertUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint shadow) |
711 | | { |
712 | | GLuint val = 0; |
713 | | gl->GetUIntegerv(pname, &val); |
714 | | if (val != shadow) { |
715 | | printf_stderr("Failed 0x%04x shadow: Cached 0x%x/%u, should be 0x%x/%u.\n", |
716 | | pname, shadow, shadow, val, val); |
717 | | MOZ_ASSERT(false, "Bad cached value."); |
718 | | } |
719 | | } |
720 | | |
721 | | void |
722 | | AssertMaskedUintParamCorrect(gl::GLContext* gl, GLenum pname, GLuint mask, |
723 | | GLuint shadow) |
724 | | { |
725 | | GLuint val = 0; |
726 | | gl->GetUIntegerv(pname, &val); |
727 | | |
728 | | const GLuint valMasked = val & mask; |
729 | | const GLuint shadowMasked = shadow & mask; |
730 | | |
731 | | if (valMasked != shadowMasked) { |
732 | | printf_stderr("Failed 0x%04x shadow: Cached 0x%x/%u, should be 0x%x/%u.\n", |
733 | | pname, shadowMasked, shadowMasked, valMasked, valMasked); |
734 | | MOZ_ASSERT(false, "Bad cached value."); |
735 | | } |
736 | | } |
737 | | #else |
738 | | void |
739 | | AssertUintParamCorrect(gl::GLContext*, GLenum, GLuint) |
740 | 0 | { |
741 | 0 | } |
742 | | #endif |
743 | | |
744 | | void |
745 | | WebGLContext::AssertCachedBindings() const |
746 | 0 | { |
747 | | #ifdef DEBUG |
748 | | GetAndFlushUnderlyingGLErrors(); |
749 | | |
750 | | if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) { |
751 | | GLuint bound = mBoundVertexArray ? mBoundVertexArray->GLName() : 0; |
752 | | AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING, bound); |
753 | | } |
754 | | |
755 | | GLint stencilBits = 0; |
756 | | if (GetStencilBits(&stencilBits)) { // Depends on current draw framebuffer. |
757 | | const GLuint stencilRefMask = (1 << stencilBits) - 1; |
758 | | |
759 | | AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront); |
760 | | AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack); |
761 | | } |
762 | | |
763 | | // Program |
764 | | GLuint bound = mCurrentProgram ? mCurrentProgram->mGLName : 0; |
765 | | AssertUintParamCorrect(gl, LOCAL_GL_CURRENT_PROGRAM, bound); |
766 | | |
767 | | // Textures |
768 | | GLenum activeTexture = mActiveTexture + LOCAL_GL_TEXTURE0; |
769 | | AssertUintParamCorrect(gl, LOCAL_GL_ACTIVE_TEXTURE, activeTexture); |
770 | | |
771 | | WebGLTexture* curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_2D); |
772 | | bound = curTex ? curTex->mGLName : 0; |
773 | | AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_2D, bound); |
774 | | |
775 | | curTex = ActiveBoundTextureForTarget(LOCAL_GL_TEXTURE_CUBE_MAP); |
776 | | bound = curTex ? curTex->mGLName : 0; |
777 | | AssertUintParamCorrect(gl, LOCAL_GL_TEXTURE_BINDING_CUBE_MAP, bound); |
778 | | |
779 | | // Buffers |
780 | | bound = mBoundArrayBuffer ? mBoundArrayBuffer->mGLName : 0; |
781 | | AssertUintParamCorrect(gl, LOCAL_GL_ARRAY_BUFFER_BINDING, bound); |
782 | | |
783 | | MOZ_ASSERT(mBoundVertexArray); |
784 | | WebGLBuffer* curBuff = mBoundVertexArray->mElementArrayBuffer; |
785 | | bound = curBuff ? curBuff->mGLName : 0; |
786 | | AssertUintParamCorrect(gl, LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING, bound); |
787 | | |
788 | | MOZ_ASSERT(!GetAndFlushUnderlyingGLErrors()); |
789 | | #endif |
790 | |
|
791 | 0 | // We do not check the renderbuffer binding, because we never rely on it matching. |
792 | 0 | } |
793 | | |
794 | | void |
795 | | WebGLContext::AssertCachedGlobalState() const |
796 | 0 | { |
797 | | #ifdef DEBUG |
798 | | GetAndFlushUnderlyingGLErrors(); |
799 | | |
800 | | //////////////// |
801 | | |
802 | | // Draw state |
803 | | MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_DITHER) == mDitherEnabled); |
804 | | MOZ_ASSERT_IF(IsWebGL2(), |
805 | | gl->fIsEnabled(LOCAL_GL_RASTERIZER_DISCARD) == mRasterizerDiscardEnabled); |
806 | | MOZ_ASSERT(gl->fIsEnabled(LOCAL_GL_SCISSOR_TEST) == mScissorTestEnabled); |
807 | | |
808 | | // Cannot trivially check COLOR_CLEAR_VALUE, since in old GL versions glGet may clamp |
809 | | // based on whether the current framebuffer is floating-point or not. |
810 | | // This also means COLOR_CLEAR_VALUE save+restore is dangerous! |
811 | | |
812 | | realGLboolean depthWriteMask = 0; |
813 | | gl->fGetBooleanv(LOCAL_GL_DEPTH_WRITEMASK, &depthWriteMask); |
814 | | MOZ_ASSERT(depthWriteMask == mDepthWriteMask); |
815 | | |
816 | | GLfloat depthClearValue = 0.0f; |
817 | | gl->fGetFloatv(LOCAL_GL_DEPTH_CLEAR_VALUE, &depthClearValue); |
818 | | MOZ_ASSERT(IsCacheCorrect(mDepthClearValue, depthClearValue)); |
819 | | |
820 | | const int maxStencilBits = 8; |
821 | | const GLuint maxStencilBitsMask = (1 << maxStencilBits) - 1; |
822 | | AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_CLEAR_VALUE, maxStencilBitsMask, mStencilClearValue); |
823 | | |
824 | | // GLES 3.0.4, $4.1.4, p177: |
825 | | // [...] the front and back stencil mask are both set to the value `2^s - 1`, where |
826 | | // `s` is greater than or equal to the number of bits in the deepest stencil buffer |
827 | | // supported by the GL implementation. |
828 | | AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK, maxStencilBitsMask, mStencilValueMaskFront); |
829 | | AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK, maxStencilBitsMask, mStencilValueMaskBack); |
830 | | |
831 | | AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK, maxStencilBitsMask, mStencilWriteMaskFront); |
832 | | AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK, maxStencilBitsMask, mStencilWriteMaskBack); |
833 | | |
834 | | // Viewport |
835 | | GLint int4[4] = {0, 0, 0, 0}; |
836 | | gl->fGetIntegerv(LOCAL_GL_VIEWPORT, int4); |
837 | | MOZ_ASSERT(int4[0] == mViewportX && |
838 | | int4[1] == mViewportY && |
839 | | int4[2] == mViewportWidth && |
840 | | int4[3] == mViewportHeight); |
841 | | |
842 | | AssertUintParamCorrect(gl, LOCAL_GL_PACK_ALIGNMENT, mPixelStore_PackAlignment); |
843 | | AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_ALIGNMENT, mPixelStore_UnpackAlignment); |
844 | | |
845 | | if (IsWebGL2()) { |
846 | | AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_IMAGE_HEIGHT, mPixelStore_UnpackImageHeight); |
847 | | AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_SKIP_IMAGES , mPixelStore_UnpackSkipImages); |
848 | | AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_ROW_LENGTH , mPixelStore_UnpackRowLength); |
849 | | AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_SKIP_ROWS , mPixelStore_UnpackSkipRows); |
850 | | AssertUintParamCorrect(gl, LOCAL_GL_UNPACK_SKIP_PIXELS , mPixelStore_UnpackSkipPixels); |
851 | | AssertUintParamCorrect(gl, LOCAL_GL_PACK_ROW_LENGTH , mPixelStore_PackRowLength); |
852 | | AssertUintParamCorrect(gl, LOCAL_GL_PACK_SKIP_ROWS , mPixelStore_PackSkipRows); |
853 | | AssertUintParamCorrect(gl, LOCAL_GL_PACK_SKIP_PIXELS , mPixelStore_PackSkipPixels); |
854 | | } |
855 | | |
856 | | MOZ_ASSERT(!GetAndFlushUnderlyingGLErrors()); |
857 | | #endif |
858 | | } |
859 | | |
860 | | const char* |
861 | | InfoFrom(WebGLTexImageFunc func, WebGLTexDimensions dims) |
862 | 0 | { |
863 | 0 | switch (dims) { |
864 | 0 | case WebGLTexDimensions::Tex2D: |
865 | 0 | switch (func) { |
866 | 0 | case WebGLTexImageFunc::TexImage: return "texImage2D"; |
867 | 0 | case WebGLTexImageFunc::TexSubImage: return "texSubImage2D"; |
868 | 0 | case WebGLTexImageFunc::CopyTexImage: return "copyTexImage2D"; |
869 | 0 | case WebGLTexImageFunc::CopyTexSubImage: return "copyTexSubImage2D"; |
870 | 0 | case WebGLTexImageFunc::CompTexImage: return "compressedTexImage2D"; |
871 | 0 | case WebGLTexImageFunc::CompTexSubImage: return "compressedTexSubImage2D"; |
872 | 0 | default: |
873 | 0 | MOZ_CRASH("GFX: invalid 2D TexDimensions"); |
874 | 0 | } |
875 | 0 | case WebGLTexDimensions::Tex3D: |
876 | 0 | switch (func) { |
877 | 0 | case WebGLTexImageFunc::TexImage: return "texImage3D"; |
878 | 0 | case WebGLTexImageFunc::TexSubImage: return "texSubImage3D"; |
879 | 0 | case WebGLTexImageFunc::CopyTexSubImage: return "copyTexSubImage3D"; |
880 | 0 | case WebGLTexImageFunc::CompTexSubImage: return "compressedTexSubImage3D"; |
881 | 0 | default: |
882 | 0 | MOZ_CRASH("GFX: invalid 3D TexDimensions"); |
883 | 0 | } |
884 | 0 | default: |
885 | 0 | MOZ_CRASH("GFX: invalid TexDimensions"); |
886 | 0 | } |
887 | 0 | } |
888 | | |
889 | | //// |
890 | | |
891 | | JS::Value |
892 | | StringValue(JSContext* cx, const nsAString& str, ErrorResult& er) |
893 | 0 | { |
894 | 0 | JSString* jsStr = JS_NewUCStringCopyN(cx, str.BeginReading(), str.Length()); |
895 | 0 | if (!jsStr) { |
896 | 0 | er.Throw(NS_ERROR_OUT_OF_MEMORY); |
897 | 0 | return JS::NullValue(); |
898 | 0 | } |
899 | 0 | |
900 | 0 | return JS::StringValue(jsStr); |
901 | 0 | } |
902 | | |
903 | | } // namespace mozilla |