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