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 "GLContext.h"
7 #include "nsPrintfCString.h"
8
9 namespace mozilla {
10 namespace gl {
11
12 const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
13
14 enum class GLVersion : uint32_t {
15 NONE = 0, // Feature is not supported natively by GL
16 GL1_2 = 120,
17 GL1_3 = 130,
18 GL2 = 200,
19 GL2_1 = 210,
20 GL3 = 300,
21 GL3_1 = 310,
22 GL3_2 = 320,
23 GL3_3 = 330,
24 GL4 = 400,
25 GL4_1 = 410,
26 GL4_2 = 420,
27 GL4_3 = 430,
28 };
29
30 enum class GLESVersion : uint32_t {
31 NONE = 0, // Feature is not support natively by GL ES
32 ES2 = 200,
33 ES3 = 300,
34 ES3_1 = 310,
35 ES3_2 = 320,
36 };
37
38 // ARB_ES2_compatibility is natively supported in OpenGL 4.1.
39 static const GLVersion kGLCoreVersionForES2Compat = GLVersion::GL4_1;
40
41 // ARB_ES3_compatibility is natively supported in OpenGL 4.3.
42 static const GLVersion kGLCoreVersionForES3Compat = GLVersion::GL4_3;
43
44 struct FeatureInfo {
45 const char* mName;
46
47 /* The (desktop) OpenGL version that provides this feature */
48 GLVersion mOpenGLVersion;
49
50 /* The OpenGL ES version that provides this feature */
51 GLESVersion mOpenGLESVersion;
52
53 /* If there is an ARB extension, and its function symbols are
54 * not decorated with an ARB suffix, then its extension ID should go
55 * here, and NOT in mExtensions. For example, ARB_vertex_array_object
56 * functions do not have an ARB suffix, because it is an extension that
57 * was created to match core GL functionality and will never differ.
58 * Some ARB extensions do have a suffix, if they were created before
59 * a core version of the functionality existed.
60 *
61 * If there is no such ARB extension, pass 0 (GLContext::Extension_None)
62 */
63 GLContext::GLExtensions mARBExtensionWithoutARBSuffix;
64
65 /* Extensions that also provide this feature */
66 GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
67 };
68
69 static const FeatureInfo sFeatureInfoArr[] = {
70 {"bind_buffer_offset",
71 GLVersion::NONE,
72 GLESVersion::NONE,
73 GLContext::Extension_None,
74 {
75
76 GLContext::EXT_transform_feedback, GLContext::NV_transform_feedback2,
77 GLContext::Extensions_End}},
78 {"blend_minmax",
79 GLVersion::GL2,
80 GLESVersion::ES3,
81 GLContext::Extension_None,
82 {GLContext::EXT_blend_minmax, GLContext::Extensions_End}},
83 {"clear_buffers",
84 GLVersion::GL3,
85 GLESVersion::ES3,
86 GLContext::Extension_None,
87 {GLContext::Extensions_End}},
88 {"copy_buffer",
89 GLVersion::GL3_1,
90 GLESVersion::ES3,
91 GLContext::ARB_copy_buffer,
92 {GLContext::Extensions_End}},
93 {"depth_texture",
94 GLVersion::GL2,
95 GLESVersion::ES3,
96 GLContext::Extension_None,
97 {GLContext::ARB_depth_texture, GLContext::OES_depth_texture,
98 // Intentionally avoid putting ANGLE_depth_texture here,
99 // it does not offer quite the same functionality.
100 GLContext::Extensions_End}},
101 {"draw_buffers",
102 GLVersion::GL2,
103 GLESVersion::ES3,
104 GLContext::Extension_None,
105 {GLContext::ARB_draw_buffers, GLContext::EXT_draw_buffers,
106 GLContext::Extensions_End}},
107 {"draw_instanced",
108 GLVersion::GL3_1,
109 GLESVersion::ES3,
110 GLContext::Extension_None,
111 {GLContext::ARB_draw_instanced, GLContext::EXT_draw_instanced,
112 GLContext::NV_draw_instanced, GLContext::ANGLE_instanced_arrays,
113 GLContext::Extensions_End}},
114 {"draw_range_elements",
115 GLVersion::GL1_2,
116 GLESVersion::ES3,
117 GLContext::Extension_None,
118 {GLContext::EXT_draw_range_elements, GLContext::Extensions_End}},
119 {"element_index_uint",
120 GLVersion::GL2,
121 GLESVersion::ES3,
122 GLContext::Extension_None,
123 {GLContext::OES_element_index_uint, GLContext::Extensions_End}},
124 {"ES2_compatibility",
125 kGLCoreVersionForES2Compat,
126 GLESVersion::ES2, // OpenGL ES version
127 GLContext::ARB_ES2_compatibility, // no suffix on ARB extension
128 {GLContext::Extensions_End}},
129 {"ES3_compatibility",
130 kGLCoreVersionForES3Compat,
131 GLESVersion::ES3, // OpenGL ES version
132 GLContext::ARB_ES3_compatibility, // no suffix on ARB extension
133 {GLContext::Extensions_End}},
134 {"EXT_color_buffer_float",
135 GLVersion::GL3,
136 GLESVersion::ES3_2,
137 GLContext::Extension_None,
138 {GLContext::EXT_color_buffer_float, GLContext::Extensions_End}},
139 {// Removes clamping for float color outputs from frag shaders.
140 "frag_color_float",
141 GLVersion::GL3,
142 GLESVersion::ES3,
143 GLContext::Extension_None,
144 {GLContext::ARB_color_buffer_float, GLContext::EXT_color_buffer_float,
145 GLContext::EXT_color_buffer_half_float, GLContext::Extensions_End}},
146 {"frag_depth",
147 GLVersion::GL2,
148 GLESVersion::ES3,
149 GLContext::Extension_None,
150 {GLContext::EXT_frag_depth, GLContext::Extensions_End}},
151 {// Check for just the blit framebuffer blit part of
152 // ARB_framebuffer_object
153 "framebuffer_blit",
154 GLVersion::GL3,
155 GLESVersion::ES3,
156 GLContext::ARB_framebuffer_object,
157 {GLContext::ANGLE_framebuffer_blit, GLContext::EXT_framebuffer_blit,
158 GLContext::NV_framebuffer_blit, GLContext::Extensions_End}},
159 {// Check for just the multisample renderbuffer part of
160 // ARB_framebuffer_object
161 "framebuffer_multisample",
162 GLVersion::GL3,
163 GLESVersion::ES3,
164 GLContext::ARB_framebuffer_object,
165 {GLContext::ANGLE_framebuffer_multisample,
166 GLContext::APPLE_framebuffer_multisample,
167 GLContext::EXT_framebuffer_multisample,
168 GLContext::EXT_multisampled_render_to_texture,
169 GLContext::Extensions_End}},
170 {// ARB_framebuffer_object support
171 "framebuffer_object",
172 GLVersion::GL3,
173 GLESVersion::ES3,
174 GLContext::ARB_framebuffer_object,
175 {GLContext::Extensions_End}},
176 {// EXT_framebuffer_object/OES_framebuffer_object support
177 "framebuffer_object_EXT_OES",
178 GLVersion::GL3,
179 GLESVersion::ES2,
180 GLContext::Extension_None,
181 {GLContext::EXT_framebuffer_object, GLContext::OES_framebuffer_object,
182 GLContext::Extensions_End}},
183 {"get_integer_indexed",
184 GLVersion::GL3,
185 GLESVersion::ES3,
186 GLContext::Extension_None,
187 {GLContext::EXT_draw_buffers2, GLContext::Extensions_End}},
188 {"get_integer64_indexed",
189 GLVersion::GL3_2,
190 GLESVersion::ES3,
191 GLContext::Extension_None,
192 {GLContext::Extensions_End}},
193 {"get_query_object_i64v",
194 GLVersion::GL3_3,
195 GLESVersion::NONE,
196 GLContext::ARB_timer_query,
197 {GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query,
198 GLContext::EXT_timer_query, GLContext::Extensions_End}},
199 {
200 "get_query_object_iv",
201 GLVersion::GL2,
202 GLESVersion::NONE,
203 GLContext::Extension_None,
204 {GLContext::Extensions_End}
205 /*
206 * XXX_get_query_object_iv only provide GetQueryObjectiv provided by
207 * ARB_occlusion_query (added by OpenGL 2.0).
208 */
209 },
210 {"gpu_shader4",
211 GLVersion::GL3,
212 GLESVersion::ES3,
213 GLContext::Extension_None,
214 {GLContext::EXT_gpu_shader4, GLContext::Extensions_End}},
215 {"instanced_arrays",
216 GLVersion::GL3_3,
217 GLESVersion::ES3,
218 GLContext::Extension_None,
219 {GLContext::ARB_instanced_arrays, GLContext::NV_instanced_arrays,
220 GLContext::ANGLE_instanced_arrays, GLContext::Extensions_End}},
221 {
222 "instanced_non_arrays",
223 GLVersion::GL3_3,
224 GLESVersion::ES3,
225 GLContext::Extension_None,
226 {GLContext::ARB_instanced_arrays, GLContext::Extensions_End}
227 /* This is an expanded version of `instanced_arrays` that allows for all
228 * enabled active attrib arrays to have non-zero divisors.
229 * ANGLE_instanced_arrays and NV_instanced_arrays forbid this, but GLES3
230 * has no such restriction.
231 */
232 },
233 {"internalformat_query",
234 GLVersion::GL4_2,
235 GLESVersion::ES3,
236 GLContext::ARB_internalformat_query,
237 {GLContext::Extensions_End}},
238 {"invalidate_framebuffer",
239 GLVersion::GL4_3,
240 GLESVersion::ES3,
241 GLContext::ARB_invalidate_subdata,
242 {GLContext::Extensions_End}},
243 {"map_buffer_range",
244 GLVersion::GL3,
245 GLESVersion::ES3,
246 GLContext::ARB_map_buffer_range,
247 {GLContext::Extensions_End}},
248 {
249 "occlusion_query",
250 GLVersion::GL2,
251 GLESVersion::NONE,
252 GLContext::Extension_None,
253 {GLContext::Extensions_End}
254 // XXX_occlusion_query depend on ARB_occlusion_query (added in
255 // OpenGL 2.0)
256 },
257 {
258 "occlusion_query_boolean",
259 kGLCoreVersionForES3Compat,
260 GLESVersion::ES3,
261 GLContext::ARB_ES3_compatibility,
262 {GLContext::EXT_occlusion_query_boolean, GLContext::Extensions_End}
263 /*
264 * XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
265 * but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
266 * it is supported on desktop if ARB_ES3_compatibility because
267 * EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
268 */
269 },
270 {
271 "occlusion_query2",
272 GLVersion::GL3_3,
273 GLESVersion::ES3,
274 GLContext::Extension_None,
275 {GLContext::ARB_occlusion_query2, GLContext::ARB_ES3_compatibility,
276 GLContext::EXT_occlusion_query_boolean, GLContext::Extensions_End}
277 /*
278 * XXX_occlusion_query2 (add in OpenGL 3.3) provide ANY_SAMPLES_PASSED,
279 * which is provided by ARB_occlusion_query2,
280 * EXT_occlusion_query_boolean (added in OpenGL ES 3.0) and
281 * ARB_ES3_compatibility
282 */
283 },
284 {"packed_depth_stencil",
285 GLVersion::GL3,
286 GLESVersion::ES3,
287 GLContext::Extension_None,
288 {GLContext::EXT_packed_depth_stencil, GLContext::OES_packed_depth_stencil,
289 GLContext::Extensions_End}},
290 {"prim_restart",
291 GLVersion::GL3_1,
292 GLESVersion::NONE,
293 GLContext::Extension_None,
294 {// GLContext::NV_primitive_restart, // Has different enum values.
295 GLContext::Extensions_End}},
296 {"prim_restart_fixed",
297 kGLCoreVersionForES3Compat,
298 GLESVersion::ES3,
299 GLContext::ARB_ES3_compatibility,
300 {GLContext::Extensions_End}},
301 {"query_counter",
302 GLVersion::GL3_3,
303 GLESVersion::NONE,
304 GLContext::ARB_timer_query,
305 {GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query,
306 // EXT_timer_query does NOT support GL_TIMESTAMP retrieval with
307 // QueryCounter.
308 GLContext::Extensions_End}},
309 {
310 "query_objects",
311 GLVersion::GL2,
312 GLESVersion::ES3,
313 GLContext::Extension_None,
314 {GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query,
315 GLContext::EXT_occlusion_query_boolean, GLContext::Extensions_End}
316 /*
317 * XXX_query_objects only provide entry points commonly supported by
318 * ARB_occlusion_query (added in OpenGL 2.0),
319 * EXT_occlusion_query_boolean (added in OpenGL ES 3.0), and
320 * ARB_timer_query (added in OpenGL 3.3)
321 */
322 },
323 {"query_time_elapsed",
324 GLVersion::GL3_3,
325 GLESVersion::NONE,
326 GLContext::ARB_timer_query,
327 {GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query,
328 GLContext::EXT_timer_query, GLContext::Extensions_End}},
329 {"read_buffer",
330 GLVersion::GL2,
331 GLESVersion::ES3,
332 GLContext::Extension_None,
333 {GLContext::Extensions_End}},
334 {"renderbuffer_color_float",
335 GLVersion::GL3,
336 GLESVersion::ES3_2,
337 GLContext::Extension_None,
338 {GLContext::ARB_texture_float, GLContext::EXT_color_buffer_float,
339 GLContext::Extensions_End}},
340 {"renderbuffer_color_half_float",
341 GLVersion::GL3,
342 GLESVersion::ES3_2,
343 GLContext::Extension_None,
344 {GLContext::ARB_texture_float, GLContext::EXT_color_buffer_float,
345 GLContext::EXT_color_buffer_half_float, GLContext::Extensions_End}},
346 {"robust_buffer_access_behavior",
347 GLVersion::NONE,
348 GLESVersion::NONE,
349 GLContext::Extension_None,
350 {GLContext::ARB_robust_buffer_access_behavior,
351 GLContext::KHR_robust_buffer_access_behavior, GLContext::Extensions_End}},
352 {"robustness",
353 GLVersion::NONE,
354 GLESVersion::NONE,
355 GLContext::Extension_None,
356 {GLContext::ARB_robustness, GLContext::EXT_robustness,
357 GLContext::KHR_robustness, GLContext::Extensions_End}},
358 {"sRGB",
359 GLVersion::GL3,
360 GLESVersion::ES3,
361 GLContext::ARB_framebuffer_sRGB,
362 {GLContext::EXT_sRGB, GLContext::EXT_framebuffer_sRGB,
363 GLContext::Extensions_End}},
364 {"sampler_objects",
365 GLVersion::GL3_3,
366 GLESVersion::ES3,
367 GLContext::ARB_sampler_objects,
368 {GLContext::Extensions_End}},
369 {"seamless_cube_map_opt_in",
370 GLVersion::GL3_2,
371 GLESVersion::NONE,
372 GLContext::ARB_seamless_cube_map,
373 {GLContext::Extensions_End}},
374 {"shader_texture_lod",
375 GLVersion::GL3,
376 GLESVersion::ES3,
377 GLContext::Extension_None,
378 {GLContext::ARB_shader_texture_lod, GLContext::EXT_shader_texture_lod,
379 GLContext::Extensions_End}},
380 {// Do we have separate DRAW and READ framebuffer bind points?
381 "split_framebuffer",
382 GLVersion::GL3,
383 GLESVersion::ES3,
384 GLContext::ARB_framebuffer_object,
385 {GLContext::ANGLE_framebuffer_blit,
386 GLContext::APPLE_framebuffer_multisample, GLContext::EXT_framebuffer_blit,
387 GLContext::NV_framebuffer_blit, GLContext::Extensions_End}},
388 {"standard_derivatives",
389 GLVersion::GL2,
390 GLESVersion::ES3,
391 GLContext::Extension_None,
392 {GLContext::OES_standard_derivatives, GLContext::Extensions_End}},
393 {"sync",
394 GLVersion::GL3_2,
395 GLESVersion::ES3,
396 GLContext::Extension_None,
397 {GLContext::ARB_sync, GLContext::APPLE_sync, GLContext::Extensions_End}},
398 {"texture_3D",
399 GLVersion::GL1_2,
400 GLESVersion::ES3,
401 GLContext::Extension_None,
402 {GLContext::EXT_texture3D, GLContext::OES_texture_3D,
403 GLContext::Extensions_End}},
404 {"texture_3D_compressed",
405 GLVersion::GL1_3,
406 GLESVersion::ES3,
407 GLContext::Extension_None,
408 {GLContext::ARB_texture_compression, GLContext::OES_texture_3D,
409 GLContext::Extensions_End}},
410 {"texture_3D_copy",
411 GLVersion::GL1_2,
412 GLESVersion::ES3,
413 GLContext::Extension_None,
414 {GLContext::EXT_copy_texture, GLContext::OES_texture_3D,
415 GLContext::Extensions_End}},
416 {"texture_float",
417 GLVersion::GL3,
418 GLESVersion::ES3,
419 GLContext::Extension_None,
420 {GLContext::ARB_texture_float, GLContext::OES_texture_float,
421 GLContext::Extensions_End}},
422 {"texture_float_linear",
423 GLVersion::GL3_1,
424 GLESVersion::ES3,
425 GLContext::Extension_None,
426 {GLContext::ARB_texture_float, GLContext::OES_texture_float_linear,
427 GLContext::Extensions_End}},
428 {
429 "texture_half_float",
430 GLVersion::GL3,
431 GLESVersion::ES3,
432 GLContext::Extension_None,
433 {GLContext::ARB_half_float_pixel, GLContext::ARB_texture_float,
434 GLContext::NV_half_float, GLContext::Extensions_End}
435 /**
436 * We are not including OES_texture_half_float in this feature, because:
437 * GL_HALF_FLOAT = 0x140B
438 * GL_HALF_FLOAT_ARB = 0x140B == GL_HALF_FLOAT
439 * GL_HALF_FLOAT_NV = 0x140B == GL_HALF_FLOAT
440 * GL_HALF_FLOAT_OES = 0x8D61 != GL_HALF_FLOAT
441 * WebGL handles this specifically with an OES_texture_half_float check.
442 */
443 },
444 {"texture_half_float_linear",
445 GLVersion::GL3_1,
446 GLESVersion::ES3,
447 GLContext::Extension_None,
448 {GLContext::ARB_half_float_pixel, GLContext::ARB_texture_float,
449 GLContext::NV_half_float, GLContext::OES_texture_half_float_linear,
450 GLContext::Extensions_End}},
451 {"texture_non_power_of_two",
452 GLVersion::GL2,
453 GLESVersion::ES3,
454 GLContext::Extension_None,
455 {GLContext::ARB_texture_non_power_of_two, GLContext::OES_texture_npot,
456 GLContext::Extensions_End}},
457 {"texture_rg",
458 GLVersion::GL3,
459 GLESVersion::ES3,
460 GLContext::ARB_texture_rg,
461 {GLContext::Extensions_End}},
462 {"texture_storage",
463 GLVersion::GL4_2,
464 GLESVersion::ES3,
465 GLContext::ARB_texture_storage,
466 {/*
467 * Not including GL_EXT_texture_storage here because it
468 * doesn't guarantee glTexStorage3D, which is required for
469 * WebGL 2.
470 */
471 GLContext::Extensions_End}},
472 {"texture_swizzle",
473 GLVersion::GL3_3,
474 GLESVersion::ES3,
475 GLContext::ARB_texture_swizzle,
476 {GLContext::Extensions_End}},
477 {"transform_feedback2",
478 GLVersion::GL4,
479 GLESVersion::ES3,
480 GLContext::ARB_transform_feedback2,
481 {GLContext::NV_transform_feedback2, GLContext::Extensions_End}},
482 {"uniform_buffer_object",
483 GLVersion::GL3_1,
484 GLESVersion::ES3,
485 GLContext::ARB_uniform_buffer_object,
486 {GLContext::Extensions_End}},
487 {"uniform_matrix_nonsquare",
488 GLVersion::GL2_1,
489 GLESVersion::ES3,
490 GLContext::Extension_None,
491 {GLContext::Extensions_End}},
492 {"vertex_array_object",
493 GLVersion::GL3,
494 GLESVersion::ES3,
495 GLContext::ARB_vertex_array_object, // ARB extension
496 {GLContext::OES_vertex_array_object, GLContext::APPLE_vertex_array_object,
497 GLContext::Extensions_End}}};
498
GetFeatureInfo(GLFeature feature)499 static inline const FeatureInfo& GetFeatureInfo(GLFeature feature) {
500 static_assert(MOZ_ARRAY_LENGTH(sFeatureInfoArr) == size_t(GLFeature::EnumMax),
501 "Mismatched lengths for sFeatureInfoInfos and GLFeature enums");
502
503 MOZ_ASSERT(feature < GLFeature::EnumMax,
504 "GLContext::GetFeatureInfoInfo : unknown <feature>");
505
506 return sFeatureInfoArr[size_t(feature)];
507 }
508
ProfileVersionForFeature(GLFeature feature,ContextProfile profile)509 static inline uint32_t ProfileVersionForFeature(GLFeature feature,
510 ContextProfile profile) {
511 MOZ_ASSERT(profile != ContextProfile::Unknown,
512 "GLContext::ProfileVersionForFeature : unknown <profile>");
513
514 const FeatureInfo& featureInfo = GetFeatureInfo(feature);
515
516 if (profile == ContextProfile::OpenGLES)
517 return (uint32_t)featureInfo.mOpenGLESVersion;
518
519 return (uint32_t)featureInfo.mOpenGLVersion;
520 }
521
IsFeaturePartOfProfileVersion(GLFeature feature,ContextProfile profile,unsigned int version)522 bool IsFeaturePartOfProfileVersion(GLFeature feature, ContextProfile profile,
523 unsigned int version) {
524 unsigned int profileVersion = ProfileVersionForFeature(feature, profile);
525
526 /**
527 * if `profileVersion` is zero, it means that no version of the profile
528 * added support for the feature.
529 */
530 return profileVersion && version >= profileVersion;
531 }
532
IsFeatureProvidedByCoreSymbols(GLFeature feature)533 bool GLContext::IsFeatureProvidedByCoreSymbols(GLFeature feature) {
534 if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) return true;
535
536 if (IsExtensionSupported(
537 GetFeatureInfo(feature).mARBExtensionWithoutARBSuffix))
538 return true;
539
540 return false;
541 }
542
GetFeatureName(GLFeature feature)543 const char* GLContext::GetFeatureName(GLFeature feature) {
544 return GetFeatureInfo(feature).mName;
545 }
546
InitFeatures()547 void GLContext::InitFeatures() {
548 for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax);
549 featureId++) {
550 GLFeature feature = GLFeature(featureId);
551
552 if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) {
553 mAvailableFeatures[featureId] = true;
554 continue;
555 }
556
557 mAvailableFeatures[featureId] = false;
558
559 const FeatureInfo& featureInfo = GetFeatureInfo(feature);
560
561 if (IsExtensionSupported(featureInfo.mARBExtensionWithoutARBSuffix)) {
562 mAvailableFeatures[featureId] = true;
563 continue;
564 }
565
566 for (size_t j = 0; true; j++) {
567 MOZ_ASSERT(j < kMAX_EXTENSION_GROUP_SIZE,
568 "kMAX_EXTENSION_GROUP_SIZE too small");
569
570 if (featureInfo.mExtensions[j] == GLContext::Extensions_End) break;
571
572 if (IsExtensionSupported(featureInfo.mExtensions[j])) {
573 mAvailableFeatures[featureId] = true;
574 break;
575 }
576 }
577 }
578
579 if (ShouldDumpExts()) {
580 for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax);
581 featureId++) {
582 GLFeature feature = GLFeature(featureId);
583 printf_stderr("[%s] Feature::%s\n",
584 IsSupported(feature) ? "enabled" : "disabled",
585 GetFeatureName(feature));
586 }
587 }
588 }
589
MarkUnsupported(GLFeature feature)590 void GLContext::MarkUnsupported(GLFeature feature) {
591 mAvailableFeatures[size_t(feature)] = false;
592
593 const FeatureInfo& featureInfo = GetFeatureInfo(feature);
594
595 for (size_t i = 0; true; i++) {
596 MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE,
597 "kMAX_EXTENSION_GROUP_SIZE too small");
598
599 if (featureInfo.mExtensions[i] == GLContext::Extensions_End) break;
600
601 MarkExtensionUnsupported(featureInfo.mExtensions[i]);
602 }
603
604 MOZ_ASSERT(!IsSupported(feature), "GLContext::MarkUnsupported has failed!");
605
606 NS_WARNING(
607 nsPrintfCString("%s marked as unsupported", GetFeatureName(feature))
608 .get());
609 }
610
611 } /* namespace gl */
612 } /* namespace mozilla */
613