|
1 /* -*- Mode: C++; tab-width: 4; 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 "WebGLContext.h" |
|
7 #include "WebGLContextUtils.h" |
|
8 #include "WebGLBuffer.h" |
|
9 #include "WebGLShader.h" |
|
10 #include "WebGLProgram.h" |
|
11 #include "WebGLFramebuffer.h" |
|
12 #include "WebGLRenderbuffer.h" |
|
13 #include "WebGLTexture.h" |
|
14 #include "WebGLVertexArray.h" |
|
15 #include "GLContext.h" |
|
16 #include "mozilla/dom/ToJSValue.h" |
|
17 |
|
18 using namespace mozilla; |
|
19 using namespace dom; |
|
20 |
|
21 void |
|
22 WebGLContext::Disable(GLenum cap) |
|
23 { |
|
24 if (IsContextLost()) |
|
25 return; |
|
26 |
|
27 if (!ValidateCapabilityEnum(cap, "disable")) |
|
28 return; |
|
29 |
|
30 realGLboolean* trackingSlot = GetStateTrackingSlot(cap); |
|
31 |
|
32 if (trackingSlot) |
|
33 { |
|
34 *trackingSlot = 0; |
|
35 } |
|
36 |
|
37 MakeContextCurrent(); |
|
38 gl->fDisable(cap); |
|
39 } |
|
40 |
|
41 void |
|
42 WebGLContext::Enable(GLenum cap) |
|
43 { |
|
44 if (IsContextLost()) |
|
45 return; |
|
46 |
|
47 if (!ValidateCapabilityEnum(cap, "enable")) |
|
48 return; |
|
49 |
|
50 realGLboolean* trackingSlot = GetStateTrackingSlot(cap); |
|
51 |
|
52 if (trackingSlot) |
|
53 { |
|
54 *trackingSlot = 1; |
|
55 } |
|
56 |
|
57 MakeContextCurrent(); |
|
58 gl->fEnable(cap); |
|
59 } |
|
60 |
|
61 static JS::Value |
|
62 StringValue(JSContext* cx, const char* chars, ErrorResult& rv) |
|
63 { |
|
64 JSString* str = JS_NewStringCopyZ(cx, chars); |
|
65 if (!str) { |
|
66 rv.Throw(NS_ERROR_OUT_OF_MEMORY); |
|
67 return JS::NullValue(); |
|
68 } |
|
69 |
|
70 return JS::StringValue(str); |
|
71 } |
|
72 |
|
73 JS::Value |
|
74 WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv) |
|
75 { |
|
76 if (IsContextLost()) |
|
77 return JS::NullValue(); |
|
78 |
|
79 MakeContextCurrent(); |
|
80 |
|
81 if (MinCapabilityMode()) { |
|
82 switch(pname) { |
|
83 //////////////////////////// |
|
84 // Single-value params |
|
85 |
|
86 // int |
|
87 case LOCAL_GL_MAX_VERTEX_ATTRIBS: |
|
88 return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_ATTRIBS); |
|
89 |
|
90 case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS: |
|
91 return JS::Int32Value(MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS); |
|
92 |
|
93 case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS: |
|
94 return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS); |
|
95 |
|
96 case LOCAL_GL_MAX_VARYING_VECTORS: |
|
97 return JS::Int32Value(MINVALUE_GL_MAX_VARYING_VECTORS); |
|
98 |
|
99 case LOCAL_GL_MAX_TEXTURE_SIZE: |
|
100 return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_SIZE); |
|
101 |
|
102 case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE: |
|
103 return JS::Int32Value(MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE); |
|
104 |
|
105 case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: |
|
106 return JS::Int32Value(MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS); |
|
107 |
|
108 case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: |
|
109 return JS::Int32Value(MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS); |
|
110 |
|
111 case LOCAL_GL_MAX_RENDERBUFFER_SIZE: |
|
112 return JS::Int32Value(MINVALUE_GL_MAX_RENDERBUFFER_SIZE); |
|
113 |
|
114 default: |
|
115 // Return the real value; we're not overriding this one |
|
116 break; |
|
117 } |
|
118 } |
|
119 |
|
120 if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) { |
|
121 if (pname == LOCAL_GL_MAX_COLOR_ATTACHMENTS) { |
|
122 return JS::Int32Value(mGLMaxColorAttachments); |
|
123 |
|
124 } else if (pname == LOCAL_GL_MAX_DRAW_BUFFERS) { |
|
125 return JS::Int32Value(mGLMaxDrawBuffers); |
|
126 |
|
127 } else if (pname >= LOCAL_GL_DRAW_BUFFER0 && |
|
128 pname < GLenum(LOCAL_GL_DRAW_BUFFER0 + mGLMaxDrawBuffers)) |
|
129 { |
|
130 if (mBoundFramebuffer) { |
|
131 GLint iv = 0; |
|
132 gl->fGetIntegerv(pname, &iv); |
|
133 return JS::Int32Value(iv); |
|
134 } |
|
135 |
|
136 GLint iv = 0; |
|
137 gl->fGetIntegerv(pname, &iv); |
|
138 |
|
139 if (iv == GLint(LOCAL_GL_COLOR_ATTACHMENT0 + pname - LOCAL_GL_DRAW_BUFFER0)) { |
|
140 return JS::Int32Value(LOCAL_GL_BACK); |
|
141 } |
|
142 |
|
143 return JS::Int32Value(LOCAL_GL_NONE); |
|
144 } |
|
145 } |
|
146 |
|
147 if (IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) { |
|
148 if (pname == LOCAL_GL_VERTEX_ARRAY_BINDING) { |
|
149 if (mBoundVertexArray == mDefaultVertexArray){ |
|
150 return WebGLObjectAsJSValue(cx, (WebGLVertexArray *) nullptr, rv); |
|
151 } |
|
152 |
|
153 return WebGLObjectAsJSValue(cx, mBoundVertexArray.get(), rv); |
|
154 } |
|
155 } |
|
156 |
|
157 switch (pname) { |
|
158 // |
|
159 // String params |
|
160 // |
|
161 case LOCAL_GL_VENDOR: |
|
162 return StringValue(cx, "Mozilla", rv); |
|
163 case LOCAL_GL_RENDERER: |
|
164 return StringValue(cx, "Mozilla", rv); |
|
165 case LOCAL_GL_VERSION: { |
|
166 const char* version = 0; |
|
167 |
|
168 if (IsWebGL2()) { |
|
169 version = "WebGL 2.0"; |
|
170 } else { |
|
171 version = "WebGL 1.0"; |
|
172 } |
|
173 |
|
174 MOZ_ASSERT(version != 0); |
|
175 return StringValue(cx, version, rv); |
|
176 } |
|
177 case LOCAL_GL_SHADING_LANGUAGE_VERSION: |
|
178 return StringValue(cx, "WebGL GLSL ES 1.0", rv); |
|
179 |
|
180 // Privileged string params exposed by WEBGL_debug_renderer_info: |
|
181 case UNMASKED_VENDOR_WEBGL: |
|
182 case UNMASKED_RENDERER_WEBGL: { |
|
183 // The privilege check is done in WebGLContext::IsExtensionSupported. |
|
184 // So here we just have to check that the extension is enabled. |
|
185 if (!IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) { |
|
186 break; |
|
187 } |
|
188 GLenum glstringname = LOCAL_GL_NONE; |
|
189 if (pname == UNMASKED_VENDOR_WEBGL) { |
|
190 glstringname = LOCAL_GL_VENDOR; |
|
191 } else if (pname == UNMASKED_RENDERER_WEBGL) { |
|
192 glstringname = LOCAL_GL_RENDERER; |
|
193 } |
|
194 const char* string = reinterpret_cast<const char*>(gl->fGetString(glstringname)); |
|
195 return StringValue(cx, string, rv); |
|
196 } |
|
197 |
|
198 //////////////////////////////// |
|
199 // Single-value params |
|
200 |
|
201 // unsigned int |
|
202 case LOCAL_GL_CULL_FACE_MODE: |
|
203 case LOCAL_GL_FRONT_FACE: |
|
204 case LOCAL_GL_ACTIVE_TEXTURE: |
|
205 case LOCAL_GL_STENCIL_FUNC: |
|
206 case LOCAL_GL_STENCIL_FAIL: |
|
207 case LOCAL_GL_STENCIL_PASS_DEPTH_FAIL: |
|
208 case LOCAL_GL_STENCIL_PASS_DEPTH_PASS: |
|
209 case LOCAL_GL_STENCIL_BACK_FUNC: |
|
210 case LOCAL_GL_STENCIL_BACK_FAIL: |
|
211 case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_FAIL: |
|
212 case LOCAL_GL_STENCIL_BACK_PASS_DEPTH_PASS: |
|
213 case LOCAL_GL_DEPTH_FUNC: |
|
214 case LOCAL_GL_BLEND_SRC_RGB: |
|
215 case LOCAL_GL_BLEND_SRC_ALPHA: |
|
216 case LOCAL_GL_BLEND_DST_RGB: |
|
217 case LOCAL_GL_BLEND_DST_ALPHA: |
|
218 case LOCAL_GL_BLEND_EQUATION_RGB: |
|
219 case LOCAL_GL_BLEND_EQUATION_ALPHA: |
|
220 case LOCAL_GL_GENERATE_MIPMAP_HINT: { |
|
221 GLint i = 0; |
|
222 gl->fGetIntegerv(pname, &i); |
|
223 return JS::NumberValue(uint32_t(i)); |
|
224 } |
|
225 // int |
|
226 case LOCAL_GL_STENCIL_CLEAR_VALUE: |
|
227 case LOCAL_GL_STENCIL_REF: |
|
228 case LOCAL_GL_STENCIL_BACK_REF: |
|
229 case LOCAL_GL_UNPACK_ALIGNMENT: |
|
230 case LOCAL_GL_PACK_ALIGNMENT: |
|
231 case LOCAL_GL_SUBPIXEL_BITS: |
|
232 case LOCAL_GL_SAMPLE_BUFFERS: |
|
233 case LOCAL_GL_SAMPLES: |
|
234 case LOCAL_GL_MAX_VERTEX_ATTRIBS: |
|
235 case LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: |
|
236 case LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: |
|
237 case LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS: |
|
238 case LOCAL_GL_RED_BITS: |
|
239 case LOCAL_GL_GREEN_BITS: |
|
240 case LOCAL_GL_BLUE_BITS: |
|
241 case LOCAL_GL_ALPHA_BITS: |
|
242 case LOCAL_GL_DEPTH_BITS: |
|
243 case LOCAL_GL_STENCIL_BITS: { |
|
244 GLint i = 0; |
|
245 gl->fGetIntegerv(pname, &i); |
|
246 return JS::Int32Value(i); |
|
247 } |
|
248 case LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT: { |
|
249 if (IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives)) { |
|
250 GLint i = 0; |
|
251 gl->fGetIntegerv(pname, &i); |
|
252 return JS::Int32Value(i); |
|
253 } else { |
|
254 break; |
|
255 } |
|
256 } |
|
257 case LOCAL_GL_MAX_TEXTURE_SIZE: |
|
258 return JS::Int32Value(mGLMaxTextureSize); |
|
259 |
|
260 case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE: |
|
261 return JS::Int32Value(mGLMaxCubeMapTextureSize); |
|
262 |
|
263 case LOCAL_GL_MAX_RENDERBUFFER_SIZE: |
|
264 return JS::Int32Value(mGLMaxRenderbufferSize); |
|
265 |
|
266 case LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS: |
|
267 return JS::Int32Value(mGLMaxVertexUniformVectors); |
|
268 |
|
269 case LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS: |
|
270 return JS::Int32Value(mGLMaxFragmentUniformVectors); |
|
271 |
|
272 case LOCAL_GL_MAX_VARYING_VECTORS: |
|
273 return JS::Int32Value(mGLMaxVaryingVectors); |
|
274 |
|
275 case LOCAL_GL_NUM_COMPRESSED_TEXTURE_FORMATS: |
|
276 return JS::Int32Value(0); |
|
277 case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS: { |
|
278 uint32_t length = mCompressedTextureFormats.Length(); |
|
279 JSObject* obj = Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements()); |
|
280 if (!obj) { |
|
281 rv = NS_ERROR_OUT_OF_MEMORY; |
|
282 } |
|
283 return JS::ObjectOrNullValue(obj); |
|
284 } |
|
285 case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: { |
|
286 if (!IsWebGL2()) { |
|
287 break; |
|
288 } |
|
289 return JS::Int32Value(mGLMaxTransformFeedbackSeparateAttribs); |
|
290 } |
|
291 |
|
292 // unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as |
|
293 // javascript integer values. We just return them as doubles and javascript doesn't care. |
|
294 case LOCAL_GL_STENCIL_BACK_VALUE_MASK: |
|
295 case LOCAL_GL_STENCIL_BACK_WRITEMASK: |
|
296 case LOCAL_GL_STENCIL_VALUE_MASK: |
|
297 case LOCAL_GL_STENCIL_WRITEMASK: { |
|
298 GLint i = 0; // the GL api (glGetIntegerv) only does signed ints |
|
299 gl->fGetIntegerv(pname, &i); |
|
300 GLuint i_unsigned(i); // this is where -1 becomes 2^32-1 |
|
301 double i_double(i_unsigned); // pass as FP value to allow large values such as 2^32-1. |
|
302 return JS::DoubleValue(i_double); |
|
303 } |
|
304 |
|
305 // float |
|
306 case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: { |
|
307 if (IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic)) { |
|
308 GLfloat f = 0.f; |
|
309 gl->fGetFloatv(pname, &f); |
|
310 return JS::DoubleValue(f); |
|
311 } else { |
|
312 break; |
|
313 } |
|
314 } |
|
315 case LOCAL_GL_DEPTH_CLEAR_VALUE: |
|
316 case LOCAL_GL_LINE_WIDTH: |
|
317 case LOCAL_GL_POLYGON_OFFSET_FACTOR: |
|
318 case LOCAL_GL_POLYGON_OFFSET_UNITS: |
|
319 case LOCAL_GL_SAMPLE_COVERAGE_VALUE: { |
|
320 GLfloat f = 0.f; |
|
321 gl->fGetFloatv(pname, &f); |
|
322 return JS::DoubleValue(f); |
|
323 } |
|
324 |
|
325 // bool |
|
326 case LOCAL_GL_BLEND: |
|
327 case LOCAL_GL_DEPTH_TEST: |
|
328 case LOCAL_GL_STENCIL_TEST: |
|
329 case LOCAL_GL_CULL_FACE: |
|
330 case LOCAL_GL_DITHER: |
|
331 case LOCAL_GL_POLYGON_OFFSET_FILL: |
|
332 case LOCAL_GL_SCISSOR_TEST: |
|
333 case LOCAL_GL_SAMPLE_COVERAGE_INVERT: |
|
334 case LOCAL_GL_DEPTH_WRITEMASK: { |
|
335 realGLboolean b = 0; |
|
336 gl->fGetBooleanv(pname, &b); |
|
337 return JS::BooleanValue(bool(b)); |
|
338 } |
|
339 |
|
340 // bool, WebGL-specific |
|
341 case UNPACK_FLIP_Y_WEBGL: |
|
342 return JS::BooleanValue(mPixelStoreFlipY); |
|
343 case UNPACK_PREMULTIPLY_ALPHA_WEBGL: |
|
344 return JS::BooleanValue(mPixelStorePremultiplyAlpha); |
|
345 |
|
346 // uint, WebGL-specific |
|
347 case UNPACK_COLORSPACE_CONVERSION_WEBGL: |
|
348 return JS::NumberValue(uint32_t(mPixelStoreColorspaceConversion)); |
|
349 |
|
350 //////////////////////////////// |
|
351 // Complex values |
|
352 |
|
353 // 2 floats |
|
354 case LOCAL_GL_DEPTH_RANGE: |
|
355 case LOCAL_GL_ALIASED_POINT_SIZE_RANGE: |
|
356 case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: { |
|
357 GLfloat fv[2] = { 0 }; |
|
358 gl->fGetFloatv(pname, fv); |
|
359 JSObject* obj = Float32Array::Create(cx, this, 2, fv); |
|
360 if (!obj) { |
|
361 rv = NS_ERROR_OUT_OF_MEMORY; |
|
362 } |
|
363 return JS::ObjectOrNullValue(obj); |
|
364 } |
|
365 |
|
366 // 4 floats |
|
367 case LOCAL_GL_COLOR_CLEAR_VALUE: |
|
368 case LOCAL_GL_BLEND_COLOR: { |
|
369 GLfloat fv[4] = { 0 }; |
|
370 gl->fGetFloatv(pname, fv); |
|
371 JSObject* obj = Float32Array::Create(cx, this, 4, fv); |
|
372 if (!obj) { |
|
373 rv = NS_ERROR_OUT_OF_MEMORY; |
|
374 } |
|
375 return JS::ObjectOrNullValue(obj); |
|
376 } |
|
377 |
|
378 // 2 ints |
|
379 case LOCAL_GL_MAX_VIEWPORT_DIMS: { |
|
380 GLint iv[2] = { 0 }; |
|
381 gl->fGetIntegerv(pname, iv); |
|
382 JSObject* obj = Int32Array::Create(cx, this, 2, iv); |
|
383 if (!obj) { |
|
384 rv = NS_ERROR_OUT_OF_MEMORY; |
|
385 } |
|
386 return JS::ObjectOrNullValue(obj); |
|
387 } |
|
388 |
|
389 // 4 ints |
|
390 case LOCAL_GL_SCISSOR_BOX: |
|
391 case LOCAL_GL_VIEWPORT: { |
|
392 GLint iv[4] = { 0 }; |
|
393 gl->fGetIntegerv(pname, iv); |
|
394 JSObject* obj = Int32Array::Create(cx, this, 4, iv); |
|
395 if (!obj) { |
|
396 rv = NS_ERROR_OUT_OF_MEMORY; |
|
397 } |
|
398 return JS::ObjectOrNullValue(obj); |
|
399 } |
|
400 |
|
401 // 4 bools |
|
402 case LOCAL_GL_COLOR_WRITEMASK: { |
|
403 realGLboolean gl_bv[4] = { 0 }; |
|
404 gl->fGetBooleanv(pname, gl_bv); |
|
405 bool vals[4] = { bool(gl_bv[0]), bool(gl_bv[1]), |
|
406 bool(gl_bv[2]), bool(gl_bv[3]) }; |
|
407 JS::Rooted<JS::Value> arr(cx); |
|
408 if (!ToJSValue(cx, vals, &arr)) { |
|
409 rv = NS_ERROR_OUT_OF_MEMORY; |
|
410 } |
|
411 return arr; |
|
412 } |
|
413 |
|
414 case LOCAL_GL_ARRAY_BUFFER_BINDING: { |
|
415 return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv); |
|
416 } |
|
417 |
|
418 case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: { |
|
419 if (!IsWebGL2()) { |
|
420 break; |
|
421 } |
|
422 return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv); |
|
423 } |
|
424 |
|
425 case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: { |
|
426 return WebGLObjectAsJSValue(cx, mBoundVertexArray->mBoundElementArrayBuffer.get(), rv); |
|
427 } |
|
428 |
|
429 case LOCAL_GL_RENDERBUFFER_BINDING: { |
|
430 return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv); |
|
431 } |
|
432 |
|
433 case LOCAL_GL_FRAMEBUFFER_BINDING: { |
|
434 return WebGLObjectAsJSValue(cx, mBoundFramebuffer.get(), rv); |
|
435 } |
|
436 |
|
437 case LOCAL_GL_CURRENT_PROGRAM: { |
|
438 return WebGLObjectAsJSValue(cx, mCurrentProgram.get(), rv); |
|
439 } |
|
440 |
|
441 case LOCAL_GL_TEXTURE_BINDING_2D: { |
|
442 return WebGLObjectAsJSValue(cx, mBound2DTextures[mActiveTexture].get(), rv); |
|
443 } |
|
444 |
|
445 case LOCAL_GL_TEXTURE_BINDING_CUBE_MAP: { |
|
446 return WebGLObjectAsJSValue(cx, mBoundCubeMapTextures[mActiveTexture].get(), rv); |
|
447 } |
|
448 |
|
449 default: |
|
450 break; |
|
451 } |
|
452 |
|
453 ErrorInvalidEnumInfo("getParameter: parameter", pname); |
|
454 return JS::NullValue(); |
|
455 } |
|
456 |
|
457 void |
|
458 WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index, |
|
459 JS::MutableHandle<JS::Value> retval) |
|
460 { |
|
461 if (IsContextLost()) { |
|
462 retval.setNull(); |
|
463 return; |
|
464 } |
|
465 |
|
466 MakeContextCurrent(); |
|
467 |
|
468 switch (pname) { |
|
469 case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: |
|
470 { |
|
471 if (index >= mGLMaxTransformFeedbackSeparateAttribs) { |
|
472 ErrorInvalidValue("getParameterIndexed: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", index); |
|
473 retval.setNull(); |
|
474 return; |
|
475 } |
|
476 retval.setNull(); // See bug 903594 |
|
477 return; |
|
478 } |
|
479 |
|
480 default: |
|
481 break; |
|
482 } |
|
483 |
|
484 ErrorInvalidEnumInfo("getParameterIndexed: parameter", pname); |
|
485 retval.setNull(); |
|
486 } |
|
487 |
|
488 bool |
|
489 WebGLContext::IsEnabled(GLenum cap) |
|
490 { |
|
491 if (IsContextLost()) |
|
492 return false; |
|
493 |
|
494 if (!ValidateCapabilityEnum(cap, "isEnabled")) |
|
495 return false; |
|
496 |
|
497 MakeContextCurrent(); |
|
498 return gl->fIsEnabled(cap); |
|
499 } |
|
500 |
|
501 bool |
|
502 WebGLContext::ValidateCapabilityEnum(GLenum cap, const char* info) |
|
503 { |
|
504 switch (cap) { |
|
505 case LOCAL_GL_BLEND: |
|
506 case LOCAL_GL_CULL_FACE: |
|
507 case LOCAL_GL_DEPTH_TEST: |
|
508 case LOCAL_GL_DITHER: |
|
509 case LOCAL_GL_POLYGON_OFFSET_FILL: |
|
510 case LOCAL_GL_SAMPLE_ALPHA_TO_COVERAGE: |
|
511 case LOCAL_GL_SAMPLE_COVERAGE: |
|
512 case LOCAL_GL_SCISSOR_TEST: |
|
513 case LOCAL_GL_STENCIL_TEST: |
|
514 return true; |
|
515 case LOCAL_GL_RASTERIZER_DISCARD: |
|
516 return IsWebGL2(); |
|
517 default: |
|
518 ErrorInvalidEnumInfo(info, cap); |
|
519 return false; |
|
520 } |
|
521 } |
|
522 |
|
523 realGLboolean* |
|
524 WebGLContext::GetStateTrackingSlot(GLenum cap) |
|
525 { |
|
526 switch (cap) { |
|
527 case LOCAL_GL_SCISSOR_TEST: |
|
528 return &mScissorTestEnabled; |
|
529 case LOCAL_GL_DITHER: |
|
530 return &mDitherEnabled; |
|
531 case LOCAL_GL_RASTERIZER_DISCARD: |
|
532 return &mRasterizerDiscardEnabled; |
|
533 } |
|
534 |
|
535 return nullptr; |
|
536 } |