tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GLContextFeatures.cpp (22397B)


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