Bug 929506 - Check that gl->MakeCurrent returns true when using OpenGL on the Compositor side. r=bjacob
authorNicolas Silva <nical@mozilla.com>
Tue, 03 Dec 2013 11:44:46 +0100
changeset 174197 e249103c2049999aa9aba68faa7c8a04bdaa7027
parent 174196 cd2a2e6b360b1ac21d53e8bd81c0236a291b9f43
child 174198 3ac6ea6491a85377e2c044d28a01f85d12a55076
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs929506
milestone28.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 929506 - Check that gl->MakeCurrent returns true when using OpenGL on the Compositor side. r=bjacob
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/TextureHostOGL.cpp
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -300,27 +300,28 @@ CompositorOGL::GetTemporaryTexture(GLenu
     size_t prevLength = mTextures.Length();
     mTextures.SetLength(index + 1);
     for(unsigned int i = prevLength; i <= index; ++i) {
       mTextures[i] = 0;
     }
   }
   // lazily initialize the temporary textures
   if (!mTextures[index]) {
-    gl()->MakeCurrent();
+    if (!gl()->MakeCurrent()) {
+      return 0;
+    }
     gl()->fGenTextures(1, &mTextures[index]);
   }
   return mTextures[index];
 }
 
 void
 CompositorOGL::Destroy()
 {
-  if (gl()) {
-    gl()->MakeCurrent();
+  if (gl() && gl()->MakeCurrent()) {
     if (mTextures.Length() > 0) {
       gl()->fDeleteTextures(mTextures.Length(), &mTextures[0]);
     }
     mVBOs.Flush(gl());
     if (mFPS) {
       if (mFPS->mTexture > 0)
         gl()->fDeleteTextures(1, &mFPS->mTexture);
       mFPS->mVBOs.Flush(gl());
@@ -341,17 +342,21 @@ CompositorOGL::CleanupResources()
 
   nsRefPtr<GLContext> ctx = mGLContext->GetSharedContext();
   if (!ctx) {
     ctx = mGLContext;
   }
 
   mPrograms.Clear();
 
-  ctx->MakeCurrent();
+  if (!ctx->MakeCurrent()) {
+    mQuadVBO = 0;
+    mGLContext = nullptr;
+    return;
+  }
 
   ctx->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
 
   if (mQuadVBO) {
     ctx->fDeleteBuffers(1, &mQuadVBO);
     mQuadVBO = 0;
   }
 
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -200,28 +200,30 @@ void CompositableDataGonkOGL::SetComposi
 void CompositableDataGonkOGL::ClearData()
 {
   DeleteTextureIfPresent();
 }
 
 GLuint CompositableDataGonkOGL::GetTexture()
 {
   if (!mTexture) {
-    gl()->MakeCurrent();
-    gl()->fGenTextures(1, &mTexture);
+    if (gl()->MakeCurrent()) {
+      gl()->fGenTextures(1, &mTexture);
+    }
   }
   return mTexture;
 }
 
 void
 CompositableDataGonkOGL::DeleteTextureIfPresent()
 {
   if (mTexture) {
-    gl()->MakeCurrent();
-    gl()->fDeleteTextures(1, &mTexture);
+    if (gl()->MakeCurrent()) {
+      gl()->fDeleteTextures(1, &mTexture);
+    }
   }
 }
 
 bool
 TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
                                      TextureFlags aFlags,
                                      nsIntRegion* aDestRegion,
                                      gfx::IntPoint* aSrcOffset)
@@ -603,17 +605,21 @@ SharedDeprecatedTextureHostOGL::SetCompo
   }
   mGL = glCompositor ? glCompositor->gl() : nullptr;
 }
 
 void
 SharedDeprecatedTextureHostOGL::DeleteTextures()
 {
   MOZ_ASSERT(mGL);
-  mGL->MakeCurrent();
+  if (!mGL->MakeCurrent()) {
+    mSharedHandle = 0;
+    mTextureHandle = 0;
+    return;
+  }
   if (mSharedHandle) {
     mGL->ReleaseSharedHandle(mShareType, mSharedHandle);
     mSharedHandle = 0;
   }
   if (mTextureHandle) {
     mGL->fDeleteTextures(1, &mTextureHandle);
     mTextureHandle = 0;
   }
@@ -703,18 +709,19 @@ SurfaceStreamHostOGL::SetCompositor(Comp
   mGL = glCompositor ? glCompositor->gl() : nullptr;
 }
 
 void
 SurfaceStreamHostOGL::DeleteTextures()
 {
   if (mUploadTexture) {
     MOZ_ASSERT(mGL);
-    mGL->MakeCurrent();
-    mGL->fDeleteTextures(1, &mUploadTexture);
+    if (mGL->MakeCurrent()) {
+      mGL->fDeleteTextures(1, &mUploadTexture);
+    }
     mUploadTexture = 0;
     mTextureHandle = 0;
   }
 }
 
 void
 SurfaceStreamHostOGL::UpdateImpl(const SurfaceDescriptor& aImage,
                                  nsIntRegion* aRegion,
@@ -741,17 +748,19 @@ SurfaceStreamHostOGL::Unlock()
 {
   // We don't know what this is unless we're locked
   mFormat = gfx::FORMAT_UNKNOWN;
 }
 
 bool
 SurfaceStreamHostOGL::Lock()
 {
-  mGL->MakeCurrent();
+  if (!mGL->MakeCurrent()) {
+    return false;
+  }
 
   SharedSurface* sharedSurf = mStream->SwapConsumer();
   if (!sharedSurf) {
     // We don't have a valid surf to show yet.
     return false;
   }
 
   mGL->MakeCurrent();
@@ -952,31 +961,43 @@ TiledDeprecatedTextureHostOGL::SetCompos
   }
   mGL = glCompositor ? glCompositor->gl() : nullptr;
 }
 
 void
 TiledDeprecatedTextureHostOGL::DeleteTextures()
 {
   if (mTextureHandle) {
-    mGL->MakeCurrent();
-    mGL->fDeleteTextures(1, &mTextureHandle);
+    if (mGL->MakeCurrent()) {
+      mGL->fDeleteTextures(1, &mTextureHandle);
 
-    gl::GfxTexturesReporter::UpdateAmount(gl::GfxTexturesReporter::MemoryFreed,
-                                          mGLFormat, GetTileType(),
-                                          TILEDLAYERBUFFER_TILE_SIZE);
+      gl::GfxTexturesReporter::UpdateAmount(gl::GfxTexturesReporter::MemoryFreed,
+                                            mGLFormat, GetTileType(),
+                                            TILEDLAYERBUFFER_TILE_SIZE);
+    } else if (mGL->IsDestroyed()) {
+      // if MakeCurrent failed because the context was already destoyed, it means
+      // the driver already freed the texture memory underneith us, so it should
+      // not count as a leak.
+      gl::GfxTexturesReporter::UpdateAmount(gl::GfxTexturesReporter::MemoryFreed,
+                                            mGLFormat, GetTileType(),
+                                            TILEDLAYERBUFFER_TILE_SIZE);
+    }
+
     mTextureHandle = 0;
   }
 }
 
 void
 TiledDeprecatedTextureHostOGL::Update(gfxReusableSurfaceWrapper* aReusableSurface, TextureFlags aFlags, const gfx::IntSize& aSize)
 {
   mSize = aSize;
-  mGL->MakeCurrent();
+  if (!mGL->MakeCurrent()) {
+    return;
+  }
+
   if (aFlags & TEXTURE_NEW_TILE) {
     SetFlags(aFlags);
     mGL->fGenTextures(1, &mTextureHandle);
     mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextureHandle);
     mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
     mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
     mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
     mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
@@ -1011,17 +1032,19 @@ TiledDeprecatedTextureHostOGL::Update(gf
 bool
 TiledDeprecatedTextureHostOGL::Lock()
 {
   if (!mTextureHandle) {
     NS_WARNING("TiledDeprecatedTextureHostOGL not ready to be composited");
     return false;
   }
 
-  mGL->MakeCurrent();
+  if (!mGL->MakeCurrent()) {
+    return false;
+  }
   mGL->fActiveTexture(LOCAL_GL_TEXTURE0);
 
   return true;
 }
 
 #ifdef MOZ_WIDGET_GONK
 static gfx::SurfaceFormat
 Deprecated_SurfaceFormatForAndroidPixelFormat(android::PixelFormat aFormat,
@@ -1119,18 +1142,19 @@ GrallocDeprecatedTextureHostOGL::GetForm
   default: return gfx::FORMAT_UNKNOWN;
   }
 }
 
 void
 GrallocDeprecatedTextureHostOGL::DeleteTextures()
 {
   if (mEGLImage) {
-    gl()->MakeCurrent();
-    gl()->DestroyEGLImage(mEGLImage);
+    if (gl()->MakeCurrent()) {
+      gl()->DestroyEGLImage(mEGLImage);
+    }
     mEGLImage = 0;
   }
 }
 
 // only used for hacky fix in gecko 23 for bug 862324
 static void
 AddDeprecatedTextureHostToGrallocBufferActor(DeprecatedTextureHost* aDeprecatedTextureHost, const SurfaceDescriptor* aSurfaceDescriptor)
 {
@@ -1169,17 +1193,19 @@ GrallocDeprecatedTextureHostOGL::SwapTex
   mFormat = Deprecated_SurfaceFormatForAndroidPixelFormat(mGraphicBuffer->getPixelFormat(),
                                                mIsRBSwapped);
 
   mTextureTarget = Deprecated_TextureTargetForAndroidPixelFormat(mGraphicBuffer->getPixelFormat());
   GLuint tex = GetGLTexture();
   // delete old EGLImage
   DeleteTextures();
 
-  gl()->MakeCurrent();
+  if (!gl()->MakeCurrent()) {
+    return;
+  }
   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
   gl()->fBindTexture(mTextureTarget, tex);
   // create new EGLImage
   // create EGLImage during buffer swap could reduce the graphic driver's task
   // during rendering.
   mEGLImage = gl()->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
   gl()->fEGLImageTargetTexture2D(mTextureTarget, mEGLImage);
 
@@ -1201,17 +1227,19 @@ void GrallocDeprecatedTextureHostOGL::Bi
    * To this effect we create an EGLImage wrapping this GraphicBuffer,
    * using CreateEGLImageForNativeBuffer, and then we tie this EGLImage to our
    * texture using fEGLImageTargetTexture2D.
    *
    * We try to avoid re-creating the EGLImage everytime, by keeping it around
    * as the mEGLImage member of this class.
    */
   MOZ_ASSERT(gl());
-  gl()->MakeCurrent();
+  if (!gl()->MakeCurrent()) {
+    return;
+  }
 
   GLuint tex = GetGLTexture();
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(mTextureTarget, tex);
   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
 }
 
@@ -1339,18 +1367,19 @@ TiledDeprecatedTextureHostOGL::GetAsSurf
     IsValid() ? ReadBackSurface(mGL, mTextureHandle, false, GetFormat())
               : nullptr;
   return surf.forget();
 }
 
 #ifdef MOZ_WIDGET_GONK
 TemporaryRef<gfx::DataSourceSurface>
 GrallocDeprecatedTextureHostOGL::GetAsSurface() {
-  gl()->MakeCurrent();
-
+  if (!gl()->MakeCurrent()) {
+    return nullptr;
+  }
   GLuint tex = GetGLTexture();
   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
   gl()->fBindTexture(mTextureTarget, tex);
   if (!mEGLImage) {
     mEGLImage = gl()->CreateEGLImageForNativeBuffer(mGraphicBuffer->getNativeBuffer());
   }
   gl()->fEGLImageTargetTexture2D(mTextureTarget, mEGLImage);