summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2024-03-29 17:19:21 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-03-29 17:19:21 +0000
commit06bf5557c902dd6a1bb88acbd3b5fd8ec48e1278 (patch)
tree3a0b11e76111b61c010d66b4321af077be787c4a
parent025022b09a621c297a23adefd7ba6f6e48235b7e (diff)
parent878911f7df21c700ddbe9e9c9d28cd0a1776946f (diff)
Merge "Fix sync issue with handling display state changes" into main
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp31
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h7
2 files changed, 29 insertions, 9 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5f36e38941..447435549b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2245,7 +2245,7 @@ bool SurfaceFlinger::updateLayerSnapshotsLegacy(VsyncId vsyncId, nsecs_t frameTi
outTransactionsAreEmpty = !needsTraversal;
const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
if (shouldCommit) {
- commitTransactions();
+ commitTransactionsLegacy();
}
bool mustComposite = latchBuffers() || shouldCommit;
@@ -2369,8 +2369,14 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs,
mLayerHierarchyBuilder.update(mLayerLifecycleManager);
}
+ // Keep a copy of the drawing state (that is going to be overwritten
+ // by commitTransactionsLocked) outside of mStateLock so that the side
+ // effects of the State assignment don't happen with mStateLock held,
+ // which can cause deadlocks.
+ State drawingState(mDrawingState);
+ Mutex::Autolock lock(mStateLock);
bool mustComposite = false;
- mustComposite |= applyAndCommitDisplayTransactionStates(update.transactions);
+ mustComposite |= applyAndCommitDisplayTransactionStatesLocked(update.transactions);
{
ATRACE_NAME("LayerSnapshotBuilder:update");
@@ -2409,7 +2415,7 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs,
bool newDataLatched = false;
if (!mLegacyFrontEndEnabled) {
ATRACE_NAME("DisplayCallbackAndStatsUpdates");
- mustComposite |= applyTransactions(update.transactions, vsyncId);
+ mustComposite |= applyTransactionsLocked(update.transactions, vsyncId);
traverseLegacyLayers([&](Layer* layer) { layer->commitTransaction(); });
const nsecs_t latchTime = systemTime();
bool unused = false;
@@ -3284,6 +3290,19 @@ void SurfaceFlinger::computeLayerBounds() {
void SurfaceFlinger::commitTransactions() {
ATRACE_CALL();
+ mDebugInTransaction = systemTime();
+
+ // Here we're guaranteed that some transaction flags are set
+ // so we can call commitTransactionsLocked unconditionally.
+ // We clear the flags with mStateLock held to guarantee that
+ // mCurrentState won't change until the transaction is committed.
+ mScheduler->modulateVsync({}, &VsyncModulator::onTransactionCommit);
+ commitTransactionsLocked(clearTransactionFlags(eTransactionMask));
+ mDebugInTransaction = 0;
+}
+
+void SurfaceFlinger::commitTransactionsLegacy() {
+ ATRACE_CALL();
// Keep a copy of the drawing state (that is going to be overwritten
// by commitTransactionsLocked) outside of mStateLock so that the side
@@ -5253,9 +5272,8 @@ bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin
return needsTraversal;
}
-bool SurfaceFlinger::applyAndCommitDisplayTransactionStates(
+bool SurfaceFlinger::applyAndCommitDisplayTransactionStatesLocked(
std::vector<TransactionState>& transactions) {
- Mutex::Autolock lock(mStateLock);
bool needsTraversal = false;
uint32_t transactionFlags = 0;
for (auto& transaction : transactions) {
@@ -6038,7 +6056,8 @@ void SurfaceFlinger::initializeDisplays() {
if (mLegacyFrontEndEnabled) {
applyTransactions(transactions, VsyncId{0});
} else {
- applyAndCommitDisplayTransactionStates(transactions);
+ Mutex::Autolock lock(mStateLock);
+ applyAndCommitDisplayTransactionStatesLocked(transactions);
}
{
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 704fcef263..4a44be632e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -758,7 +758,8 @@ private:
bool force = false)
REQUIRES(mStateLock, kMainThreadContext);
- void commitTransactions() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
+ void commitTransactionsLegacy() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
+ void commitTransactions() REQUIRES(kMainThreadContext, mStateLock);
void commitTransactionsLocked(uint32_t transactionFlags)
REQUIRES(mStateLock, kMainThreadContext);
void doCommitTransactions() REQUIRES(mStateLock);
@@ -808,8 +809,8 @@ private:
bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext);
bool applyTransactions(std::vector<TransactionState>&, VsyncId) REQUIRES(kMainThreadContext);
- bool applyAndCommitDisplayTransactionStates(std::vector<TransactionState>& transactions)
- REQUIRES(kMainThreadContext);
+ bool applyAndCommitDisplayTransactionStatesLocked(std::vector<TransactionState>& transactions)
+ REQUIRES(kMainThreadContext, mStateLock);
// Returns true if there is at least one transaction that needs to be flushed
bool transactionFlushNeeded();