From 28378392fd5aa3e0a392c9eb64634055678c3987 Mon Sep 17 00:00:00 2001 From: Jamie Gennis Date: Wed, 12 Oct 2011 17:39:00 -0700 Subject: [PATCH] SurfaceFlinger: make sync transactions explicit This change enables a layer or orientation update transaction sent to SurfaceFlinger to explicitly request a synchronous transaction. Change-Id: I97cbba610c13679849f66114b216fa6dbf12f2a9 --- include/surfaceflinger/ISurfaceComposer.h | 8 +++-- .../surfaceflinger/SurfaceComposerClient.h | 2 +- libs/gui/ISurfaceComposer.cpp | 6 ++-- libs/gui/SurfaceComposerClient.cpp | 33 ++++++++++++++----- services/surfaceflinger/SurfaceFlinger.cpp | 31 +++++++++-------- services/surfaceflinger/SurfaceFlinger.h | 4 +-- 6 files changed, 53 insertions(+), 31 deletions(-) diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h index ea022a67b..26cf094a6 100644 --- a/include/surfaceflinger/ISurfaceComposer.h +++ b/include/surfaceflinger/ISurfaceComposer.h @@ -83,7 +83,11 @@ public: eOrientationUnchanged = 4, eOrientationSwapMask = 0x01 }; - + + enum { + eSynchronous = 0x01, + }; + enum { eElectronBeamAnimationOn = 0x01, eElectronBeamAnimationOff = 0x10 @@ -103,7 +107,7 @@ public: /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ virtual void setTransactionState(const Vector& state, - int orientation) = 0; + int orientation, uint32_t flags) = 0; /* signal that we're done booting. * Requires ACCESS_SURFACE_FLINGER permission diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h index 14e5b23a7..8226abec1 100644 --- a/include/surfaceflinger/SurfaceComposerClient.h +++ b/include/surfaceflinger/SurfaceComposerClient.h @@ -112,7 +112,7 @@ public: static void openGlobalTransaction(); //! Close a composer transaction on all active SurfaceComposerClients. - static void closeGlobalTransaction(); + static void closeGlobalTransaction(bool synchronous = false); //! Freeze the specified display but not transactions. static status_t freezeDisplay(DisplayID dpy, uint32_t flags = 0); diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index eb90147ac..86bc62aa2 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -79,7 +79,7 @@ public: } virtual void setTransactionState(const Vector& state, - int orientation) + int orientation, uint32_t flags) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); @@ -90,6 +90,7 @@ public: b->write(data); } data.writeInt32(orientation); + data.writeInt32(flags); remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); } @@ -204,7 +205,8 @@ status_t BnSurfaceComposer::onTransact( state.add(s); } int orientation = data.readInt32(); - setTransactionState(state, orientation); + uint32_t flags = data.readInt32(); + setTransactionState(state, orientation, flags); } break; case BOOT_FINISHED: { CHECK_INTERFACE(ISurfaceComposer, data, reply); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 5f3d608a5..4ad6c22c0 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -92,11 +92,14 @@ class Composer : public Singleton mutable Mutex mLock; SortedVector mStates; int mOrientation; + uint32_t mForceSynchronous; Composer() : Singleton(), - mOrientation(ISurfaceComposer::eOrientationUnchanged) { } + mOrientation(ISurfaceComposer::eOrientationUnchanged), + mForceSynchronous(0) + { } - void closeGlobalTransactionImpl(); + void closeGlobalTransactionImpl(bool synchronous); layer_state_t* getLayerStateLocked( const sp& client, SurfaceID id); @@ -123,8 +126,8 @@ public: uint32_t tint); status_t setOrientation(int orientation); - static void closeGlobalTransaction() { - Composer::getInstance().closeGlobalTransactionImpl(); + static void closeGlobalTransaction(bool synchronous) { + Composer::getInstance().closeGlobalTransactionImpl(synchronous); } }; @@ -132,11 +135,12 @@ ANDROID_SINGLETON_STATIC_INSTANCE(Composer); // --------------------------------------------------------------------------- -void Composer::closeGlobalTransactionImpl() { +void Composer::closeGlobalTransactionImpl(bool synchronous) { sp sm(getComposerService()); Vector transaction; int orientation; + uint32_t flags = 0; { // scope for the lock Mutex::Autolock _l(mLock); @@ -145,9 +149,14 @@ void Composer::closeGlobalTransactionImpl() { orientation = mOrientation; mOrientation = ISurfaceComposer::eOrientationUnchanged; + + if (synchronous || mForceSynchronous) { + flags |= ISurfaceComposer::eSynchronous; + } + mForceSynchronous = false; } - sm->setTransactionState(transaction, orientation); + sm->setTransactionState(transaction, orientation, flags); } layer_state_t* Composer::getLayerStateLocked( @@ -188,6 +197,10 @@ status_t Composer::setSize(const sp& client, s->what |= ISurfaceComposer::eSizeChanged; s->w = w; s->h = h; + + // Resizing a surface makes the transaction synchronous. + mForceSynchronous = true; + return NO_ERROR; } @@ -270,6 +283,10 @@ status_t Composer::setFreezeTint(const sp& client, status_t Composer::setOrientation(int orientation) { Mutex::Autolock _l(mLock); mOrientation = orientation; + + // Changing the orientation makes the transaction synchronous. + mForceSynchronous = true; + return NO_ERROR; } @@ -375,8 +392,8 @@ void SurfaceComposerClient::openGlobalTransaction() { // Currently a no-op } -void SurfaceComposerClient::closeGlobalTransaction() { - Composer::closeGlobalTransaction(); +void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { + Composer::closeGlobalTransaction(synchronous); } // ---------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1441a5406..bfb5cf4a9 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -79,7 +79,7 @@ const String16 sDump("android.permission.DUMP"); SurfaceFlinger::SurfaceFlinger() : BnSurfaceComposer(), Thread(false), mTransactionFlags(0), - mResizeTransationPending(false), + mTransationPending(false), mLayersRemoved(false), mBootTime(systemTime()), mVisibleRegionsDirty(false), @@ -748,7 +748,7 @@ void SurfaceFlinger::computeVisibleRegions( void SurfaceFlinger::commitTransaction() { mDrawingState = mCurrentState; - mResizeTransationPending = false; + mTransationPending = false; mTransactionCV.broadcast(); } @@ -1235,15 +1235,14 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) void SurfaceFlinger::setTransactionState(const Vector& state, - int orientation) { + int orientation, uint32_t flags) { Mutex::Autolock _l(mStateLock); - uint32_t flags = 0; + uint32_t transactionFlags = 0; if (mCurrentState.orientation != orientation) { if (uint32_t(orientation)<=eOrientation270 || orientation==42) { mCurrentState.orientation = orientation; - flags |= eTransactionNeeded; - mResizeTransationPending = true; + transactionFlags |= eTransactionNeeded; } else if (orientation != eOrientationUnchanged) { LOGW("setTransactionState: ignoring unrecognized orientation: %d", orientation); @@ -1254,23 +1253,24 @@ void SurfaceFlinger::setTransactionState(const Vector& state, for (size_t i=0 ; i client( static_cast(s.client.get()) ); - flags |= setClientStateLocked(client, s.state); + transactionFlags |= setClientStateLocked(client, s.state); } - if (flags) { - setTransactionFlags(flags); + if (transactionFlags) { + setTransactionFlags(transactionFlags); } - signalEvent(); - - // if there is a transaction with a resize, wait for it to - // take effect before returning. - while (mResizeTransationPending) { + // if this is a synchronous transaction, wait for it to take effect before + // returning. + if (flags & eSynchronous) { + mTransationPending = true; + } + while (mTransationPending) { status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); if (CC_UNLIKELY(err != NO_ERROR)) { // just in case something goes wrong in SF, return to the // called after a few seconds. LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); - mResizeTransationPending = false; + mTransationPending = false; break; } } @@ -1489,7 +1489,6 @@ uint32_t SurfaceFlinger::setClientStateLocked( if (what & eSizeChanged) { if (layer->setSize(s.w, s.h)) { flags |= eTraversalNeeded; - mResizeTransationPending = true; } } if (what & eAlphaChanged) { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 0e642c100..9ff080fda 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -168,7 +168,7 @@ public: virtual sp getCblk() const; virtual void bootFinished(); virtual void setTransactionState(const Vector& state, - int orientation); + int orientation, uint32_t flags); virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags); virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags); virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags); @@ -341,7 +341,7 @@ private: volatile int32_t mTransactionFlags; Condition mTransactionCV; SortedVector< sp > mLayerPurgatory; - bool mResizeTransationPending; + bool mTransationPending; // protected by mStateLock (but we could use another lock) GraphicPlane mGraphicPlanes[1];