gfx/gl/GLContextFeatures.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "GLContext.h"
     8 #include "nsPrintfCString.h"
    10 #ifdef XP_MACOSX
    11 #include "nsCocoaFeatures.h"
    12 #endif
    14 namespace mozilla {
    15 namespace gl {
    17 const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
    19 // ARB_ES2_compatibility is natively supported in OpenGL 4.1.
    20 static const unsigned int kGLCoreVersionForES2Compat = 410;
    22 // ARB_ES3_compatibility is natively supported in OpenGL 4.3.
    23 static const unsigned int kGLCoreVersionForES3Compat = 430;
    25 struct FeatureInfo
    26 {
    27     const char* mName;
    28     unsigned int mOpenGLVersion;
    29     unsigned int mOpenGLESVersion;
    30     GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
    31 };
    33 static const FeatureInfo sFeatureInfoArr[] = {
    34     {
    35         "bind_buffer_offset",
    36         0,   // OpenGL version
    37         0,   // OpenGL ES version
    38         {
    39             GLContext::EXT_transform_feedback,
    40             GLContext::NV_transform_feedback,
    41             GLContext::Extensions_End
    42         }
    43     },
    44     {
    45         "blend_minmax",
    46         200, // OpenGL version
    47         300, // OpenGL ES version
    48         {
    49             GLContext::EXT_blend_minmax,
    50             GLContext::Extensions_End
    51         }
    52     },
    53     {
    54         "depth_texture",
    55         200, // OpenGL version
    56         300, // OpenGL ES version
    57         {
    58             GLContext::ARB_depth_texture,
    59             GLContext::OES_depth_texture,
    60             // Intentionally avoid putting ANGLE_depth_texture here,
    61             // it does not offer quite the same functionality.
    62             GLContext::Extensions_End
    63         }
    64     },
    65     {
    66         "draw_buffers",
    67         200, // OpenGL version
    68         300, // OpenGL ES version
    69         {
    70             GLContext::ARB_draw_buffers,
    71             GLContext::EXT_draw_buffers,
    72             GLContext::Extensions_End
    73         }
    74     },
    75     {
    76         "draw_instanced",
    77         310, // OpenGL version
    78         300, // OpenGL ES version
    79         {
    80             GLContext::ARB_draw_instanced,
    81             GLContext::EXT_draw_instanced,
    82             GLContext::NV_draw_instanced,
    83             GLContext::ANGLE_instanced_arrays,
    84             GLContext::Extensions_End
    85         }
    86     },
    87     {
    88         "draw_range_elements",
    89         120, // OpenGL version
    90         300, // OpenGL ES version
    91         {
    92             GLContext::EXT_draw_range_elements,
    93             GLContext::Extensions_End
    94         }
    95     },
    96     {
    97         "element_index_uint",
    98         200, // OpenGL version
    99         300, // OpenGL ES version
   100         {
   101             GLContext::OES_element_index_uint,
   102             GLContext::Extensions_End
   103         }
   104     },
   105     {
   106         "ES2_compatibility",
   107         kGLCoreVersionForES2Compat,
   108         200, // OpenGL ES version
   109         {
   110             GLContext::ARB_ES2_compatibility,
   111             GLContext::Extensions_End
   112         }
   113     },
   114     {
   115         "ES3_compatibility",
   116         kGLCoreVersionForES3Compat,
   117         300, // OpenGL ES version
   118         {
   119             GLContext::ARB_ES3_compatibility,
   120             GLContext::Extensions_End
   121         }
   122     },
   123     {
   124         // Removes clamping for float color outputs from frag shaders.
   125         "frag_color_float",
   126         300, // OpenGL version
   127         300, // OpenGL ES version
   128         {
   129             GLContext::ARB_color_buffer_float,
   130             GLContext::EXT_color_buffer_float,
   131             GLContext::EXT_color_buffer_half_float,
   132             GLContext::Extensions_End
   133         }
   134     },
   135     {
   136         "frag_depth",
   137         200, // OpenGL version
   138         300, // OpenGL ES version
   139         {
   140             GLContext::EXT_frag_depth,
   141             GLContext::Extensions_End
   142         }
   143     },
   144     {
   145         "framebuffer_blit",
   146         300, // OpenGL version
   147         300, // OpenGL ES version
   148         {
   149             GLContext::EXT_framebuffer_blit,
   150             GLContext::ANGLE_framebuffer_blit,
   151             GLContext::Extensions_End
   152         }
   153     },
   154     {
   155         "framebuffer_multisample",
   156         300, // OpenGL version
   157         300, // OpenGL ES version
   158         {
   159             GLContext::EXT_framebuffer_multisample,
   160             GLContext::ANGLE_framebuffer_multisample,
   161             GLContext::Extensions_End
   162         }
   163     },
   164     {
   165         "framebuffer_object",
   166         300, // OpenGL version
   167         200, // OpenGL ES version
   168         {
   169             GLContext::ARB_framebuffer_object,
   170             GLContext::EXT_framebuffer_object,
   171             GLContext::Extensions_End
   172         }
   173     },
   174     {
   175         "get_query_object_iv",
   176         200, // OpenGL version
   177         0,   // OpenGL ES version
   178         {
   179             GLContext::Extensions_End
   180         }
   181         /*
   182          * XXX_get_query_object_iv only provide GetQueryObjectiv provided by
   183          * ARB_occlusion_query (added by OpenGL 2.0).
   184          */
   185     },
   186     {
   187         "instanced_arrays",
   188         330, // OpenGL version
   189         300, // OpenGL ES version
   190         {
   191             GLContext::ARB_instanced_arrays,
   192             GLContext::NV_instanced_arrays,
   193             GLContext::ANGLE_instanced_arrays,
   194             GLContext::Extensions_End
   195         }
   196     },
   197     {
   198         "instanced_non_arrays",
   199         330, // OpenGL version
   200         300, // OpenGL ES version
   201         {
   202             GLContext::ARB_instanced_arrays,
   203             GLContext::Extensions_End
   204         }
   205         /* This is an expanded version of `instanced_arrays` that allows for all
   206          * enabled active attrib arrays to have non-zero divisors.
   207          * ANGLE_instanced_arrays and NV_instanced_arrays forbid this, but GLES3
   208          * has no such restriction.
   209          */
   210     },
   211     {
   212         "occlusion_query",
   213         200, // OpenGL version
   214         0,   // OpenGL ES version
   215         {
   216             GLContext::Extensions_End
   217         }
   218         // XXX_occlusion_query depend on ARB_occlusion_query (added in OpenGL 2.0)
   219     },
   220     {
   221         "occlusion_query_boolean",
   222         kGLCoreVersionForES3Compat,
   223         300, // OpenGL ES version
   224         {
   225             GLContext::ARB_ES3_compatibility,
   226             GLContext::EXT_occlusion_query_boolean,
   227             GLContext::Extensions_End
   228         }
   229         /*
   230          * XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
   231          * but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
   232          * it is supported on desktop if ARB_ES3_compatibility because
   233          * EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
   234          */
   235     },
   236     {
   237         "occlusion_query2",
   238         330, // = min(330, kGLCoreVersionForES3Compat),
   239         300, // OpenGL ES version
   240         {
   241             GLContext::ARB_occlusion_query2,
   242             GLContext::ARB_ES3_compatibility,
   243             GLContext::EXT_occlusion_query_boolean,
   244             GLContext::Extensions_End
   245         }
   246         /*
   247          * XXX_occlusion_query2 (add in OpenGL 3.3) provide ANY_SAMPLES_PASSED,
   248          * which is provided by ARB_occlusion_query2, EXT_occlusion_query_boolean
   249          * (added in OpenGL ES 3.0) and ARB_ES3_compatibility
   250          */
   251     },
   252     {
   253         "packed_depth_stencil",
   254         300, // OpenGL version
   255         300, // OpenGL ES version
   256         {
   257             GLContext::EXT_packed_depth_stencil,
   258             GLContext::OES_packed_depth_stencil,
   259             GLContext::Extensions_End
   260         }
   261     },
   262     {
   263         "query_objects",
   264         200, // OpenGL version
   265         300, // OpenGL ES version
   266         {
   267             GLContext::EXT_occlusion_query_boolean,
   268             GLContext::Extensions_End
   269         }
   270         /*
   271          * XXX_query_objects only provide entry points commonly supported by
   272          * ARB_occlusion_query (added in OpenGL 2.0) and EXT_occlusion_query_boolean
   273          * (added in OpenGL ES 3.0)
   274          */
   275     },
   276     {
   277         "renderbuffer_float",
   278         300, // OpenGL version
   279         300, // OpenGL ES version
   280         {
   281             GLContext::ARB_texture_float,
   282             GLContext::EXT_color_buffer_float,
   283             GLContext::Extensions_End
   284         }
   285     },
   286     {
   287         "renderbuffer_half_float",
   288         300, // OpenGL version
   289         300, // OpenGL ES version
   290         {
   291             GLContext::ARB_texture_float,
   292             GLContext::EXT_color_buffer_half_float,
   293             GLContext::Extensions_End
   294         }
   295     },
   296     {
   297         "robustness",
   298         0,   // OpenGL version
   299         0,   // OpenGL ES version
   300         {
   301             GLContext::ARB_robustness,
   302             GLContext::EXT_robustness,
   303             GLContext::Extensions_End
   304         }
   305     },
   306     {
   307         "sRGB",
   308         300, // OpenGL version
   309         300, // OpenGL ES version
   310         {
   311             GLContext::EXT_sRGB,
   312             GLContext::Extensions_End
   313         }
   314     },
   315     {
   316         "standard_derivatives",
   317         200, // OpenGL version
   318         300, // OpenGL ES version
   319         {
   320             GLContext::OES_standard_derivatives,
   321             GLContext::Extensions_End
   322         }
   323     },
   324     {
   325         "texture_float",
   326         300, // OpenGL version
   327         300, // OpenGL ES version
   328         {
   329             GLContext::ARB_texture_float,
   330             GLContext::OES_texture_float,
   331             GLContext::Extensions_End
   332         }
   333     },
   334     {
   335         "texture_float_linear",
   336         310, // OpenGL version
   337         300, // OpenGL ES version
   338         {
   339             GLContext::ARB_texture_float,
   340             GLContext::OES_texture_float_linear,
   341             GLContext::Extensions_End
   342         }
   343     },
   344     {
   345         "texture_half_float",
   346         300, // OpenGL version
   347         300, // OpenGL ES version
   348         {
   349             GLContext::ARB_half_float_pixel,
   350             GLContext::ARB_texture_float,
   351             GLContext::NV_half_float,
   352             GLContext::Extensions_End
   353         }
   354         /**
   355          * We are not including OES_texture_half_float in this feature, because:
   356          *   GL_HALF_FLOAT     = 0x140B
   357          *   GL_HALF_FLOAT_ARB = 0x140B == GL_HALF_FLOAT
   358          *   GL_HALF_FLOAT_NV  = 0x140B == GL_HALF_FLOAT
   359          *   GL_HALF_FLOAT_OES = 0x8D61 != GL_HALF_FLOAT
   360          * WebGL handles this specifically with an OES_texture_half_float check.
   361          */
   362     },
   363     {
   364         "texture_half_float_linear",
   365         310, // OpenGL version
   366         300, // OpenGL ES version
   367         {
   368             GLContext::ARB_half_float_pixel,
   369             GLContext::ARB_texture_float,
   370             GLContext::NV_half_float,
   371             GLContext::OES_texture_half_float_linear,
   372             GLContext::Extensions_End
   373         }
   374     },
   375     {
   376         "texture_non_power_of_two",
   377         200, // OpenGL version
   378         300, // OpenGL ES version
   379         {
   380             GLContext::ARB_texture_non_power_of_two,
   381             GLContext::OES_texture_npot,
   382             GLContext::Extensions_End
   383         }
   384     },
   385     {
   386         "transform_feedback",
   387         300, // OpenGL version
   388         300, // OpenGL ES version
   389         {
   390             GLContext::EXT_transform_feedback,
   391             GLContext::NV_transform_feedback,
   392             GLContext::Extensions_End
   393         }
   394     },
   395     {
   396         "vertex_array_object",
   397         300, // OpenGL version
   398         300, // OpenGL ES version
   399         {
   400             GLContext::ARB_vertex_array_object,
   401             GLContext::OES_vertex_array_object,
   402             GLContext::APPLE_vertex_array_object,
   403             GLContext::Extensions_End
   404         }
   405     }
   406 };
   408 static inline const FeatureInfo&
   409 GetFeatureInfo(GLFeature feature)
   410 {
   411     static_assert(MOZ_ARRAY_LENGTH(sFeatureInfoArr) == size_t(GLFeature::EnumMax),
   412                   "Mismatched lengths for sFeatureInfoInfos and GLFeature enums");
   414     MOZ_ASSERT(feature < GLFeature::EnumMax,
   415                "GLContext::GetFeatureInfoInfo : unknown <feature>");
   417     return sFeatureInfoArr[size_t(feature)];
   418 }
   420 static inline uint32_t
   421 ProfileVersionForFeature(GLFeature feature, ContextProfile profile)
   422 {
   423     MOZ_ASSERT(profile != ContextProfile::Unknown,
   424                "GLContext::ProfileVersionForFeature : unknown <profile>");
   426     const FeatureInfo& featureInfo = GetFeatureInfo(feature);
   428     if (profile == ContextProfile::OpenGLES) {
   429         return featureInfo.mOpenGLESVersion;
   430     }
   432     return featureInfo.mOpenGLVersion;
   433 }
   435 static inline bool
   436 IsFeatureIsPartOfProfileVersion(GLFeature feature,
   437                                 ContextProfile profile, unsigned int version)
   438 {
   439     unsigned int profileVersion = ProfileVersionForFeature(feature, profile);
   441     /**
   442      * if `profileVersion` is zero, it means that no version of the profile
   443      * added support for the feature.
   444      */
   445     return profileVersion && version >= profileVersion;
   446 }
   448 const char*
   449 GLContext::GetFeatureName(GLFeature feature)
   450 {
   451     return GetFeatureInfo(feature).mName;
   452 }
   454 static bool
   455 CanReadSRGBFromFBOTexture(GLContext* gl)
   456 {
   457     if (!gl->WorkAroundDriverBugs())
   458         return true;
   460 #ifdef XP_MACOSX
   461     // Bug 843668:
   462     // MacOSX 10.6 reports to support EXT_framebuffer_sRGB and
   463     // EXT_texture_sRGB but fails to convert from sRGB to linear
   464     // when writing to an sRGB texture attached to an FBO.
   465     if (!nsCocoaFeatures::OnLionOrLater()) {
   466         return false;
   467     }
   468 #endif // XP_MACOSX
   469     return true;
   470 }
   472 void
   473 GLContext::InitFeatures()
   474 {
   475     for (size_t feature_index = 0; feature_index < size_t(GLFeature::EnumMax); feature_index++)
   476     {
   477         GLFeature feature = GLFeature(feature_index);
   479         if (IsFeatureIsPartOfProfileVersion(feature, mProfile, mVersion)) {
   480             mAvailableFeatures[feature_index] = true;
   481             continue;
   482         }
   484         mAvailableFeatures[feature_index] = false;
   486         const FeatureInfo& featureInfo = GetFeatureInfo(feature);
   488         for (size_t j = 0; true; j++)
   489         {
   490             MOZ_ASSERT(j < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
   492             if (featureInfo.mExtensions[j] == GLContext::Extensions_End) {
   493                 break;
   494             }
   496             if (IsExtensionSupported(featureInfo.mExtensions[j])) {
   497                 mAvailableFeatures[feature_index] = true;
   498                 break;
   499             }
   500         }
   501     }
   503     // Bug 843668: Work around limitation of the feature system.
   504     // For sRGB support under OpenGL to match OpenGL ES spec, check for both
   505     // EXT_texture_sRGB and EXT_framebuffer_sRGB is required.
   506     const bool aresRGBExtensionsAvailable =
   507         IsExtensionSupported(EXT_texture_sRGB) &&
   508         (IsExtensionSupported(ARB_framebuffer_sRGB) ||
   509          IsExtensionSupported(EXT_framebuffer_sRGB));
   511     mAvailableFeatures[size_t(GLFeature::sRGB)] =
   512         aresRGBExtensionsAvailable &&
   513         CanReadSRGBFromFBOTexture(this);
   514 }
   516 void
   517 GLContext::MarkUnsupported(GLFeature feature)
   518 {
   519     mAvailableFeatures[size_t(feature)] = false;
   521     const FeatureInfo& featureInfo = GetFeatureInfo(feature);
   523     for (size_t i = 0; true; i++)
   524     {
   525         MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
   527         if (featureInfo.mExtensions[i] == GLContext::Extensions_End) {
   528             break;
   529         }
   531         MarkExtensionUnsupported(featureInfo.mExtensions[i]);
   532     }
   534     MOZ_ASSERT(!IsSupported(feature), "GLContext::MarkUnsupported has failed!");
   536     NS_WARNING(nsPrintfCString("%s marked as unsupported", GetFeatureName(feature)).get());
   537 }
   539 } /* namespace gl */
   540 } /* namespace mozilla */

mercurial