diff options
author | Jamie Gennis <jgennis@google.com> | 2012-10-15 18:24:43 -0700 |
---|---|---|
committer | The Android Automerger <android-build@android.com> | 2012-10-16 11:25:47 -0700 |
commit | 529efdf60f2015e591dd9cd62e8802c583a8917a (patch) | |
tree | b8017bb03c4eb1907757de6352059ff84e33646f | |
parent | eec9e6456d98aa7a6657fc69ad8da0f58b1241ea (diff) | |
download | frameworks_native-529efdf60f2015e591dd9cd62e8802c583a8917a.zip frameworks_native-529efdf60f2015e591dd9cd62e8802c583a8917a.tar.gz frameworks_native-529efdf60f2015e591dd9cd62e8802c583a8917a.tar.bz2 |
SurfaceFlinger: add animation transactions
This change adds a transaction flag for WindowManager to indicate that a
transaction is being used to animate windows around the screen. SurfaceFlinger
will not allow more than one of these transactions to be outstanding at a time
to prevent the animation "frames" from being dropped.
Bug: 7353840
Change-Id: I6488a6e0e1ed13d27356d2203c9dc766dc6b1759
-rw-r--r-- | include/gui/ISurfaceComposer.h | 1 | ||||
-rw-r--r-- | include/gui/SurfaceComposerClient.h | 5 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 23 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 32 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 3 |
5 files changed, 55 insertions, 9 deletions
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index 5d2d8d7..002aafc 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -46,6 +46,7 @@ public: // flags for setTransactionState() enum { eSynchronous = 0x01, + eAnimation = 0x02, }; enum { diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index 581ec8d..21d16a9 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -101,10 +101,13 @@ public: //! Open a composer transaction on all active SurfaceComposerClients. static void openGlobalTransaction(); - + //! Close a composer transaction on all active SurfaceComposerClients. static void closeGlobalTransaction(bool synchronous = false); + //! Flag the currently open transaction as an animation transaction. + static void setAnimationTransaction(); + status_t hide(SurfaceID id); status_t show(SurfaceID id); status_t setFlags(SurfaceID id, uint32_t flags, uint32_t mask); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 3efd086..8586ed2 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -115,12 +115,15 @@ class Composer : public Singleton<Composer> SortedVector<ComposerState> mComposerStates; SortedVector<DisplayState > mDisplayStates; uint32_t mForceSynchronous; + bool mAnimation; Composer() : Singleton<Composer>(), - mForceSynchronous(0) + mForceSynchronous(0), + mAnimation(false) { } void closeGlobalTransactionImpl(bool synchronous); + void setAnimationTransactionImpl(); layer_state_t* getLayerStateLocked( const sp<SurfaceComposerClient>& client, SurfaceID id); @@ -159,6 +162,10 @@ public: const Rect& layerStackRect, const Rect& displayRect); + static void setAnimationTransaction() { + Composer::getInstance().setAnimationTransactionImpl(); + } + static void closeGlobalTransaction(bool synchronous) { Composer::getInstance().closeGlobalTransactionImpl(synchronous); } @@ -194,12 +201,22 @@ void Composer::closeGlobalTransactionImpl(bool synchronous) { if (synchronous || mForceSynchronous) { flags |= ISurfaceComposer::eSynchronous; } + if (mAnimation) { + flags |= ISurfaceComposer::eAnimation; + } + mForceSynchronous = false; + mAnimation = false; } sm->setTransactionState(transaction, displayTransaction, flags); } +void Composer::setAnimationTransactionImpl() { + Mutex::Autolock _l(mLock); + mAnimation = true; +} + layer_state_t* Composer::getLayerStateLocked( const sp<SurfaceComposerClient>& client, SurfaceID id) { @@ -471,6 +488,10 @@ void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { Composer::closeGlobalTransaction(synchronous); } +void SurfaceComposerClient::setAnimationTransaction() { + Composer::setAnimationTransaction(); +} + // ---------------------------------------------------------------------------- status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 492d1cf..e21e2bf 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -86,7 +86,8 @@ const String16 sDump("android.permission.DUMP"); SurfaceFlinger::SurfaceFlinger() : BnSurfaceComposer(), Thread(false), mTransactionFlags(0), - mTransationPending(false), + mTransactionPending(false), + mAnimTransactionPending(false), mLayersRemoved(false), mRepaintEverything(0), mBootTime(systemTime()), @@ -1264,7 +1265,8 @@ void SurfaceFlinger::commitTransaction() } mDrawingState = mCurrentState; - mTransationPending = false; + mTransactionPending = false; + mAnimTransactionPending = false; mTransactionCV.broadcast(); } @@ -1665,6 +1667,21 @@ void SurfaceFlinger::setTransactionState( Mutex::Autolock _l(mStateLock); uint32_t transactionFlags = 0; + if (flags & eAnimation) { + // For window updates that are part of an animation we must wait for + // previous animation "frames" to be handled. + while (mAnimTransactionPending) { + status_t err = mTransactionCV.waitRelative(mStateLock, 500 * 1000); + if (CC_UNLIKELY(err != NO_ERROR)) { + // just in case something goes wrong in SF, return to the + // caller after a few hundred microseconds. + ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); + mAnimTransactionPending = false; + break; + } + } + } + size_t count = displays.size(); for (size_t i=0 ; i<count ; i++) { const DisplayState& s(displays[i]); @@ -1685,15 +1702,18 @@ void SurfaceFlinger::setTransactionState( // if this is a synchronous transaction, wait for it to take effect // before returning. if (flags & eSynchronous) { - mTransationPending = true; + mTransactionPending = true; + } + if (flags & eAnimation) { + mAnimTransactionPending = true; } - while (mTransationPending) { + while (mTransactionPending) { 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. - ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); - mTransationPending = false; + ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!"); + mTransactionPending = false; break; } } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 6d36719..efe34af 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -398,7 +398,8 @@ private: volatile int32_t mTransactionFlags; Condition mTransactionCV; SortedVector<sp<LayerBase> > mLayerPurgatory; - bool mTransationPending; + bool mTransactionPending; + bool mAnimTransactionPending; Vector<sp<LayerBase> > mLayersPendingRemoval; // protected by mStateLock (but we could use another lock) |