Release buffers early after GL comp

When client comped a layers buffers are never really
acquired/released by HWC, since they are already composited
by the time they are sent there. This means we don't
need to wait on the release fence from the next
frame in order to release the buffer. As soon as
we receive a new buffer we can directly release with the previous
GL comp fence. We accomplish this by plumbing the GL comp fence
down to BufferStateLayer, and using it for early release
from setBuffer when applicable.

Bug: 200284594
Test: Existing tests pass
Change-Id: Ib76a8a02efd85ef2925d4fb32c3f096c55d383e1
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index ed45cab..4eeaba1 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -132,6 +132,20 @@
 // Interface implementation for Layer
 // -----------------------------------------------------------------------
 void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
+
+    // If a layer has been displayed again we may need to clear
+    // the mLastClientComposition fence that we use for early release in setBuffer
+    // (as we now have a new fence which won't pass through the client composition path in some cases
+    //  e.g. screenshot). We expect one call to onLayerDisplayed after receiving the GL comp fence
+    // from a single composition cycle, and want to clear on the second call
+    // (which we track with mLastClientCompositionDisplayed)
+   if (mLastClientCompositionDisplayed) {
+        mLastClientCompositionFence = nullptr;
+        mLastClientCompositionDisplayed = false;
+    } else if (mLastClientCompositionFence) {
+        mLastClientCompositionDisplayed = true;
+    }
+
     if (!releaseFence->isValid()) {
         return;
     }
@@ -474,6 +488,13 @@
               addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX);
               mDrawingState.bufferSurfaceFrameTX.reset();
             }
+        } else if (mLastClientCompositionFence != nullptr) {
+            callReleaseBufferCallback(mDrawingState.releaseBufferListener,
+                                      mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
+                                      mLastClientCompositionFence, mTransformHint,
+                                      mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
+                                          mOwnerUid));
+            mLastClientCompositionFence = nullptr;
         }
     }