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

@ -84,6 +84,10 @@ public:
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<ComposerState>& state,
int orientation) = 0;
int orientation, uint32_t flags) = 0;
/* signal that we're done booting.
* Requires ACCESS_SURFACE_FLINGER permission

View File

@ -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);

View File

@ -79,7 +79,7 @@ public:
}
virtual void setTransactionState(const Vector<ComposerState>& 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);

View File

@ -92,11 +92,14 @@ class Composer : public Singleton<Composer>
mutable Mutex mLock;
SortedVector<ComposerState> mStates;
int mOrientation;
uint32_t mForceSynchronous;
Composer() : Singleton<Composer>(),
mOrientation(ISurfaceComposer::eOrientationUnchanged) { }
mOrientation(ISurfaceComposer::eOrientationUnchanged),
mForceSynchronous(0)
{ }
void closeGlobalTransactionImpl();
void closeGlobalTransactionImpl(bool synchronous);
layer_state_t* getLayerStateLocked(
const sp<SurfaceComposerClient>& 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<ISurfaceComposer> sm(getComposerService());
Vector<ComposerState> 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<SurfaceComposerClient>& 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<SurfaceComposerClient>& 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);
}
// ----------------------------------------------------------------------------

View File

@ -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<ComposerState>& 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<ComposerState>& state,
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
sp<Client> client( static_cast<Client *>(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) {

View File

@ -168,7 +168,7 @@ public:
virtual sp<IMemoryHeap> getCblk() const;
virtual void bootFinished();
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 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<LayerBase> > mLayerPurgatory;
bool mResizeTransationPending;
bool mTransationPending;
// protected by mStateLock (but we could use another lock)
GraphicPlane mGraphicPlanes[1];