Bug 1288446 - Call glCheckFramebufferStatus after glFramebufferTexture2D to avoid driver crash; r?jrmuizel draft
authorJamie Nicol <jnicol@mozilla.com>
Thu, 08 Sep 2016 15:29:44 +0100
changeset 411724 362b32c30f3e9c47d5292839ddb52a4d5d77ef2b
parent 411657 938ce16be25f9c551c19ef8938e8717ed3d41ff5
child 530795 6fc5a1e5d979a6e1a9f81d1e61ec553f0e704c0e
push id28964
push userbmo:jnicol@mozilla.com
push dateThu, 08 Sep 2016 14:51:27 +0000
reviewersjrmuizel
bugs1288446
milestone51.0a1
Bug 1288446 - Call glCheckFramebufferStatus after glFramebufferTexture2D to avoid driver crash; r?jrmuizel Some PowerVR SGX540 devices running Android 4.0 were crashing when uploading texture data with glTexSubImage2D. This was unearthed by a Skia upgrade which removed what should have been an unnecessary OpenGL call. This reinstates the OpenGL call which prevents the crash, but at a GLContext level rather than in Skia. MozReview-Commit-ID: Dub8VSs2Dzd
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -466,16 +466,17 @@ GLContext::GLContext(CreateContextFlags 
     mMaxTextureSize(0),
     mMaxCubeMapTextureSize(0),
     mMaxTextureImageSize(0),
     mMaxRenderbufferSize(0),
     mMaxSamples(0),
     mNeedsTextureSizeChecks(false),
     mNeedsFlushBeforeDeleteFB(false),
     mTextureAllocCrashesOnMapFailure(false),
+    mNeedsCheckAfterAttachTextureToFb(false),
     mWorkAroundDriverBugs(true),
     mHeavyGLCallsSinceLastFlush(false)
 {
     mMaxViewportDims[0] = 0;
     mMaxViewportDims[1] = 0;
     mOwningThreadId = PlatformThread::CurrentId();
 }
 
@@ -1058,16 +1059,27 @@ GLContext::InitWithPrefixImpl(const char
          Renderer() == GLRenderer::AdrenoTM320 ||
          Renderer() == GLRenderer::AdrenoTM330) &&
         AndroidBridge::Bridge()->GetAPIVersion() < 21) {
         // Bug 1164027. Driver crashes when functions such as
         // glTexImage2D fail due to virtual memory exhaustion.
         mTextureAllocCrashesOnMapFailure = true;
     }
 #endif
+#if MOZ_WIDGET_ANDROID
+    if (mWorkAroundDriverBugs &&
+        Renderer() == GLRenderer::SGX540 &&
+        AndroidBridge::Bridge()->GetAPIVersion() <= 15) {
+        // Bug 1288446. Driver sometimes crashes when uploading data to a
+        // texture if the render target has changed since the texture was
+        // rendered from. Calling glCheckFramebufferStatus after
+        // glFramebufferTexture2D prevents the crash.
+        mNeedsCheckAfterAttachTextureToFb = true;
+    }
+#endif
 
     mMaxTextureImageSize = mMaxTextureSize;
 
     if (IsSupported(GLFeature::framebuffer_multisample)) {
         fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples);
     }
 
     ////////////////////////////////////////////////////////////////////////////
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -1962,16 +1962,19 @@ public:
         mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
         AFTER_GL_CALL;
     }
 
     void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level) {
         BEFORE_GL_CALL;
         mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level);
         AFTER_GL_CALL;
+        if (mNeedsCheckAfterAttachTextureToFb) {
+            fCheckFramebufferStatus(target);
+        }
     }
 
     void fFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fFramebufferTextureLayer);
         mSymbols.fFramebufferTextureLayer(target, attachment, texture, level, layer);
         AFTER_GL_CALL;
     }
@@ -3526,16 +3529,17 @@ protected:
     GLint mMaxCubeMapTextureSize;
     GLint mMaxTextureImageSize;
     GLint mMaxRenderbufferSize;
     GLint mMaxViewportDims[2];
     GLsizei mMaxSamples;
     bool mNeedsTextureSizeChecks;
     bool mNeedsFlushBeforeDeleteFB;
     bool mTextureAllocCrashesOnMapFailure;
+    bool mNeedsCheckAfterAttachTextureToFb;
     bool mWorkAroundDriverBugs;
 
     bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
         if (mNeedsTextureSizeChecks) {
             // some drivers incorrectly handle some large texture sizes that are below the
             // max texture size that they report. So we check ourselves against our own values
             // (mMax[CubeMap]TextureSize).
             // see bug 737182 for Mac Intel 2D textures