Bug 1180326 - Part 3: Move repeated code into GetBackBuffer. r=jrmuizel
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 29 Jul 2015 12:02:27 -0400
changeset 281572 6b9ace2a57ab841885530d884cb27d8b333ddffe
parent 281571 e1bfa923a761d62b92657ccbbfbc5774fac4b7f3
child 281573 9bd5b37c01684687e820921c7bb15a0ec5d56404
push id3894
push usermconley@mozilla.com
push dateThu, 30 Jul 2015 00:27:47 +0000
reviewersjrmuizel
bugs1180326
milestone42.0a1
Bug 1180326 - Part 3: Move repeated code into GetBackBuffer. r=jrmuizel
gfx/layers/client/TiledContentClient.cpp
gfx/layers/client/TiledContentClient.h
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -730,81 +730,114 @@ TileClient::DiscardBackBuffer()
     mBackLock = nullptr;
   }
 }
 
 TextureClient*
 TileClient::GetBackBuffer(const nsIntRegion& aDirtyRegion,
                           gfxContentType aContent,
                           SurfaceMode aMode,
-                          bool *aCreatedTextureClient,
                           nsIntRegion& aAddPaintedRegion,
                           RefPtr<TextureClient>* aBackBufferOnWhite)
 {
   // Try to re-use the front-buffer if possible
+  bool createdTextureClient = false;
   if (mFrontBuffer &&
       mFrontBuffer->HasInternalBuffer() &&
       mFrontLock->GetReadCount() == 1 &&
       !(aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA && !mFrontBufferOnWhite)) {
     // If we had a backbuffer we no longer care about it since we'll
     // re-use the front buffer.
     DiscardBackBuffer();
     Flip();
-    *aBackBufferOnWhite = mBackBufferOnWhite;
-    return mBackBuffer;
-  }
+  } else {
+    if (!mBackBuffer ||
+        mBackLock->GetReadCount() > 1) {
+
+      if (mBackLock) {
+        // Before we Replacing the lock by another one we need to unlock it!
+        mBackLock->ReadUnlock();
+      }
 
-  if (!mBackBuffer ||
-      mBackLock->GetReadCount() > 1) {
+      if (mBackBuffer) {
+        // Our current back-buffer is still locked by the compositor. This can occur
+        // when the client is producing faster than the compositor can consume. In
+        // this case we just want to drop it and not return it to the pool.
+        mAllocator->ReportClientLost();
+      }
+      if (mBackBufferOnWhite) {
+        mAllocator->ReportClientLost();
+        mBackBufferOnWhite = nullptr;
+      }
 
-    if (mBackLock) {
-      // Before we Replacing the lock by another one we need to unlock it!
-      mBackLock->ReadUnlock();
-    }
+      mBackBuffer.Set(this, mAllocator->GetTextureClient());
+      if (!mBackBuffer) {
+        gfxCriticalError() << "[Tiling:Client] Failed to allocate a TextureClient";
+        return nullptr;
+      }
 
-    if (mBackBuffer) {
-      // Our current back-buffer is still locked by the compositor. This can occur
-      // when the client is producing faster than the compositor can consume. In
-      // this case we just want to drop it and not return it to the pool.
-      mAllocator->ReportClientLost();
-    }
-    if (mBackBufferOnWhite) {
-      mAllocator->ReportClientLost();
-      mBackBufferOnWhite = nullptr;
+      if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
+        mBackBufferOnWhite = mAllocator->GetTextureClient();
+        if (!mBackBufferOnWhite) {
+          mBackBuffer.Set(this, nullptr);
+          gfxCriticalError() << "[Tiling:Client] Failed to allocate a TextureClient";
+          return nullptr;
+        }
+      }
+
+      // Create a lock for our newly created back-buffer.
+      if (mManager->AsShadowForwarder()->IsSameProcess()) {
+        // If our compositor is in the same process, we can save some cycles by not
+        // using shared memory.
+        mBackLock = new gfxMemorySharedReadLock();
+      } else {
+        mBackLock = new gfxShmSharedReadLock(mManager->AsShadowForwarder());
+      }
+
+      MOZ_ASSERT(mBackLock->IsValid());
+
+      createdTextureClient = true;
+      mInvalidBack = IntRect(0, 0, mBackBuffer->GetSize().width, mBackBuffer->GetSize().height);
     }
 
-    mBackBuffer.Set(this, mAllocator->GetTextureClient());
-    if (!mBackBuffer) {
+    ValidateBackBufferFromFront(aDirtyRegion, aAddPaintedRegion);
+  }
+
+  if (!mBackBuffer->IsLocked()) {
+    if (!mBackBuffer->Lock(OpenMode::OPEN_READ_WRITE)) {
+      gfxCriticalError() << "[Tiling:Client] Failed to lock a tile";
+      DiscardBackBuffer();
+      DiscardFrontBuffer();
       return nullptr;
     }
-
-    if (aMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
-      mBackBufferOnWhite = mAllocator->GetTextureClient();
-      if (!mBackBufferOnWhite) {
-        mBackBuffer.Set(this, nullptr);
-        return nullptr;
-      }
-    }
+  }
 
-    // Create a lock for our newly created back-buffer.
-    if (mManager->AsShadowForwarder()->IsSameProcess()) {
-      // If our compositor is in the same process, we can save some cycles by not
-      // using shared memory.
-      mBackLock = new gfxMemorySharedReadLock();
-    } else {
-      mBackLock = new gfxShmSharedReadLock(mManager->AsShadowForwarder());
+  if (mBackBufferOnWhite && !mBackBufferOnWhite->IsLocked()) {
+    if (!mBackBufferOnWhite->Lock(OpenMode::OPEN_READ_WRITE)) {
+      gfxCriticalError() << "[Tiling:Client] Failed to lock a tile";
+      DiscardBackBuffer();
+      DiscardFrontBuffer();
+      return nullptr;
     }
-
-    MOZ_ASSERT(mBackLock->IsValid());
-
-    *aCreatedTextureClient = true;
-    mInvalidBack = IntRect(0, 0, mBackBuffer->GetSize().width, mBackBuffer->GetSize().height);
   }
 
-  ValidateBackBufferFromFront(aDirtyRegion, aAddPaintedRegion);
+  if (createdTextureClient) {
+    if (!mCompositableClient->AddTextureClient(mBackBuffer)) {
+      gfxCriticalError() << "[Tiling:Client] Failed to connect a TextureClient (a)";
+      DiscardFrontBuffer();
+      DiscardBackBuffer();
+      return nullptr;
+    }
+    if (mBackBufferOnWhite && !mCompositableClient->AddTextureClient(mBackBufferOnWhite)) {
+      gfxCriticalError() << "[Tiling:Client] Failed to connect a TextureClient (b)";
+      DiscardFrontBuffer();
+      DiscardBackBuffer();
+      return nullptr;
+    }
+  }
 
   *aBackBufferOnWhite = mBackBufferOnWhite;
   return mBackBuffer;
 }
 
 TileDescriptor
 TileClient::GetTileDescriptor()
 {
@@ -1206,74 +1239,41 @@ ClientMultiTiledLayerBuffer::ValidateTil
 
   if (aTile.IsPlaceholderTile()) {
     aTile.SetLayerManager(mManager);
     aTile.SetTextureAllocator(mManager->GetTexturePool(
       gfxPlatform::GetPlatform()->Optimal2DFormatForContent(content)));
   }
   aTile.SetCompositableClient(mCompositableClient);
 
-  bool createdTextureClient = false;
   nsIntRegion offsetScaledDirtyRegion = aDirtyRegion.MovedBy(-aTileOrigin);
   offsetScaledDirtyRegion.ScaleRoundOut(mResolution, mResolution);
 
   bool usingTiledDrawTarget = gfxPrefs::TiledDrawTargetEnabled();
   MOZ_ASSERT(usingTiledDrawTarget || !!mSinglePaintDrawTarget);
 
   nsIntRegion extraPainted;
   RefPtr<TextureClient> backBufferOnWhite;
   RefPtr<TextureClient> backBuffer =
     aTile.GetBackBuffer(offsetScaledDirtyRegion,
                         content, mode,
-                        &createdTextureClient, extraPainted,
+                        extraPainted,
                         &backBufferOnWhite);
 
   aTile.mUpdateRect = offsetScaledDirtyRegion.GetBounds().Union(extraPainted.GetBounds());
 
   extraPainted.MoveBy(aTileOrigin);
   extraPainted.And(extraPainted, mNewValidRegion);
   mPaintedRegion.Or(mPaintedRegion, extraPainted);
 
   if (!backBuffer) {
-    gfxCriticalError() << "[Tiling:Client] Failed to allocate a TextureClient";
-    aTile.DiscardBuffers();
     return false;
   }
 
-  // the back buffer may have been already locked in ValidateBackBufferFromFront
-  if (!backBuffer->IsLocked()) {
-    if (!backBuffer->Lock(OpenMode::OPEN_READ_WRITE)) {
-      gfxCriticalError() << "[Tiling:Client] Failed to lock a tile";
-      aTile.DiscardBuffers();
-      return false;
-    }
-  }
-
-  if (backBufferOnWhite && !backBufferOnWhite->IsLocked()) {
-    if (!backBufferOnWhite->Lock(OpenMode::OPEN_READ_WRITE)) {
-      gfxCriticalError() << "[Tiling:Client] Failed to lock a tile";
-      aTile.DiscardBuffers();
-      return false;
-    }
-  }
-
   if (usingTiledDrawTarget) {
-    if (createdTextureClient) {
-      if (!mCompositableClient->AddTextureClient(backBuffer)) {
-        gfxCriticalError() << "[Tiling:Client] Failed to connect a TextureClient (a)";
-        aTile.DiscardBuffers();
-        return false;
-      }
-      if (backBufferOnWhite && !mCompositableClient->AddTextureClient(backBufferOnWhite)) {
-        gfxCriticalError() << "[Tiling:Client] Failed to connect a TextureClient (b)";
-        aTile.DiscardBuffers();
-        return false;
-      }
-    }
-
     gfx::Tile moz2DTile;
     RefPtr<DrawTarget> dt = backBuffer->BorrowDrawTarget();
     RefPtr<DrawTarget> dtOnWhite;
     if (backBufferOnWhite) {
       dtOnWhite = backBufferOnWhite->BorrowDrawTarget();
       moz2DTile.mDrawTarget = Factory::CreateDualDrawTarget(dt, dtOnWhite);
     } else {
       moz2DTile.mDrawTarget = dt;
@@ -1369,24 +1369,16 @@ ClientMultiTiledLayerBuffer::ValidateTil
     IntRect(aTileOrigin.x, aTileOrigin.y,
               GetScaledTileSize().width, GetScaledTileSize().height);
   // Intersect this area with the portion that's invalid.
   tileRegion.SubOut(GetValidRegion());
   tileRegion.SubOut(aDirtyRegion); // Has now been validated
 
   backBuffer->SetWaste(tileRegion.Area() * mResolution * mResolution);
 
-  if (createdTextureClient) {
-    if (!mCompositableClient->AddTextureClient(backBuffer)) {
-      gfxCriticalError() << "[Tiling:Client] Failed to connect a TextureClient (c)";
-      aTile.DiscardBuffers();
-      return false;
-    }
-  }
-
   aTile.Flip();
 
   // Note, we don't call UpdatedTexture. The Updated function is called manually
   // by the TiledContentHost before composition.
 
   if (backBuffer->HasInternalBuffer()) {
     // If our new buffer has an internal buffer, we don't want to keep another
     // TextureClient around unnecessarily, so discard the back-buffer.
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -239,17 +239,16 @@ struct TileClient
   * If getting the back buffer required copying pixels from the front buffer
   * then the copied region is stored in aAddPaintedRegion so the host side
   * knows to upload it.
   *
   * If nullptr is returned, aTextureClientOnWhite is undefined.
   */
   TextureClient* GetBackBuffer(const nsIntRegion& aDirtyRegion,
                                gfxContentType aContent, SurfaceMode aMode,
-                               bool *aCreatedTextureClient,
                                nsIntRegion& aAddPaintedRegion,
                                RefPtr<TextureClient>* aTextureClientOnWhite);
 
   void DiscardFrontBuffer();
 
   void DiscardBackBuffer();
 
   /* We wrap the back buffer in a class that disallows assignment