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