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