Merge "SurfaceFlinger: add animation transactions" into jb-mr1-dev

This commit is contained in:
Jamie Gennis 2012-10-15 19:36:11 -07:00 committed by Android (Google) Code Review
commit 3365c56716
5 changed files with 55 additions and 9 deletions

View File

@ -46,6 +46,7 @@ public:
// flags for setTransactionState() // flags for setTransactionState()
enum { enum {
eSynchronous = 0x01, eSynchronous = 0x01,
eAnimation = 0x02,
}; };
enum { enum {

View File

@ -101,10 +101,13 @@ public:
//! Open a composer transaction on all active SurfaceComposerClients. //! Open a composer transaction on all active SurfaceComposerClients.
static void openGlobalTransaction(); static void openGlobalTransaction();
//! Close a composer transaction on all active SurfaceComposerClients. //! Close a composer transaction on all active SurfaceComposerClients.
static void closeGlobalTransaction(bool synchronous = false); 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 hide(SurfaceID id);
status_t show(SurfaceID id); status_t show(SurfaceID id);
status_t setFlags(SurfaceID id, uint32_t flags, uint32_t mask); status_t setFlags(SurfaceID id, uint32_t flags, uint32_t mask);

View File

@ -115,12 +115,15 @@ class Composer : public Singleton<Composer>
SortedVector<ComposerState> mComposerStates; SortedVector<ComposerState> mComposerStates;
SortedVector<DisplayState > mDisplayStates; SortedVector<DisplayState > mDisplayStates;
uint32_t mForceSynchronous; uint32_t mForceSynchronous;
bool mAnimation;
Composer() : Singleton<Composer>(), Composer() : Singleton<Composer>(),
mForceSynchronous(0) mForceSynchronous(0),
mAnimation(false)
{ } { }
void closeGlobalTransactionImpl(bool synchronous); void closeGlobalTransactionImpl(bool synchronous);
void setAnimationTransactionImpl();
layer_state_t* getLayerStateLocked( layer_state_t* getLayerStateLocked(
const sp<SurfaceComposerClient>& client, SurfaceID id); const sp<SurfaceComposerClient>& client, SurfaceID id);
@ -159,6 +162,10 @@ public:
const Rect& layerStackRect, const Rect& layerStackRect,
const Rect& displayRect); const Rect& displayRect);
static void setAnimationTransaction() {
Composer::getInstance().setAnimationTransactionImpl();
}
static void closeGlobalTransaction(bool synchronous) { static void closeGlobalTransaction(bool synchronous) {
Composer::getInstance().closeGlobalTransactionImpl(synchronous); Composer::getInstance().closeGlobalTransactionImpl(synchronous);
} }
@ -194,12 +201,22 @@ void Composer::closeGlobalTransactionImpl(bool synchronous) {
if (synchronous || mForceSynchronous) { if (synchronous || mForceSynchronous) {
flags |= ISurfaceComposer::eSynchronous; flags |= ISurfaceComposer::eSynchronous;
} }
if (mAnimation) {
flags |= ISurfaceComposer::eAnimation;
}
mForceSynchronous = false; mForceSynchronous = false;
mAnimation = false;
} }
sm->setTransactionState(transaction, displayTransaction, flags); sm->setTransactionState(transaction, displayTransaction, flags);
} }
void Composer::setAnimationTransactionImpl() {
Mutex::Autolock _l(mLock);
mAnimation = true;
}
layer_state_t* Composer::getLayerStateLocked( layer_state_t* Composer::getLayerStateLocked(
const sp<SurfaceComposerClient>& client, SurfaceID id) { const sp<SurfaceComposerClient>& client, SurfaceID id) {
@ -471,6 +488,10 @@ void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
Composer::closeGlobalTransaction(synchronous); Composer::closeGlobalTransaction(synchronous);
} }
void SurfaceComposerClient::setAnimationTransaction() {
Composer::setAnimationTransaction();
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) { status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) {

View File

@ -86,7 +86,8 @@ const String16 sDump("android.permission.DUMP");
SurfaceFlinger::SurfaceFlinger() SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(), Thread(false), : BnSurfaceComposer(), Thread(false),
mTransactionFlags(0), mTransactionFlags(0),
mTransationPending(false), mTransactionPending(false),
mAnimTransactionPending(false),
mLayersRemoved(false), mLayersRemoved(false),
mRepaintEverything(0), mRepaintEverything(0),
mBootTime(systemTime()), mBootTime(systemTime()),
@ -1264,7 +1265,8 @@ void SurfaceFlinger::commitTransaction()
} }
mDrawingState = mCurrentState; mDrawingState = mCurrentState;
mTransationPending = false; mTransactionPending = false;
mAnimTransactionPending = false;
mTransactionCV.broadcast(); mTransactionCV.broadcast();
} }
@ -1665,6 +1667,21 @@ void SurfaceFlinger::setTransactionState(
Mutex::Autolock _l(mStateLock); Mutex::Autolock _l(mStateLock);
uint32_t transactionFlags = 0; 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(); size_t count = displays.size();
for (size_t i=0 ; i<count ; i++) { for (size_t i=0 ; i<count ; i++) {
const DisplayState& s(displays[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 // if this is a synchronous transaction, wait for it to take effect
// before returning. // before returning.
if (flags & eSynchronous) { if (flags & eSynchronous) {
mTransationPending = true; mTransactionPending = true;
} }
while (mTransationPending) { if (flags & eAnimation) {
mAnimTransactionPending = true;
}
while (mTransactionPending) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) { if (CC_UNLIKELY(err != NO_ERROR)) {
// just in case something goes wrong in SF, return to the // just in case something goes wrong in SF, return to the
// called after a few seconds. // called after a few seconds.
ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
mTransationPending = false; mTransactionPending = false;
break; break;
} }
} }

View File

@ -398,7 +398,8 @@ private:
volatile int32_t mTransactionFlags; volatile int32_t mTransactionFlags;
Condition mTransactionCV; Condition mTransactionCV;
SortedVector<sp<LayerBase> > mLayerPurgatory; SortedVector<sp<LayerBase> > mLayerPurgatory;
bool mTransationPending; bool mTransactionPending;
bool mAnimTransactionPending;
Vector<sp<LayerBase> > mLayersPendingRemoval; Vector<sp<LayerBase> > mLayersPendingRemoval;
// protected by mStateLock (but we could use another lock) // protected by mStateLock (but we could use another lock)