Blocking client thread during animation frames
Since the main UI thread will never block on prior animation
frames if applying a transaction, we need the client thread to be
blocked when it is trying to apply another animation frame.
Bug: 129130064
Test: build, boot, manual, SurfaceFlinger_test
Change-Id: I20c7351d5b6aa13810990099f71d4e1771a2ef7b
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3744f8b..2d53609 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3486,7 +3486,12 @@
flushedATransaction = true;
}
- it = (transactionQueue.empty()) ? mTransactionQueues.erase(it) : std::next(it, 1);
+ if (transactionQueue.empty()) {
+ it = mTransactionQueues.erase(it);
+ mTransactionCV.broadcast();
+ } else {
+ std::next(it, 1);
+ }
}
return flushedATransaction;
}
@@ -3559,7 +3564,22 @@
}
// If its TransactionQueue already has a pending TransactionState or if it is pending
- if (mTransactionQueues.find(applyToken) != mTransactionQueues.end() ||
+ auto itr = mTransactionQueues.find(applyToken);
+ // if this is an animation frame, wait until prior animation frame has
+ // been applied by SF
+ if (flags & eAnimation) {
+ while (itr != mTransactionQueues.end()) {
+ status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
+ if (CC_UNLIKELY(err != NO_ERROR)) {
+ ALOGW_IF(err == TIMED_OUT,
+ "setTransactionState timed out "
+ "waiting for animation frame to apply");
+ break;
+ }
+ itr = mTransactionQueues.find(applyToken);
+ }
+ }
+ if (itr != mTransactionQueues.end() ||
!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
uncacheBuffer, listenerCallbacks, postTime,