Bug 867226 - Don't crash if we can't create a valid framebuffer. r=bjacob
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 11 Jun 2013 11:38:03 +1200
changeset 134579 92b758cba0f17448b274a6fab3061b11adf20b44
parent 134578 6fac977ad9eaea999bd9bb02c7f9de5213251170
child 134580 9ce9c145e07238c62803c509c6f7d0db1b366402
push id29282
push usermwoodrow@mozilla.com
push dateMon, 10 Jun 2013 23:38:13 +0000
treeherdermozilla-inbound@92b758cba0f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs867226
milestone24.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 867226 - Don't crash if we can't create a valid framebuffer. r=bjacob
gfx/layers/opengl/ContainerLayerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
--- a/gfx/layers/opengl/ContainerLayerOGL.cpp
+++ b/gfx/layers/opengl/ContainerLayerOGL.cpp
@@ -229,21 +229,26 @@ ContainerRender(Container* aContainer,
         framebufferRect.y += transform.y0;
         aContainer->mSupportsComponentAlphaChildren = gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering();
       }
     }
 
     aContainer->gl()->PushViewportRect();
     framebufferRect -= childOffset;
     if (!aManager->CompositingDisabled()) {
-      aManager->CreateFBOWithTexture(framebufferRect,
-                                     mode,
-                                     aPreviousFrameBuffer,
-                                     &frameBuffer,
-                                     &containerSurface);
+      if (!aManager->CreateFBOWithTexture(framebufferRect,
+                                          mode,
+                                          aPreviousFrameBuffer,
+                                          &frameBuffer,
+                                          &containerSurface)) {
+        aContainer->gl()->PopViewportRect();
+        aContainer->gl()->PopScissorRect();
+        aContainer->gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
+        return;
+      }
     }
     childOffset.x = visibleRect.x;
     childOffset.y = visibleRect.y;
   } else {
     frameBuffer = aPreviousFrameBuffer;
     aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) ||
       (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren());
   }
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -1177,17 +1177,17 @@ GetFrameBufferInternalFormat(GLContext* 
                              nsIWidget* aWidget)
 {
   if (aCurrentFrameBuffer == 0) { // default framebuffer
     return aWidget->GetGLFrameBufferFormat();
   }
   return LOCAL_GL_RGBA;
 }
 
-void
+bool
 LayerManagerOGL::CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
                                       GLuint aCurrentFrameBuffer,
                                       GLuint *aFBO, GLuint *aTexture)
 {
   GLuint tex, fbo;
 
   mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
   mGLContext->fGenTextures(1, &tex);
@@ -1270,29 +1270,35 @@ LayerManagerOGL::CreateFBOWithTexture(co
     msg.Append("Framebuffer not complete -- error 0x");
     msg.AppendInt(result, 16);
     msg.Append(", mFBOTextureTarget 0x");
     msg.AppendInt(mFBOTextureTarget, 16);
     msg.Append(", aRect.width ");
     msg.AppendInt(aRect.width);
     msg.Append(", aRect.height ");
     msg.AppendInt(aRect.height);
-    NS_RUNTIMEABORT(msg.get());
+    NS_WARNING(msg.get());
+
+    mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
+    mGLContext->fDeleteFramebuffers(1, &fbo);
+    mGLContext->fDeleteTextures(1, &tex);
+    return false;
   }
 
   SetupPipeline(aRect.width, aRect.height, DontApplyWorldTransform);
   mGLContext->fScissor(0, 0, aRect.width, aRect.height);
 
   if (aInit == InitModeClear) {
     mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
     mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
   }
 
   *aFBO = fbo;
   *aTexture = tex;
+  return true;
 }
 
 TemporaryRef<DrawTarget>
 LayerManagerOGL::CreateDrawTarget(const IntSize &aSize,
                                   SurfaceFormat aFormat)
 {
 #ifdef XP_MACOSX
   // We don't want to accelerate if the surface is too small which indicates
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ b/gfx/layers/opengl/LayerManagerOGL.h
@@ -207,17 +207,17 @@ public:
   };
 
   /* Create a FBO backed by a texture; will leave the FBO
    * bound.  Note that the texture target type will be
    * of the type returned by FBOTextureTarget; different
    * shaders are required to sample from the different
    * texture types.
    */
-  void CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
+  bool CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
                             GLuint aCurrentFrameBuffer,
                             GLuint *aFBO, GLuint *aTexture);
 
   GLuint QuadVBO() { return mQuadVBO; }
   GLintptr QuadVBOVertexOffset() { return 0; }
   GLintptr QuadVBOTexCoordOffset() { return sizeof(float)*4*2; }
   GLintptr QuadVBOFlippedTexCoordOffset() { return sizeof(float)*8*2; }