blast: Send transaction callback
Send transaction callback to client via the
TransactionCompletedListener.
Test: Transaction_test
Bug: 80477568
Change-Id: Iac98780b1357b9cc54b93cc3c848013b28fab441
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 0e14d8c..adc91a7 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -64,6 +64,12 @@
return hasFrameUpdate();
}
+bool BufferStateLayer::willPresentCurrentTransaction() const {
+ // Returns true if the most recent Transaction applied to CurrentState will be presented.
+ return getSidebandStreamChanged() || getAutoRefresh() ||
+ (mCurrentState.modified && mCurrentState.buffer != nullptr);
+}
+
bool BufferStateLayer::getTransformToDisplayInverse() const {
return mCurrentState.transformToDisplayInverse;
}
@@ -183,6 +189,34 @@
return true;
}
+bool BufferStateLayer::setTransactionCompletedListeners(
+ const std::vector<sp<CallbackHandle>>& handles) {
+ // If there is no handle, we will not send a callback
+ if (handles.empty()) {
+ return false;
+ }
+
+ const bool willPresent = willPresentCurrentTransaction();
+
+ for (const auto& handle : handles) {
+ // If this layer will be presented in this frame
+ if (willPresent) {
+ // Notify the transaction completed thread that there is a pending latched callback
+ // handle
+ mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle);
+
+ // Store so latched time and release fence can be set
+ mCurrentState.callbackHandles.push_back(handle);
+
+ } else { // If this layer will NOT need to be relatched and presented this frame
+ // Notify the transaction completed thread this handle is done
+ mFlinger->getTransactionCompletedThread().addUnlatchedCallbackHandle(handle);
+ }
+ }
+
+ return willPresent;
+}
+
bool BufferStateLayer::setSize(uint32_t w, uint32_t h) {
if (mCurrentState.active.w == w && mCurrentState.active.h == h) return false;
mCurrentState.active.w = w;
@@ -404,6 +438,9 @@
return BAD_VALUE;
}
+ mFlinger->getTransactionCompletedThread().addLatchedCallbackHandles(
+ getDrawingState().callbackHandles);
+
// Handle sync fences
if (SyncFeatures::getInstance().useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {
// TODO(alecmouri): Fail somewhere upstream if the fence is invalid.