Simplify copying the front buffer to the back buffer (bug 1399692 part 5, r=bas)
☠☠ backed out by 28647c01f828 ☠ ☠
authorRyan Hunt <rhunt@eqrion.net>
Mon, 23 Oct 2017 18:27:53 -0400
changeset 443204 3d0da65640964e5a0565b5e7b7646cf719ce1449
parent 443203 926af2eca400cf8a16777813ceb586b1d3be7d68
child 443205 cb6507b560aaad188fc83a47b664aaa5692a0acd
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs1399692
milestone58.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
Simplify copying the front buffer to the back buffer (bug 1399692 part 5, r=bas) To sync the back buffer with the front buffer, we set the back buffer rect and rotation to the front buffer's, and then copy over the pixels that different. We used to do the updating of the rect and rotation before BeginPaint, but that isn't necessary and we can move it to be with the copying of pixels. MozReview-Commit-ID: HzBKvMZkn1
gfx/layers/client/ContentClient.cpp
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -158,17 +158,16 @@ ContentClient::BeginPaint(PaintedLayer* 
   bool canDrawRotated = aFlags & PAINT_CAN_DRAW_ROTATED;
   IntRect drawBounds = result.mRegionToDraw.GetBounds();
 
   if (dest.mCanReuseBuffer) {
     MOZ_ASSERT(mBuffer);
 
     if (mBuffer->Lock(lockMode)) {
       // Do not modify result.mRegionToDraw or result.mContentType after this call.
-      // Do not modify the back buffer's bufferRect, bufferRotation, or didSelfCopy.
       FinalizeFrame(result.mRegionToDraw);
 
       if (!mBuffer->AdjustTo(dest.mBufferRect,
                              drawBounds,
                              canHaveRotation,
                              canDrawRotated)) {
         dest.mBufferRect = ComputeBufferRect(dest.mNeededRegion.GetBounds());
         dest.mCanReuseBuffer = false;
@@ -829,38 +828,20 @@ ContentClientDoubleBuffered::SwapBuffers
   mFrontAndBackBufferDiffer = true;
 }
 
 ContentClient::PaintState
 ContentClientDoubleBuffered::BeginPaint(PaintedLayer* aLayer,
                                         uint32_t aFlags)
 {
   mIsNewBuffer = false;
-
   if (!mFrontBuffer || !mBuffer) {
     mFrontAndBackBufferDiffer = false;
   }
 
-  if (mFrontAndBackBufferDiffer) {
-    if (mFrontBuffer->DidSelfCopy()) {
-      // We can't easily draw our front buffer into us, since we're going to be
-      // copying stuff around anyway it's easiest if we just move our situation
-      // to non-rotated while we're at it. If this situation occurs we'll have
-      // hit a self-copy path in PaintThebes before as well anyway.
-      gfx::IntRect backBufferRect = mBuffer->BufferRect();
-      backBufferRect.MoveTo(mFrontBuffer->BufferRect().TopLeft());
-
-      mBuffer->SetBufferRect(backBufferRect);
-      mBuffer->SetBufferRotation(IntPoint(0,0));
-    } else {
-      mBuffer->SetBufferRect(mFrontBuffer->BufferRect());
-      mBuffer->SetBufferRotation(mFrontBuffer->BufferRotation());
-    }
-  }
-
   return ContentClient::BeginPaint(aLayer, aFlags);
 }
 
 RefPtr<RotatedBuffer>
 ContentClientDoubleBuffered::GetFrontBuffer() const
 {
   return mFrontBuffer;
 }
@@ -868,50 +849,60 @@ ContentClientDoubleBuffered::GetFrontBuf
 // Sync front/back buffers content
 // After executing, the new back buffer has the same (interesting) pixels as
 // the new front buffer, and mValidRegion et al. are correct wrt the new
 // back buffer (i.e. as they were for the old back buffer)
 void
 ContentClientDoubleBuffered::FinalizeFrame(const nsIntRegion& aRegionToDraw)
 {
   if (!mFrontAndBackBufferDiffer) {
-    MOZ_ASSERT(!mFrontBuffer->DidSelfCopy(), "If we have to copy the world, then our buffers are different, right?");
+    MOZ_ASSERT(!mFrontBuffer || !mFrontBuffer->DidSelfCopy(),
+               "If the front buffer did a self copy then our front and back buffer must be different.");
     return;
   }
-  MOZ_ASSERT(mFrontBuffer);
-  if (!mFrontBuffer) {
+
+  MOZ_ASSERT(mFrontBuffer && mBuffer);
+  if (!mFrontBuffer || !mBuffer) {
     return;
   }
 
   MOZ_LAYERS_LOG(("BasicShadowableThebes(%p): reading back <x=%d,y=%d,w=%d,h=%d>",
                   this,
                   mFrontUpdatedRegion.GetBounds().x,
                   mFrontUpdatedRegion.GetBounds().y,
                   mFrontUpdatedRegion.GetBounds().Width(),
                   mFrontUpdatedRegion.GetBounds().Height()));
 
   mFrontAndBackBufferDiffer = false;
 
+  // Move the back buffer rect and rotation to the front buffer rect and rotation
+  // so that we can update the pixels that changed between frames
+  gfx::IntRect backBufferRect = mBuffer->BufferRect();
+  backBufferRect.MoveTo(mFrontBuffer->BufferRect().TopLeft());
+  mBuffer->SetBufferRect(backBufferRect);
+  mBuffer->SetBufferRotation(mBuffer->BufferRotation());
+
+  // Calculate the region to update
   nsIntRegion updateRegion = mFrontUpdatedRegion;
   if (mFrontBuffer->DidSelfCopy()) {
+    // If we did an unrotate operation on the front buffer we might as well
+    // unrotate as well because we will be reading back the whole front buffer
+    mBuffer->SetBufferRotation(IntPoint(0,0));
+
     mFrontBuffer->ClearDidSelfCopy();
     updateRegion = mBuffer->BufferRect();
   }
 
   // No point in sync'ing what we are going to draw over anyway. And if there is
   // nothing to sync at all, there is nothing to do and we can go home early.
   updateRegion.Sub(updateRegion, aRegionToDraw);
   if (updateRegion.IsEmpty()) {
     return;
   }
 
-  if (!mBuffer) {
-    return;
-  }
-
   if (mFrontBuffer->Lock(OpenMode::OPEN_READ_ONLY)) {
     mBuffer->UpdateDestinationFrom(*mFrontBuffer, updateRegion.GetBounds());
     mFrontBuffer->Unlock();
   }
 }
 
 } // namespace layers
 } // namespace mozilla