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 286897 6b9ace2a57ab841885530d884cb27d8b333ddffe
parent 286896 e1bfa923a761d62b92657ccbbfbc5774fac4b7f3
child 286898 9bd5b37c01684687e820921c7bb15a0ec5d56404
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1180326
milestone42.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 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