blast: flush transaction wake ups
When SurfaceFlinger's main thread wakes up just to flush
transactions and no transactions are ready to be flushed, go back
to sleep.
Bug: 128520233
Test: Play a 30hz video that has desiredPresentTimes. Check that
SurfaceFlinger is only doing a full present cycle 30 times
a second.
Change-Id: Iae11f9a604a3ea5b0d553947f47133871e608fca
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fae4b81..7061ad6 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1709,22 +1709,22 @@
ATRACE_CALL();
uint32_t transactionFlags = peekTransactionFlags();
- // Apply any ready transactions in the queues if there are still transactions that have not been
- // applied, wake up during the next vsync period and check again
- bool transactionNeeded = false;
- if (!flushTransactionQueues()) {
- transactionNeeded = true;
+ bool flushedATransaction = flushTransactionQueues();
+
+ bool runHandleTransaction = transactionFlags &&
+ ((transactionFlags != eTransactionFlushNeeded) || flushedATransaction);
+
+ if (runHandleTransaction) {
+ handleTransaction(eTransactionMask);
+ } else {
+ getTransactionFlags(eTransactionFlushNeeded);
}
- if (transactionFlags) {
- handleTransaction(transactionFlags);
+ if (transactionFlushNeeded()) {
+ setTransactionFlags(eTransactionFlushNeeded);
}
- if (transactionNeeded) {
- setTransactionFlags(eTransactionNeeded);
- }
-
- return transactionFlags;
+ return runHandleTransaction;
}
void SurfaceFlinger::handleMessageRefresh() {
@@ -3522,6 +3522,8 @@
bool SurfaceFlinger::flushTransactionQueues() {
Mutex::Autolock _l(mStateLock);
+ bool flushedATransaction = false;
+
auto it = mTransactionQueues.begin();
while (it != mTransactionQueues.end()) {
auto& [applyToken, transactionQueue] = *it;
@@ -3531,17 +3533,23 @@
[states, displays, flags, desiredPresentTime, uncacheBuffer, listenerCallbacks,
postTime, privileged] = transactionQueue.front();
if (!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
+ setTransactionFlags(eTransactionFlushNeeded);
break;
}
applyTransactionState(states, displays, flags, mPendingInputWindowCommands,
desiredPresentTime, uncacheBuffer, listenerCallbacks, postTime,
privileged, /*isMainThread*/ true);
transactionQueue.pop();
+ flushedATransaction = true;
}
it = (transactionQueue.empty()) ? mTransactionQueues.erase(it) : std::next(it, 1);
}
- return mTransactionQueues.empty();
+ return flushedATransaction;
+}
+
+bool SurfaceFlinger::transactionFlushNeeded() {
+ return !mTransactionQueues.empty();
}
bool SurfaceFlinger::containsAnyInvalidClientState(const Vector<ComposerState>& states) {
@@ -3613,7 +3621,7 @@
mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
uncacheBuffer, listenerCallbacks, postTime,
privileged);
- setTransactionFlags(eTransactionNeeded);
+ setTransactionFlags(eTransactionFlushNeeded);
return;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3d8b6b7..f176e06 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -135,11 +135,12 @@
// ---------------------------------------------------------------------------
enum {
- eTransactionNeeded = 0x01,
- eTraversalNeeded = 0x02,
+ eTransactionNeeded = 0x01,
+ eTraversalNeeded = 0x02,
eDisplayTransactionNeeded = 0x04,
eDisplayLayerStackChanged = 0x08,
- eTransactionMask = 0x0f,
+ eTransactionFlushNeeded = 0x10,
+ eTransactionMask = 0x1f,
};
enum class DisplayColorSetting : int32_t {
@@ -606,7 +607,10 @@
const std::vector<ListenerCallbacks>& listenerCallbacks,
const int64_t postTime, bool privileged, bool isMainThread = false)
REQUIRES(mStateLock);
+ // Returns true if at least one transaction was flushed
bool flushTransactionQueues();
+ // Returns true if there is at least one transaction that needs to be flushed
+ bool transactionFlushNeeded();
uint32_t getTransactionFlags(uint32_t flags);
uint32_t peekTransactionFlags();
// Can only be called from the main thread or with mStateLock held