From f3f7db6346323ca3ec4ec449a2622adddc6306b4 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Fri, 31 Aug 2012 02:18:38 -0700 Subject: Allow global transactions to nest. This change fixes a number of small glitches that can occur when multiple components in the same process are updating surfaces. One would expect that updates to disjoint sets of surfaces would not collide but this is not the case. The first component to close the global transaction causes all pending updates to be applied, including those that another component might not have finished setting up if it also had an open transaction at the same time. Change-Id: I99345958581abbe0e1e325a5bcba37e8941a313a --- libs/gui/SurfaceComposerClient.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'libs/gui/SurfaceComposerClient.cpp') diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 80dd6ee96a..746057b429 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -115,13 +115,15 @@ class Composer : public Singleton SortedVector mComposerStates; SortedVector mDisplayStates; uint32_t mForceSynchronous; + uint32_t mTransactionNestCount; bool mAnimation; Composer() : Singleton(), - mForceSynchronous(0), + mForceSynchronous(0), mTransactionNestCount(0), mAnimation(false) { } + void openGlobalTransactionImpl(); void closeGlobalTransactionImpl(bool synchronous); void setAnimationTransactionImpl(); @@ -166,6 +168,10 @@ public: Composer::getInstance().setAnimationTransactionImpl(); } + static void openGlobalTransaction() { + Composer::getInstance().openGlobalTransactionImpl(); + } + static void closeGlobalTransaction(bool synchronous) { Composer::getInstance().closeGlobalTransactionImpl(synchronous); } @@ -184,6 +190,13 @@ sp Composer::getBuiltInDisplay(int32_t id) { return ComposerService::getComposerService()->getBuiltInDisplay(id); } +void Composer::openGlobalTransactionImpl() { + { // scope for the lock + Mutex::Autolock _l(mLock); + mTransactionNestCount += 1; + } +} + void Composer::closeGlobalTransactionImpl(bool synchronous) { sp sm(ComposerService::getComposerService()); @@ -193,13 +206,21 @@ void Composer::closeGlobalTransactionImpl(bool synchronous) { { // scope for the lock Mutex::Autolock _l(mLock); + mForceSynchronous |= synchronous; + if (!mTransactionNestCount) { + ALOGW("At least one call to closeGlobalTransaction() was not matched by a prior " + "call to openGlobalTransaction()."); + } else if (--mTransactionNestCount) { + return; + } + transaction = mComposerStates; mComposerStates.clear(); displayTransaction = mDisplayStates; mDisplayStates.clear(); - if (synchronous || mForceSynchronous) { + if (mForceSynchronous) { flags |= ISurfaceComposer::eSynchronous; } if (mAnimation) { @@ -483,7 +504,7 @@ inline Composer& SurfaceComposerClient::getComposer() { // ---------------------------------------------------------------------------- void SurfaceComposerClient::openGlobalTransaction() { - // Currently a no-op + Composer::openGlobalTransaction(); } void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { -- cgit v1.2.3-59-g8ed1b