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) {