summaryrefslogtreecommitdiff
path: root/libs/gui/SurfaceComposerClient.cpp
diff options
context:
space:
mode:
author Jeff Brown <jeffbrown@google.com> 2012-08-31 02:18:38 -0700
committer Jeff Brown <jeffbrown@google.com> 2012-11-02 14:02:52 -0700
commitf3f7db6346323ca3ec4ec449a2622adddc6306b4 (patch)
treec223b3a3c179d238bfca5efef876e5d137c8b646 /libs/gui/SurfaceComposerClient.cpp
parent7e251273880c4108bc56b4cdc52f6193876ef59a (diff)
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
Diffstat (limited to 'libs/gui/SurfaceComposerClient.cpp')
-rw-r--r--libs/gui/SurfaceComposerClient.cpp27
1 files changed, 24 insertions, 3 deletions
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<Composer>
SortedVector<ComposerState> mComposerStates;
SortedVector<DisplayState > mDisplayStates;
uint32_t mForceSynchronous;
+ uint32_t mTransactionNestCount;
bool mAnimation;
Composer() : Singleton<Composer>(),
- 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<IBinder> 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<ISurfaceComposer> 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) {