Bug 741689 - Disable poorly implemented GL extensions on load - r=bjacob
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 04 Apr 2012 18:44:55 -0700
changeset 91030 3a06c3ef2c1b0d2f733db4322c20901c6460c330
parent 91029 d0430a04d92a92dfa26f16ae631c09625d8f86b6
child 91031 e529dbc6eddbe5e6505bcedab1b5065b3ab3df38
push id7987
push userjgilbert@mozilla.com
push dateThu, 05 Apr 2012 01:45:15 +0000
treeherdermozilla-inbound@3a06c3ef2c1b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs741689
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 741689 - Disable poorly implemented GL extensions on load - r=bjacob
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderGLX.cpp
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -365,71 +365,102 @@ GLContext::InitWithPrefix(const char *pr
 
         NS_ASSERTION(!IsExtensionSupported(GLContext::ARB_pixel_buffer_object) ||
                      (mSymbols.fMapBuffer && mSymbols.fUnmapBuffer),
                      "ARB_pixel_buffer_object supported without glMapBuffer/UnmapBuffer being available!");
 
         if (SupportsRobustness()) {
             if (IsExtensionSupported(ARB_robustness)) {
                 SymLoadStruct robustnessSymbols[] = {
-                    { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusARB", NULL } },
-                    { NULL, { NULL } },
+                    { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusARB", nsnull } },
+                    { nsnull, { nsnull } },
                 };
 
                 if (!LoadSymbols(&robustnessSymbols[0], trygl, prefix)) {
                     NS_ERROR("GL supports ARB_robustness without supplying GetGraphicsResetStatusARB.");
-                    mInitialized = false;
+
+                    MarkExtensionUnsupported(ARB_robustness);
+                    mSymbols.fGetGraphicsResetStatus = nsnull;
                 } else {
                     mHasRobustness = true;
                 }
-            } else if (IsExtensionSupported(EXT_robustness)) {
+            }
+            if (!IsExtensionSupported(ARB_robustness) &&
+                IsExtensionSupported(EXT_robustness)) {
                 SymLoadStruct robustnessSymbols[] = {
-                    { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusEXT", NULL } },
-                    { NULL, { NULL } },
+                    { (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusEXT", nsnull } },
+                    { nsnull, { nsnull } },
                 };
 
                 if (!LoadSymbols(&robustnessSymbols[0], trygl, prefix)) {
-                    NS_ERROR("GL supports EGL_robustness without supplying GetGraphicsResetStatusEXT.");
-                    mInitialized = false;
+                    NS_ERROR("GL supports EXT_robustness without supplying GetGraphicsResetStatusEXT.");
+
+                    MarkExtensionUnsupported(EXT_robustness);
+                    mSymbols.fGetGraphicsResetStatus = nsnull;
                 } else {
                     mHasRobustness = true;
                 }
             }
         }
 
         // Check for aux symbols based on extensions
         if (IsExtensionSupported(GLContext::ANGLE_framebuffer_blit) ||
-            IsExtensionSupported(GLContext::EXT_framebuffer_blit)) {
+            IsExtensionSupported(GLContext::EXT_framebuffer_blit))
+        {
             SymLoadStruct auxSymbols[] = {
-                    { (PRFuncPtr*) &mSymbols.fBlitFramebuffer, { "BlitFramebuffer", "BlitFramebufferEXT", "BlitFramebufferANGLE", NULL } },
-                    { NULL, { NULL } },
+                {
+                    (PRFuncPtr*) &mSymbols.fBlitFramebuffer,
+                    {
+                        "BlitFramebuffer",
+                        "BlitFramebufferEXT",
+                        "BlitFramebufferANGLE",
+                        nsnull
+                    }
+                },
+                { nsnull, { nsnull } },
             };
             if (!LoadSymbols(&auxSymbols[0], trygl, prefix)) {
                 NS_ERROR("GL supports framebuffer_blit without supplying glBlitFramebuffer");
-                mInitialized = false;
+
+                MarkExtensionUnsupported(ANGLE_framebuffer_blit);
+                MarkExtensionUnsupported(EXT_framebuffer_blit);
+                mSymbols.fBlitFramebuffer = nsnull;
             }
         }
 
-        if (IsExtensionSupported(GLContext::ANGLE_framebuffer_multisample) ||
-            IsExtensionSupported(GLContext::EXT_framebuffer_multisample)) {
+        if (SupportsOffscreenSplit() &&
+            ( IsExtensionSupported(GLContext::ANGLE_framebuffer_multisample) ||
+              IsExtensionSupported(GLContext::EXT_framebuffer_multisample) ))
+        {
             SymLoadStruct auxSymbols[] = {
-                    { (PRFuncPtr*) &mSymbols.fRenderbufferStorageMultisample, { "RenderbufferStorageMultisample", "RenderbufferStorageMultisampleEXT", "RenderbufferStorageMultisampleANGLE", NULL } },
-                    { NULL, { NULL } },
+                {
+                    (PRFuncPtr*) &mSymbols.fRenderbufferStorageMultisample,
+                    {
+                        "RenderbufferStorageMultisample",
+                        "RenderbufferStorageMultisampleEXT",
+                        "RenderbufferStorageMultisampleANGLE",
+                        nsnull
+                    }
+                },
+                { nsnull, { nsnull } },
             };
             if (!LoadSymbols(&auxSymbols[0], trygl, prefix)) {
                 NS_ERROR("GL supports framebuffer_multisample without supplying glRenderbufferStorageMultisample");
-                mInitialized = false;
+
+                MarkExtensionUnsupported(ANGLE_framebuffer_multisample);
+                MarkExtensionUnsupported(EXT_framebuffer_multisample);
+                mSymbols.fRenderbufferStorageMultisample = nsnull;
             }
         }
        
         // Load developer symbols, don't fail if we can't find them.
         SymLoadStruct auxSymbols[] = {
-                { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", NULL } },
-                { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", NULL } },
-                { NULL, { NULL } },
+                { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nsnull } },
+                { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", nsnull } },
+                { nsnull, { nsnull } },
         };
         LoadSymbols(&auxSymbols[0], trygl, prefix);
     }
 
     if (mInitialized) {
         GLint v[4];
 
         fGetIntegerv(LOCAL_GL_SCISSOR_BOX, v);
@@ -562,22 +593,16 @@ CopyAndPadTextureData(const GLvoid* srcB
         rowDest = static_cast<unsigned char*>(dstBuffer) + srcWidth * pixelsize;
         for (GLsizei h = 0; h < padHeight; ++h) {
             memcpy(rowDest, rowDest - pixelsize, pixelsize);
             rowDest += dstWidth * pixelsize;
         }
     }
 }
 
-bool
-GLContext::IsExtensionSupported(const char *extension)
-{
-    return ListHasExtension(fGetString(LOCAL_GL_EXTENSIONS), extension);
-}
-
 // In both of these cases (for the Adreno at least) it is impossible
 // to determine good or bad driver versions for POT texture uploads,
 // so blacklist them all. Newer drivers use a different rendering
 // string in the form "Adreno (TM) 200" and the drivers we've seen so
 // far work fine with NPOT textures, so don't blacklist those until we
 // have evidence of any problems with them.
 bool
 GLContext::CanUploadSubTextures()
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -1502,22 +1502,23 @@ public:
         EXT_robustness,
         Extensions_Max
     };
 
     bool IsExtensionSupported(GLExtensions aKnownExtension) {
         return mAvailableExtensions[aKnownExtension];
     }
 
-    // for unknown extensions
-    bool IsExtensionSupported(const char *extension);
+    void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
+        mAvailableExtensions[aKnownExtension] = 0;
+    }
 
     // Shared code for GL extensions and GLX extensions.
     static bool ListHasExtension(const GLubyte *extensions,
-                                   const char *extension);
+                                 const char *extension);
 
     GLint GetMaxTextureSize() { return mMaxTextureSize; }
     GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
     void SetFlipped(bool aFlipped) { mFlipped = aFlipped; }
 
     // this should just be a std::bitset, but that ended up breaking
     // MacOS X builds; see bug 584919.  We can replace this with one
     // later on.  This is handy to use in WebGL contexts as well,
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -771,17 +771,17 @@ TRY_AGAIN_NO_SHARING:
     bool Init()
     {
         MakeCurrent();
         SetupLookupFunction();
         if (!InitWithPrefix("gl", true)) {
             return false;
         }
 
-        if (!IsExtensionSupported("GL_EXT_framebuffer_object"))
+        if (!IsExtensionSupported(EXT_framebuffer_object))
             return false;
 
         InitFramebuffers();
 
         return true;
     }
 
     bool MakeCurrentImpl(bool aForce = false)