Bug 1194923 - Call glFlush before glDeleteFramebuffers on Adreno 420 devices. r=snorp
authorJamie Nicol <jnicol@mozilla.com>
Thu, 17 Sep 2015 04:41:00 +0200
changeset 295661 1bfcd86512b448b8c705b60134c6797197f574c1
parent 295660 4717107189fe6623d2e3a022e365b137fb0b2ae9
child 295662 80822711aca56dac51b0e311bc07f25d551ecead
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1194923
milestone43.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 1194923 - Call glFlush before glDeleteFramebuffers on Adreno 420 devices. r=snorp There is an occasional driver crash on the nexus 6, and possibly other Adreno 420 devices, which seems to occur in some circumstances after calling glDeleteFramebuffers. Calling glFlush before glDeleteFramebuffers prevents this. Add this workaround at least until it is better known what is going on.
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -311,16 +311,17 @@ GLContext::GLContext(const SurfaceCaps& 
     mCaps(caps),
     mScreen(nullptr),
     mLockedSurface(nullptr),
     mMaxTextureSize(0),
     mMaxCubeMapTextureSize(0),
     mMaxTextureImageSize(0),
     mMaxRenderbufferSize(0),
     mNeedsTextureSizeChecks(false),
+    mNeedsFlushBeforeDeleteFB(false),
     mWorkAroundDriverBugs(true),
     mHeavyGLCallsSinceLastFlush(false)
 {
     mOwningThreadId = PlatformThread::CurrentId();
 }
 
 GLContext::~GLContext() {
     NS_ASSERTION(IsDestroyed(), "GLContext implementation must call MarkDestroyed in destructor!");
@@ -611,16 +612,17 @@ GLContext::InitWithPrefix(const char *pr
             mInitialized = false;
 
         const char *rendererMatchStrings[size_t(GLRenderer::Other)] = {
                 "Adreno 200",
                 "Adreno 205",
                 "Adreno (TM) 200",
                 "Adreno (TM) 205",
                 "Adreno (TM) 320",
+                "Adreno (TM) 420",
                 "PowerVR SGX 530",
                 "PowerVR SGX 540",
                 "NVIDIA Tegra",
                 "Android Emulator",
                 "Gallium 0.4 on llvmpipe",
                 "Intel HD Graphics 3000 OpenGL Engine",
                 "Microsoft Basic Render Driver"
         };
@@ -1602,16 +1604,22 @@ GLContext::InitWithPrefix(const char *pr
 #ifdef MOZ_X11
         if (mWorkAroundDriverBugs &&
             mVendor == GLVendor::Nouveau) {
             // see bug 814716. Clamp MaxCubeMapTextureSize at 2K for Nouveau.
             mMaxCubeMapTextureSize = std::min(mMaxCubeMapTextureSize, 2048);
             mNeedsTextureSizeChecks = true;
         }
 #endif
+        if (mWorkAroundDriverBugs &&
+            Renderer() == GLRenderer::AdrenoTM420) {
+            // see bug 1194923. Calling glFlush before glDeleteFramebuffers
+            // prevents occasional driver crash.
+            mNeedsFlushBeforeDeleteFB = true;
+        }
 
         mMaxTextureImageSize = mMaxTextureSize;
 
         mMaxSamples = 0;
         if (IsSupported(GLFeature::framebuffer_multisample)) {
             fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples);
         }
 
@@ -2846,16 +2854,21 @@ GLContext::fDeleteFramebuffers(GLsizei n
     if (mScreen) {
         // Notify mScreen which framebuffers we're deleting.
         // Otherwise, we will get framebuffer binding mispredictions.
         for (int i = 0; i < n; i++) {
             mScreen->DeletingFB(names[i]);
         }
     }
 
+    // Avoid crash by flushing before glDeleteFramebuffers. See bug 1194923.
+    if (mNeedsFlushBeforeDeleteFB) {
+        fFlush();
+    }
+
     if (n == 1 && *names == 0) {
         // Deleting framebuffer 0 causes hangs on the DROID. See bug 623228.
     } else {
         raw_fDeleteFramebuffers(n, names);
     }
     TRACKING_CONTEXT(DeletedFramebuffers(this, n, names));
 }
 
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -164,16 +164,17 @@ enum class GLVendor {
 };
 
 enum class GLRenderer {
     Adreno200,
     Adreno205,
     AdrenoTM200,
     AdrenoTM205,
     AdrenoTM320,
+    AdrenoTM420,
     SGX530,
     SGX540,
     Tegra,
     AndroidEmulator,
     GalliumLlvmpipe,
     IntelHD3000,
     MicrosoftBasicRenderDriver,
     Other
@@ -3499,16 +3500,17 @@ protected:
 
     GLint mMaxTextureSize;
     GLint mMaxCubeMapTextureSize;
     GLint mMaxTextureImageSize;
     GLint mMaxRenderbufferSize;
     GLint mMaxViewportDims[2];
     GLsizei mMaxSamples;
     bool mNeedsTextureSizeChecks;
+    bool mNeedsFlushBeforeDeleteFB;
     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