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
This commit is contained in:
Jamie Gennis 2011-10-12 17:39:00 -07:00
parent 5dff2beb5d
commit 28378392fd
6 changed files with 53 additions and 31 deletions

View File

@ -83,7 +83,11 @@ public:
eOrientationUnchanged = 4, eOrientationUnchanged = 4,
eOrientationSwapMask = 0x01 eOrientationSwapMask = 0x01
}; };
enum {
eSynchronous = 0x01,
};
enum { enum {
eElectronBeamAnimationOn = 0x01, eElectronBeamAnimationOn = 0x01,
eElectronBeamAnimationOff = 0x10 eElectronBeamAnimationOff = 0x10
@ -103,7 +107,7 @@ public:
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
virtual void setTransactionState(const Vector<ComposerState>& state, virtual void setTransactionState(const Vector<ComposerState>& state,
int orientation) = 0; int orientation, uint32_t flags) = 0;
/* signal that we're done booting. /* signal that we're done booting.
* Requires ACCESS_SURFACE_FLINGER permission * Requires ACCESS_SURFACE_FLINGER permission

View File

@ -112,7 +112,7 @@ public:
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(); static void closeGlobalTransaction(bool synchronous = false);
//! Freeze the specified display but not transactions. //! Freeze the specified display but not transactions.
static status_t freezeDisplay(DisplayID dpy, uint32_t flags = 0); static status_t freezeDisplay(DisplayID dpy, uint32_t flags = 0);

View File

@ -79,7 +79,7 @@ public:
} }
virtual void setTransactionState(const Vector<ComposerState>& state, virtual void setTransactionState(const Vector<ComposerState>& state,
int orientation) int orientation, uint32_t flags)
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@ -90,6 +90,7 @@ public:
b->write(data); b->write(data);
} }
data.writeInt32(orientation); data.writeInt32(orientation);
data.writeInt32(flags);
remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply); remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
} }
@ -204,7 +205,8 @@ status_t BnSurfaceComposer::onTransact(
state.add(s); state.add(s);
} }
int orientation = data.readInt32(); int orientation = data.readInt32();
setTransactionState(state, orientation); uint32_t flags = data.readInt32();
setTransactionState(state, orientation, flags);
} break; } break;
case BOOT_FINISHED: { case BOOT_FINISHED: {
CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply);

View File

@ -92,11 +92,14 @@ class Composer : public Singleton<Composer>
mutable Mutex mLock; mutable Mutex mLock;
SortedVector<ComposerState> mStates; SortedVector<ComposerState> mStates;
int mOrientation; int mOrientation;
uint32_t mForceSynchronous;
Composer() : Singleton<Composer>(), Composer() : Singleton<Composer>(),
mOrientation(ISurfaceComposer::eOrientationUnchanged) { } mOrientation(ISurfaceComposer::eOrientationUnchanged),
mForceSynchronous(0)
{ }
void closeGlobalTransactionImpl(); void closeGlobalTransactionImpl(bool synchronous);
layer_state_t* getLayerStateLocked( layer_state_t* getLayerStateLocked(
const sp<SurfaceComposerClient>& client, SurfaceID id); const sp<SurfaceComposerClient>& client, SurfaceID id);
@ -123,8 +126,8 @@ public:
uint32_t tint); uint32_t tint);
status_t setOrientation(int orientation); status_t setOrientation(int orientation);
static void closeGlobalTransaction() { static void closeGlobalTransaction(bool synchronous) {
Composer::getInstance().closeGlobalTransactionImpl(); Composer::getInstance().closeGlobalTransactionImpl(synchronous);
} }
}; };
@ -132,11 +135,12 @@ ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
void Composer::closeGlobalTransactionImpl() { void Composer::closeGlobalTransactionImpl(bool synchronous) {
sp<ISurfaceComposer> sm(getComposerService()); sp<ISurfaceComposer> sm(getComposerService());
Vector<ComposerState> transaction; Vector<ComposerState> transaction;
int orientation; int orientation;
uint32_t flags = 0;
{ // scope for the lock { // scope for the lock
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
@ -145,9 +149,14 @@ void Composer::closeGlobalTransactionImpl() {
orientation = mOrientation; orientation = mOrientation;
mOrientation = ISurfaceComposer::eOrientationUnchanged; 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( layer_state_t* Composer::getLayerStateLocked(
@ -188,6 +197,10 @@ status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
s->what |= ISurfaceComposer::eSizeChanged; s->what |= ISurfaceComposer::eSizeChanged;
s->w = w; s->w = w;
s->h = h; s->h = h;
// Resizing a surface makes the transaction synchronous.
mForceSynchronous = true;
return NO_ERROR; return NO_ERROR;
} }
@ -270,6 +283,10 @@ status_t Composer::setFreezeTint(const sp<SurfaceComposerClient>& client,
status_t Composer::setOrientation(int orientation) { status_t Composer::setOrientation(int orientation) {
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
mOrientation = orientation; mOrientation = orientation;
// Changing the orientation makes the transaction synchronous.
mForceSynchronous = true;
return NO_ERROR; return NO_ERROR;
} }
@ -375,8 +392,8 @@ void SurfaceComposerClient::openGlobalTransaction() {
// Currently a no-op // Currently a no-op
} }
void SurfaceComposerClient::closeGlobalTransaction() { void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
Composer::closeGlobalTransaction(); Composer::closeGlobalTransaction(synchronous);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -79,7 +79,7 @@ const String16 sDump("android.permission.DUMP");
SurfaceFlinger::SurfaceFlinger() SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(), Thread(false), : BnSurfaceComposer(), Thread(false),
mTransactionFlags(0), mTransactionFlags(0),
mResizeTransationPending(false), mTransationPending(false),
mLayersRemoved(false), mLayersRemoved(false),
mBootTime(systemTime()), mBootTime(systemTime()),
mVisibleRegionsDirty(false), mVisibleRegionsDirty(false),
@ -748,7 +748,7 @@ void SurfaceFlinger::computeVisibleRegions(
void SurfaceFlinger::commitTransaction() void SurfaceFlinger::commitTransaction()
{ {
mDrawingState = mCurrentState; mDrawingState = mCurrentState;
mResizeTransationPending = false; mTransationPending = false;
mTransactionCV.broadcast(); mTransactionCV.broadcast();
} }
@ -1235,15 +1235,14 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
int orientation) { int orientation, uint32_t flags) {
Mutex::Autolock _l(mStateLock); Mutex::Autolock _l(mStateLock);
uint32_t flags = 0; uint32_t transactionFlags = 0;
if (mCurrentState.orientation != orientation) { if (mCurrentState.orientation != orientation) {
if (uint32_t(orientation)<=eOrientation270 || orientation==42) { if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
mCurrentState.orientation = orientation; mCurrentState.orientation = orientation;
flags |= eTransactionNeeded; transactionFlags |= eTransactionNeeded;
mResizeTransationPending = true;
} else if (orientation != eOrientationUnchanged) { } else if (orientation != eOrientationUnchanged) {
LOGW("setTransactionState: ignoring unrecognized orientation: %d", LOGW("setTransactionState: ignoring unrecognized orientation: %d",
orientation); orientation);
@ -1254,23 +1253,24 @@ void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,
for (size_t i=0 ; i<count ; i++) { for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]); const ComposerState& s(state[i]);
sp<Client> client( static_cast<Client *>(s.client.get()) ); sp<Client> client( static_cast<Client *>(s.client.get()) );
flags |= setClientStateLocked(client, s.state); transactionFlags |= setClientStateLocked(client, s.state);
} }
if (flags) { if (transactionFlags) {
setTransactionFlags(flags); setTransactionFlags(transactionFlags);
} }
signalEvent(); // if this is a synchronous transaction, wait for it to take effect before
// returning.
// if there is a transaction with a resize, wait for it to if (flags & eSynchronous) {
// take effect before returning. mTransationPending = true;
while (mResizeTransationPending) { }
while (mTransationPending) {
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.
LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
mResizeTransationPending = false; mTransationPending = false;
break; break;
} }
} }
@ -1489,7 +1489,6 @@ uint32_t SurfaceFlinger::setClientStateLocked(
if (what & eSizeChanged) { if (what & eSizeChanged) {
if (layer->setSize(s.w, s.h)) { if (layer->setSize(s.w, s.h)) {
flags |= eTraversalNeeded; flags |= eTraversalNeeded;
mResizeTransationPending = true;
} }
} }
if (what & eAlphaChanged) { if (what & eAlphaChanged) {

View File

@ -168,7 +168,7 @@ public:
virtual sp<IMemoryHeap> getCblk() const; virtual sp<IMemoryHeap> getCblk() const;
virtual void bootFinished(); virtual void bootFinished();
virtual void setTransactionState(const Vector<ComposerState>& state, virtual void setTransactionState(const Vector<ComposerState>& state,
int orientation); int orientation, uint32_t flags);
virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags); virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags);
virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags); virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags);
virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags); virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
@ -341,7 +341,7 @@ private:
volatile int32_t mTransactionFlags; volatile int32_t mTransactionFlags;
Condition mTransactionCV; Condition mTransactionCV;
SortedVector< sp<LayerBase> > mLayerPurgatory; SortedVector< sp<LayerBase> > mLayerPurgatory;
bool mResizeTransationPending; bool mTransationPending;
// protected by mStateLock (but we could use another lock) // protected by mStateLock (but we could use another lock)
GraphicPlane mGraphicPlanes[1]; GraphicPlane mGraphicPlanes[1];