Bug 1465590 - Clean up code for copying between an old tile buffer and a new one. r?nical draft
authorRyan Hunt <rhunt@eqrion.net>
Tue, 29 May 2018 16:21:32 -0500
changeset 801815 4a27ba2e93f753291712bfac8753c204a2008f9f
parent 801814 f690eb76839684e72064381801e39560ad77d895
push id111746
push userbmo:rhunt@eqrion.net
push dateWed, 30 May 2018 19:53:45 +0000
reviewersnical
bugs1465590
milestone62.0a1
Bug 1465590 - Clean up code for copying between an old tile buffer and a new one. r?nical Another cleanup patch. MozReview-Commit-ID: Ak0TTcbFePt
gfx/layers/client/SingleTiledContentClient.cpp
gfx/layers/client/TiledContentClient.cpp
gfx/layers/client/TiledContentClient.h
--- a/gfx/layers/client/SingleTiledContentClient.cpp
+++ b/gfx/layers/client/SingleTiledContentClient.cpp
@@ -192,78 +192,31 @@ ClientSingleTiledLayerBuffer::PaintThebe
 
   // If the old frontbuffer was discarded then attempt to copy what we
   // can from it to the new backbuffer.
   if (discardedFrontBuffer) {
     nsIntRegion copyableRegion;
     copyableRegion.And(aNewValidRegion, discardedValidRegion);
     copyableRegion.SubOut(aDirtyRegion);
 
-    if (!copyableRegion.IsEmpty()) {
-      OpenMode asyncFlags = asyncPaint ? OpenMode::OPEN_ASYNC
-                                       : OpenMode::OPEN_NONE;
-
-      TextureClientAutoLock frontLock(discardedFrontBuffer,
-                                      OpenMode::OPEN_READ | asyncFlags);
-      Maybe<TextureClientAutoLock> frontOnWhiteLock;
-      if (discardedFrontBufferOnWhite && backBufferOnWhite) {
-        frontOnWhiteLock.emplace(discardedFrontBufferOnWhite, OpenMode::OPEN_READ | asyncFlags);
-      }
-
-      // Copy to both backBuffer and backBufferOnWhite if required, or copy to neither.
-      if (frontLock.Succeeded() && (!frontOnWhiteLock || frontOnWhiteLock->Succeeded())) {
-        RefPtr<gfx::DrawTarget> frontBuffer = discardedFrontBuffer->BorrowDrawTarget();
-
-        if (frontBuffer) {
-          for (auto iter = copyableRegion.RectIter(); !iter.Done(); iter.Next()) {
-            const gfx::IntRect rect = iter.Get() - discardedValidRegion.GetBounds().TopLeft();
-            const gfx::IntPoint dest = iter.Get().TopLeft() - mTilingOrigin;
-
-            auto copy = CapturedTiledPaintState::Copy{
-              frontBuffer, dt, rect, dest
-            };
-            if (asyncPaint) {
-              paintCopies.push_back(copy);
-            } else {
-              copy.CopyBuffer();
-            }
-          }
+    if (!mTile.CopyFromBuffer(discardedFrontBuffer,
+                              discardedFrontBufferOnWhite,
+                              discardedValidRegion.GetBounds().TopLeft(),
+                              mTilingOrigin,
+                              copyableRegion,
+                              aFlags,
+                              &paintCopies)) {
+      gfxWarning() << "[Tiling:Client] Failed to aquire the discarded front buffer's draw target";
+    } else {
+      TILING_LOG("TILING %p: Region copied from discarded frontbuffer %s\n", &mPaintedLayer, Stringify(copyableRegion).c_str());
 
-          if (frontOnWhiteLock) {
-            RefPtr<gfx::DrawTarget> frontBufferOnWhite = discardedFrontBufferOnWhite->BorrowDrawTarget();
-
-            if (frontBufferOnWhite) {
-              for (auto iter = copyableRegion.RectIter(); !iter.Done(); iter.Next()) {
-                const gfx::IntRect rect = iter.Get() - discardedValidRegion.GetBounds().TopLeft();
-                const gfx::IntPoint dest = iter.Get().TopLeft() - mTilingOrigin;
-
-                auto copy = CapturedTiledPaintState::Copy{
-                  frontBufferOnWhite, dtOnWhite, rect, dest
-                };
-                if (asyncPaint) {
-                  paintCopies.push_back(copy);
-                } else {
-                  copy.CopyBuffer();
-                }
-              }
-            } else {
-              gfxWarning() << "[Tiling:Client] Failed to aquire the discarded front buffer's draw target";
-            }
-          }
-        } else {
-          gfxWarning() << "[Tiling:Client] Failed to aquire the discarded front buffer's draw target";
-        }
-
-        TILING_LOG("TILING %p: Region copied from discarded frontbuffer %s\n", &mPaintedLayer, Stringify(copyableRegion).c_str());
-
-        // We don't need to repaint valid content that was just copied.
-        paintRegion.SubOut(copyableRegion);
-        copyableRegion.MoveBy(-mTilingOrigin);
-        tileDirtyRegion.SubOut(copyableRegion);
-      }
+      // We don't need to repaint valid content that was just copied.
+      paintRegion.SubOut(copyableRegion);
+      copyableRegion.MoveBy(-mTilingOrigin);
+      tileDirtyRegion.SubOut(copyableRegion);
     }
   }
 
   if (mode != SurfaceMode::SURFACE_OPAQUE) {
     auto clear = CapturedTiledPaintState::Clear{
       dt,
       dtOnWhite,
       tileDirtyRegion,
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -579,16 +579,69 @@ TileClient::DiscardBackBuffer()
   if (mBackBuffer) {
     DiscardTexture(mBackBuffer, mAllocator);
     mBackBuffer.Set(this, nullptr);
     DiscardTexture(mBackBufferOnWhite, mAllocator);
     mBackBufferOnWhite = nullptr;
   }
 }
 
+bool
+TileClient::CopyFromBuffer(RefPtr<TextureClient> aBuffer,
+                           RefPtr<TextureClient> aBufferOnWhite,
+                           nsIntPoint aBufferOrigin,
+                           nsIntPoint aTileOrigin,
+                           const nsIntRegion& aRegion,
+                           TilePaintFlags aFlags,
+                           std::vector<CapturedTiledPaintState::Copy>* aCopies)
+{
+  if (aRegion.IsEmpty()) {
+    return true;
+  }
+
+  bool asyncPaint = !!(aFlags & TilePaintFlags::Async);
+  auto CopyBuffer = [&aRegion, asyncPaint, &aCopies] (auto aSrc, auto aSrcOrigin, auto aDest, auto aDestOrigin) {
+    MOZ_ASSERT(aDest->IsLocked());
+
+    OpenMode asyncFlags = asyncPaint ? OpenMode::OPEN_ASYNC
+                                     : OpenMode::OPEN_NONE;
+    TextureClientAutoLock lock(aSrc, OpenMode::OPEN_READ | asyncFlags);
+    if (!lock.Succeeded()) {
+      return false;
+    }
+
+    RefPtr<gfx::DrawTarget> srcTarget = aSrc->BorrowDrawTarget();
+    RefPtr<gfx::DrawTarget> destTarget = aDest->BorrowDrawTarget();
+    if (!srcTarget || !destTarget) {
+      return false;
+    }
+
+    for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
+      const gfx::IntRect src = iter.Get() - aSrcOrigin;
+      const gfx::IntPoint dest = iter.Get().TopLeft() - aDestOrigin;
+
+      auto copy = CapturedTiledPaintState::Copy{
+        srcTarget, destTarget, src, dest
+      };
+
+      if (asyncPaint) {
+        aCopies->push_back(copy);
+      } else {
+        copy.CopyBuffer();
+      }
+    }
+    return true;
+  };
+
+  return CopyBuffer(aBuffer, aBufferOrigin, mBackBuffer, aTileOrigin) &&
+    (!aBufferOnWhite ||
+     !mBackBufferOnWhite ||
+     CopyBuffer(aBufferOnWhite, aBufferOrigin, mBackBufferOnWhite, aTileOrigin));
+}
+
 static already_AddRefed<TextureClient>
 CreateBackBufferTexture(TextureClient* aCurrentTexture,
                         CompositableClient& aCompositable,
                         TextureClientAllocator* aAllocator)
 {
   if (aCurrentTexture) {
     // 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
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -135,16 +135,28 @@ struct TileClient
                                RefPtr<TextureClient>* aTextureClientOnWhite,
                                std::vector<CapturedTiledPaintState::Copy>* aCopies,
                                std::vector<RefPtr<TextureClient>>* aClients);
 
   void DiscardFrontBuffer();
 
   void DiscardBackBuffer();
 
+  /*
+   * Copy aRegion from aBuffer and aBufferOnWhite positioned at aBufferOrigin
+   * into ourselves assuming we are positioned at aTileOrigin.
+   */
+  bool CopyFromBuffer(RefPtr<TextureClient> aBuffer,
+                      RefPtr<TextureClient> aBufferOnWhite,
+                      nsIntPoint aBufferOrigin,
+                      nsIntPoint aTileOrigin,
+                      const nsIntRegion& aRegion,
+                      TilePaintFlags aFlags,
+                      std::vector<CapturedTiledPaintState::Copy>* aCopies);
+
   /* We wrap the back buffer in a class that disallows assignment
    * so that we can track when ever it changes so that we can update
    * the expiry tracker for expiring the back buffers */
   class PrivateProtector {
     public:
       void Set(TileClient * container, RefPtr<TextureClient>);
       void Set(TileClient * container, TextureClient*);
       // Implicitly convert to TextureClient* because we can't chain
@@ -163,18 +175,20 @@ struct TileClient
   bool mWasPlaceholder;
 #ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
   TimeStamp        mLastUpdate;
 #endif
   nsIntRegion mInvalidFront;
   nsIntRegion mInvalidBack;
   nsExpirationState mExpirationState;
 private:
-  // Copies dirty pixels from the front buffer into the back buffer,
-  // and records the copied region in aAddPaintedRegion.
+  /*
+   * Copies dirty pixels from the front buffer into the back buffer,
+   * and records the copied region in aAddPaintedRegion.
+   */
   void ValidateBackBufferFromFront(const nsIntRegion &aDirtyRegion,
                                    const nsIntRegion& aVisibleRegion,
                                    nsIntRegion& aAddPaintedRegion,
                                    TilePaintFlags aFlags,
                                    std::vector<CapturedTiledPaintState::Copy>* aCopies,
                                    std::vector<RefPtr<TextureClient>>* aClients);
 };