blast: send TransactionStats with callback

Add TransactionStats to callback so the client knows when the
buffers were released and acquired. Also when transaction was
presented and latched.

Test: Transaction_test
Bug: 80477568

Change-Id: I578a7000193a4401783cb2538172167a552b043f
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index adc91a7..2ada701 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -41,9 +41,11 @@
 // -----------------------------------------------------------------------
 // Interface implementation for Layer
 // -----------------------------------------------------------------------
-void BufferStateLayer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {
-    // TODO(marissaw): send the release fence back to buffer owner
-    return;
+void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
+    // The transaction completed callback can only be sent if the release fence from the PREVIOUS
+    // frame has fired. In practice, we should never actually wait on the previous release fence
+    // but we should store it just in case.
+    mPreviousReleaseFence = releaseFence;
 }
 
 void BufferStateLayer::setTransformHint(uint32_t /*orientation*/) const {
@@ -52,7 +54,6 @@
 }
 
 void BufferStateLayer::releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) {
-    // TODO(marissaw): use this to signal the buffer owner
     return;
 }
 
@@ -125,7 +126,11 @@
     return true;
 }
 
-bool BufferStateLayer::setBuffer(sp<GraphicBuffer> buffer) {
+bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer) {
+    if (mCurrentState.buffer) {
+        mReleasePreviousBuffer = true;
+    }
+
     mCurrentState.sequence++;
     mCurrentState.buffer = buffer;
     mCurrentState.modified = true;
@@ -134,6 +139,9 @@
 }
 
 bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
+    // The acquire fences of BufferStateLayers have already signaled before they are set
+    mCallbackHandleAcquireTime = fence->getSignalTime();
+
     mCurrentState.acquireFence = fence;
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
@@ -191,16 +199,23 @@
 
 bool BufferStateLayer::setTransactionCompletedListeners(
         const std::vector<sp<CallbackHandle>>& handles) {
-    // If there is no handle, we will not send a callback
+    // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
     if (handles.empty()) {
+        mReleasePreviousBuffer = false;
         return false;
     }
 
     const bool willPresent = willPresentCurrentTransaction();
 
     for (const auto& handle : handles) {
+        // If this transaction set a buffer on this layer, release its previous buffer
+        handle->releasePreviousBuffer = mReleasePreviousBuffer;
+
         // If this layer will be presented in this frame
         if (willPresent) {
+            // If this transaction set an acquire fence on this layer, set its acquire time
+            handle->acquireTime = mCallbackHandleAcquireTime;
+
             // Notify the transaction completed thread that there is a pending latched callback
             // handle
             mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle);
@@ -214,6 +229,9 @@
         }
     }
 
+    mReleasePreviousBuffer = false;
+    mCallbackHandleAcquireTime = -1;
+
     return willPresent;
 }
 
@@ -438,8 +456,9 @@
         return BAD_VALUE;
     }
 
-    mFlinger->getTransactionCompletedThread().addLatchedCallbackHandles(
-            getDrawingState().callbackHandles);
+    mFlinger->getTransactionCompletedThread()
+            .addLatchedCallbackHandles(getDrawingState().callbackHandles, latchTime,
+                                       mPreviousReleaseFence);
 
     // Handle sync fences
     if (SyncFeatures::getInstance().useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {