SurfaceFlinger: Fix duplicate callbacks
Transaction callbacks are emitted early, for empty transactions,
after latch for on commit callbacks and on post composition for
transaction complete callbacks. Pending callbacks are stored
together. If a transaction contains a layer that is presented
and a layer that is not presented, the transaction callback will
get added to the pending list after the transaction is committed
and it will get emitted after buffers are latched and then again
at the end of composition. To fix this we make sure to only emit
on commit callbacks after a buffer is latched.
Test: atest SurfaceFlinger_test
Bug: 202394221
Change-Id: I356fbf221812060c17765c53cc3df24cb3cd139a
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index 8fbf0b4..f3d46ea 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -121,7 +121,7 @@
return addCallbackHandle(handle, std::vector<JankData>());
}
-status_t TransactionCallbackInvoker::findTransactionStats(
+status_t TransactionCallbackInvoker::findOrCreateTransactionStats(
const sp<IBinder>& listener, const std::vector<CallbackId>& callbackIds,
TransactionStats** outTransactionStats) {
auto& transactionStatsDeque = mCompletedTransactions[listener];
@@ -143,7 +143,8 @@
// If we can't find the transaction stats something has gone wrong. The client should call
// startRegistration before trying to add a callback handle.
TransactionStats* transactionStats;
- status_t err = findTransactionStats(handle->listener, handle->callbackIds, &transactionStats);
+ status_t err =
+ findOrCreateTransactionStats(handle->listener, handle->callbackIds, &transactionStats);
if (err != NO_ERROR) {
return err;
}
@@ -204,7 +205,7 @@
mPresentFence = presentFence;
}
-void TransactionCallbackInvoker::sendCallbacks() {
+void TransactionCallbackInvoker::sendCallbacks(bool onCommitOnly) {
// For each listener
auto completedTransactionsItr = mCompletedTransactions.begin();
while (completedTransactionsItr != mCompletedTransactions.end()) {
@@ -216,6 +217,10 @@
auto transactionStatsItr = transactionStatsDeque.begin();
while (transactionStatsItr != transactionStatsDeque.end()) {
auto& transactionStats = *transactionStatsItr;
+ if (onCommitOnly && !containsOnCommitCallbacks(transactionStats.callbackIds)) {
+ transactionStatsItr++;
+ continue;
+ }
// If the transaction has been latched
if (transactionStats.latchTime >= 0 &&