summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamie Gennis <jgennis@google.com>2012-10-15 18:24:43 -0700
committerThe Android Automerger <android-build@android.com>2012-10-16 11:25:47 -0700
commit529efdf60f2015e591dd9cd62e8802c583a8917a (patch)
treeb8017bb03c4eb1907757de6352059ff84e33646f
parenteec9e6456d98aa7a6657fc69ad8da0f58b1241ea (diff)
downloadframeworks_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.h1
-rw-r--r--include/gui/SurfaceComposerClient.h5
-rw-r--r--libs/gui/SurfaceComposerClient.cpp23
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp32
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h3
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)