SF transactions are now O(1) wrt IPC instead of O(N).

Change-Id: I57669852cbf6aabae244ea86940a08a5a27ffc43
This commit is contained in:
Mathias Agopian 2011-06-28 19:09:31 -07:00
parent 0748907d6a
commit 698c0873cf
16 changed files with 464 additions and 503 deletions

View File

@ -29,6 +29,7 @@
namespace android {
class Parcel;
class ISurfaceComposerClient;
struct layer_state_t {
@ -68,6 +69,13 @@ struct layer_state_t {
Region transparentRegion;
};
struct ComposerState {
sp<ISurfaceComposerClient> client;
layer_state_t state;
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
};
}; // namespace android
#endif // ANDROID_SF_LAYER_STATE_H

View File

@ -34,6 +34,7 @@ namespace android {
// ----------------------------------------------------------------------------
class IMemoryHeap;
class ComposerState;
class ISurfaceComposer : public IInterface
{
@ -105,8 +106,7 @@ public:
virtual sp<IMemoryHeap> getCblk() const = 0;
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
virtual void openGlobalTransaction() = 0;
virtual void closeGlobalTransaction() = 0;
virtual void setTransactionState(const Vector<ComposerState>& state) = 0;
/* [un]freeze display. requires ACCESS_SURFACE_FLINGER permission */
virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags) = 0;
@ -149,8 +149,7 @@ public:
CREATE_CONNECTION,
CREATE_GRAPHIC_BUFFER_ALLOC,
GET_CBLK,
OPEN_GLOBAL_TRANSACTION,
CLOSE_GLOBAL_TRANSACTION,
SET_TRANSACTION_STATE,
SET_ORIENTATION,
FREEZE_DISPLAY,
UNFREEZE_DISPLAY,

View File

@ -37,8 +37,6 @@ typedef int32_t DisplayID;
// ----------------------------------------------------------------------------
class layer_state_t;
class ISurfaceComposerClient : public IInterface
{
public:
@ -69,11 +67,6 @@ public:
* Requires ACCESS_SURFACE_FLINGER permission
*/
virtual status_t destroySurface(SurfaceID sid) = 0;
/*
* Requires ACCESS_SURFACE_FLINGER permission
*/
virtual status_t setState(int32_t count, const layer_state_t* states) = 0;
};
// ----------------------------------------------------------------------------

View File

@ -37,10 +37,12 @@ namespace android {
// ---------------------------------------------------------------------------
class DisplayInfo;
class Composer;
class IMemoryHeap;
class ISurfaceComposer;
class Region;
class surface_flinger_cblk_t;
struct layer_state_t;
// ---------------------------------------------------------------------------
@ -59,8 +61,11 @@ public:
// ---------------------------------------------------------------------------
class Composer;
class SurfaceComposerClient : public RefBase
{
friend class Composer;
public:
SurfaceComposerClient();
virtual ~SurfaceComposerClient();
@ -101,13 +106,7 @@ public:
// All composer parameters must be changed within a transaction
// several surfaces can be updated in one transaction, all changes are
// committed at once when the transaction is closed.
// CloseTransaction() usually requires an IPC with the server.
//! Open a composer transaction
status_t openTransaction();
//! commit the transaction
status_t closeTransaction();
// closeGlobalTransaction() usually requires an IPC with the server.
//! Open a composer transaction on all active SurfaceComposerClients.
static void openGlobalTransaction();
@ -152,19 +151,12 @@ public:
private:
virtual void onFirstRef();
inline layer_state_t* get_state_l(SurfaceID id);
layer_state_t* lockLayerState(SurfaceID id);
inline void unlockLayerState();
Composer& getComposer();
mutable Mutex mLock;
SortedVector<layer_state_t> mStates;
int32_t mTransactionOpen;
layer_state_t* mPrebuiltLayerState;
// these don't need to be protected because they never change
// after assignment
mutable Mutex mLock;
status_t mStatus;
sp<ISurfaceComposerClient> mClient;
Composer& mComposer;
};
// ---------------------------------------------------------------------------

View File

@ -32,6 +32,8 @@ namespace android {
template <class TYPE>
class SortedVector : private SortedVectorImpl
{
friend class Vector<TYPE>;
public:
typedef TYPE value_type;

View File

@ -29,6 +29,9 @@
namespace android {
template <typename TYPE>
class SortedVector;
/*!
* The main templated vector class ensuring type safety
* while making use of VectorImpl.
@ -47,13 +50,17 @@ public:
Vector();
Vector(const Vector<TYPE>& rhs);
explicit Vector(const SortedVector<TYPE>& rhs);
virtual ~Vector();
/*! copy operator */
const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const;
Vector<TYPE>& operator = (const Vector<TYPE>& rhs);
/*
const Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const;
Vector<TYPE>& operator = (const SortedVector<TYPE>& rhs);
/*
* empty the vector
*/
@ -214,6 +221,11 @@ Vector<TYPE>::Vector(const Vector<TYPE>& rhs)
: VectorImpl(rhs) {
}
template<class TYPE> inline
Vector<TYPE>::Vector(const SortedVector<TYPE>& rhs)
: VectorImpl(static_cast<const VectorImpl&>(rhs)) {
}
template<class TYPE> inline
Vector<TYPE>::~Vector() {
finish_vector();
@ -227,6 +239,18 @@ Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
template<class TYPE> inline
const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {
VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
return *this;
}
template<class TYPE> inline
Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
VectorImpl::operator = (static_cast<const VectorImpl&>(rhs));
return *this;
}
template<class TYPE> inline
const Vector<TYPE>& Vector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
VectorImpl::operator = (rhs);
return *this;
}

View File

@ -25,6 +25,8 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <private/surfaceflinger/LayerState.h>
#include <surfaceflinger/ISurfaceComposer.h>
#include <ui/DisplayInfo.h>
@ -74,18 +76,17 @@ public:
return interface_cast<IMemoryHeap>(reply.readStrongBinder());
}
virtual void openGlobalTransaction()
virtual void setTransactionState(const Vector<ComposerState>& state)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::OPEN_GLOBAL_TRANSACTION, data, &reply);
}
virtual void closeGlobalTransaction()
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::CLOSE_GLOBAL_TRANSACTION, data, &reply);
Vector<ComposerState>::const_iterator b(state.begin());
Vector<ComposerState>::const_iterator e(state.end());
data.writeInt32(state.size());
for ( ; b != e ; ++b ) {
b->write(data);
}
remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
}
virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags)
@ -218,13 +219,17 @@ status_t BnSurfaceComposer::onTransact(
sp<IBinder> b = createGraphicBufferAlloc()->asBinder();
reply->writeStrongBinder(b);
} break;
case OPEN_GLOBAL_TRANSACTION: {
case SET_TRANSACTION_STATE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
openGlobalTransaction();
} break;
case CLOSE_GLOBAL_TRANSACTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
closeGlobalTransaction();
size_t count = data.readInt32();
ComposerState s;
Vector<ComposerState> state;
state.setCapacity(count);
for (size_t i=0 ; i<count ; i++) {
s.read(data);
state.add(s);
}
setTransactionState(state);
} break;
case SET_ORIENTATION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);

View File

@ -51,8 +51,7 @@ namespace android {
enum {
CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
DESTROY_SURFACE,
SET_STATE
DESTROY_SURFACE
};
class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
@ -92,17 +91,6 @@ public:
remote()->transact(DESTROY_SURFACE, data, &reply);
return reply.readInt32();
}
virtual status_t setState(int32_t count, const layer_state_t* states)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
data.writeInt32(count);
for (int i=0 ; i<count ; i++)
states[i].write(data);
remote()->transact(SET_STATE, data, &reply);
return reply.readInt32();
}
};
IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
@ -133,17 +121,6 @@ status_t BnSurfaceComposerClient::onTransact(
reply->writeInt32( destroySurface( data.readInt32() ) );
return NO_ERROR;
} break;
case SET_STATE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
int32_t count = data.readInt32();
layer_state_t* states = new layer_state_t[count];
for (int i=0 ; i<count ; i++)
states[i].read(data);
status_t err = setState(count, states);
delete [] states;
reply->writeInt32(err);
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}

View File

@ -17,6 +17,7 @@
#include <utils/Errors.h>
#include <binder/Parcel.h>
#include <private/surfaceflinger/LayerState.h>
#include <surfaceflinger/ISurfaceComposerClient.h>
namespace android {
@ -58,4 +59,14 @@ status_t layer_state_t::read(const Parcel& input)
return NO_ERROR;
}
status_t ComposerState::write(Parcel& output) const {
output.writeStrongBinder(client->asBinder());
return state.write(output);
}
status_t ComposerState::read(const Parcel& input) {
client = interface_cast<ISurfaceComposerClient>(input.readStrongBinder());
return state.read(input);
}
}; // namespace android

View File

@ -74,75 +74,52 @@ static inline surface_flinger_cblk_t const volatile * get_cblk() {
// ---------------------------------------------------------------------------
// NOTE: this is NOT a member function (it's a friend defined with its
// declaration).
static inline
int compare_type( const ComposerState& lhs, const ComposerState& rhs) {
if (lhs.client < rhs.client) return -1;
if (lhs.client > rhs.client) return 1;
if (lhs.state.surface < rhs.state.surface) return -1;
if (lhs.state.surface > rhs.state.surface) return 1;
return 0;
}
class Composer : public Singleton<Composer>
{
Mutex mLock;
SortedVector< wp<SurfaceComposerClient> > mActiveConnections;
SortedVector<sp<SurfaceComposerClient> > mOpenTransactions;
Composer() : Singleton<Composer>() {
}
void addClientImpl(const sp<SurfaceComposerClient>& client) {
Mutex::Autolock _l(mLock);
mActiveConnections.add(client);
}
void removeClientImpl(const sp<SurfaceComposerClient>& client) {
Mutex::Autolock _l(mLock);
mActiveConnections.remove(client);
}
void openGlobalTransactionImpl()
{
Mutex::Autolock _l(mLock);
if (mOpenTransactions.size()) {
LOGE("openGlobalTransaction() called more than once. skipping.");
return;
}
const size_t N = mActiveConnections.size();
for (size_t i=0; i<N; i++) {
sp<SurfaceComposerClient> client(mActiveConnections[i].promote());
if (client != 0 && mOpenTransactions.indexOf(client) < 0) {
if (client->openTransaction() == NO_ERROR) {
mOpenTransactions.add(client);
} else {
LOGE("openTransaction on client %p failed", client.get());
// let it go, it'll fail later when the user
// tries to do something with the transaction
}
}
}
}
void closeGlobalTransactionImpl()
{
mLock.lock();
SortedVector< sp<SurfaceComposerClient> > clients(mOpenTransactions);
mOpenTransactions.clear();
mLock.unlock();
sp<ISurfaceComposer> sm(getComposerService());
sm->openGlobalTransaction();
const size_t N = clients.size();
for (size_t i=0; i<N; i++) {
clients[i]->closeTransaction();
}
sm->closeGlobalTransaction();
}
friend class Singleton<Composer>;
mutable Mutex mLock;
SortedVector<ComposerState> mStates;
Composer() : Singleton<Composer>() { }
void closeGlobalTransactionImpl();
layer_state_t* getLayerStateLocked(
const sp<SurfaceComposerClient>& client, SurfaceID id);
public:
static void addClient(const sp<SurfaceComposerClient>& client) {
Composer::getInstance().addClientImpl(client);
}
static void removeClient(const sp<SurfaceComposerClient>& client) {
Composer::getInstance().removeClientImpl(client);
}
static void openGlobalTransaction() {
Composer::getInstance().openGlobalTransactionImpl();
}
status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
int32_t x, int32_t y);
status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id,
uint32_t w, uint32_t h);
status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id,
int32_t z);
status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id,
uint32_t flags, uint32_t mask);
status_t setTransparentRegionHint(
const sp<SurfaceComposerClient>& client, SurfaceID id,
const Region& transparentRegion);
status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id,
float alpha);
status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
float dsdx, float dtdx, float dsdy, float dtdy);
status_t setFreezeTint(
const sp<SurfaceComposerClient>& client, SurfaceID id,
uint32_t tint);
static void closeGlobalTransaction() {
Composer::getInstance().closeGlobalTransactionImpl();
}
@ -152,69 +129,306 @@ ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
// ---------------------------------------------------------------------------
static inline int compare_type( const layer_state_t& lhs,
const layer_state_t& rhs) {
if (lhs.surface < rhs.surface) return -1;
if (lhs.surface > rhs.surface) return 1;
return 0;
void Composer::closeGlobalTransactionImpl() {
sp<ISurfaceComposer> sm(getComposerService());
Vector<ComposerState> transaction;
{ // scope for the lock
Mutex::Autolock _l(mLock);
transaction = mStates;
mStates.clear();
}
sm->setTransactionState(transaction);
}
layer_state_t* Composer::getLayerStateLocked(
const sp<SurfaceComposerClient>& client, SurfaceID id) {
ComposerState s;
s.client = client->mClient;
s.state.surface = id;
ssize_t index = mStates.indexOf(s);
if (index < 0) {
// we don't have it, add an initialized layer_state to our list
index = mStates.add(s);
}
ComposerState* const out = mStates.editArray();
return &(out[index].state);
}
status_t Composer::setPosition(const sp<SurfaceComposerClient>& client,
SurfaceID id, int32_t x, int32_t y) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= ISurfaceComposer::ePositionChanged;
s->x = x;
s->y = y;
return NO_ERROR;
}
status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
SurfaceID id, uint32_t w, uint32_t h) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= ISurfaceComposer::eSizeChanged;
s->w = w;
s->h = h;
return NO_ERROR;
}
status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
SurfaceID id, int32_t z) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= ISurfaceComposer::eLayerChanged;
s->z = z;
return NO_ERROR;
}
status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
SurfaceID id, uint32_t flags,
uint32_t mask) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= ISurfaceComposer::eVisibilityChanged;
s->flags &= ~mask;
s->flags |= (flags & mask);
s->mask |= mask;
return NO_ERROR;
}
status_t Composer::setTransparentRegionHint(
const sp<SurfaceComposerClient>& client, SurfaceID id,
const Region& transparentRegion) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= ISurfaceComposer::eTransparentRegionChanged;
s->transparentRegion = transparentRegion;
return NO_ERROR;
}
status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client,
SurfaceID id, float alpha) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= ISurfaceComposer::eAlphaChanged;
s->alpha = alpha;
return NO_ERROR;
}
status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
SurfaceID id, float dsdx, float dtdx,
float dsdy, float dtdy) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= ISurfaceComposer::eMatrixChanged;
layer_state_t::matrix22_t matrix;
matrix.dsdx = dsdx;
matrix.dtdx = dtdx;
matrix.dsdy = dsdy;
matrix.dtdy = dtdy;
s->matrix = matrix;
return NO_ERROR;
}
status_t Composer::setFreezeTint(const sp<SurfaceComposerClient>& client,
SurfaceID id, uint32_t tint) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= ISurfaceComposer::eFreezeTintChanged;
s->tint = tint;
return NO_ERROR;
}
// ---------------------------------------------------------------------------
SurfaceComposerClient::SurfaceComposerClient()
: mTransactionOpen(0), mPrebuiltLayerState(0), mStatus(NO_INIT)
: mStatus(NO_INIT), mComposer(Composer::getInstance())
{
}
void SurfaceComposerClient::onFirstRef()
{
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sm(getComposerService());
if (sm != 0) {
sp<ISurfaceComposerClient> conn = sm->createConnection();
if (conn != 0) {
mClient = conn;
Composer::addClient(this);
mPrebuiltLayerState = new layer_state_t;
mStatus = NO_ERROR;
}
}
}
SurfaceComposerClient::~SurfaceComposerClient()
{
delete mPrebuiltLayerState;
SurfaceComposerClient::~SurfaceComposerClient() {
dispose();
}
status_t SurfaceComposerClient::initCheck() const
{
status_t SurfaceComposerClient::initCheck() const {
return mStatus;
}
sp<IBinder> SurfaceComposerClient::connection() const
{
sp<IBinder> SurfaceComposerClient::connection() const {
return (mClient != 0) ? mClient->asBinder() : 0;
}
status_t SurfaceComposerClient::linkToComposerDeath(
const sp<IBinder::DeathRecipient>& recipient,
void* cookie, uint32_t flags)
{
void* cookie, uint32_t flags) {
sp<ISurfaceComposer> sm(getComposerService());
return sm->asBinder()->linkToDeath(recipient, cookie, flags);
}
void SurfaceComposerClient::dispose()
{
void SurfaceComposerClient::dispose() {
// this can be called more than once.
sp<ISurfaceComposerClient> client;
Mutex::Autolock _lm(mLock);
if (mClient != 0) {
Composer::removeClient(this);
client = mClient; // hold ref while lock is held
mClient.clear();
}
mStatus = NO_INIT;
}
sp<SurfaceControl> SurfaceComposerClient::createSurface(
DisplayID display,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
String8 name;
const size_t SIZE = 128;
char buffer[SIZE];
snprintf(buffer, SIZE, "<pid_%d>", getpid());
name.append(buffer);
return SurfaceComposerClient::createSurface(name, display,
w, h, format, flags);
}
sp<SurfaceControl> SurfaceComposerClient::createSurface(
const String8& name,
DisplayID display,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
sp<SurfaceControl> result;
if (mStatus == NO_ERROR) {
ISurfaceComposerClient::surface_data_t data;
sp<ISurface> surface = mClient->createSurface(&data, name,
display, w, h, format, flags);
if (surface != 0) {
result = new SurfaceControl(this, surface, data, w, h, format, flags);
}
}
return result;
}
status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
if (mStatus != NO_ERROR)
return mStatus;
status_t err = mClient->destroySurface(sid);
return err;
}
inline Composer& SurfaceComposerClient::getComposer() {
return mComposer;
}
// ----------------------------------------------------------------------------
void SurfaceComposerClient::openGlobalTransaction() {
// Currently a no-op
}
void SurfaceComposerClient::closeGlobalTransaction() {
Composer::closeGlobalTransaction();
}
// ----------------------------------------------------------------------------
status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) {
return getComposer().setFreezeTint(this, id, tint);
}
status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y) {
return getComposer().setPosition(this, id, x, y);
}
status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) {
return getComposer().setSize(this, id, w, h);
}
status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) {
return getComposer().setLayer(this, id, z);
}
status_t SurfaceComposerClient::hide(SurfaceID id) {
return getComposer().setFlags(this, id,
ISurfaceComposer::eLayerHidden,
ISurfaceComposer::eLayerHidden);
}
status_t SurfaceComposerClient::show(SurfaceID id, int32_t) {
return getComposer().setFlags(this, id,
0,
ISurfaceComposer::eLayerHidden);
}
status_t SurfaceComposerClient::freeze(SurfaceID id) {
return getComposer().setFlags(this, id,
ISurfaceComposer::eLayerFrozen,
ISurfaceComposer::eLayerFrozen);
}
status_t SurfaceComposerClient::unfreeze(SurfaceID id) {
return getComposer().setFlags(this, id,
0,
ISurfaceComposer::eLayerFrozen);
}
status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
uint32_t mask) {
return getComposer().setFlags(this, id, flags, mask);
}
status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id,
const Region& transparentRegion) {
return getComposer().setTransparentRegionHint(this, id, transparentRegion);
}
status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) {
return getComposer().setAlpha(this, id, alpha);
}
status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx,
float dsdy, float dtdy) {
return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
}
// ----------------------------------------------------------------------------
status_t SurfaceComposerClient::getDisplayInfo(
DisplayID dpy, DisplayInfo* info)
{
@ -273,70 +487,7 @@ ssize_t SurfaceComposerClient::getNumberOfDisplays()
return n;
}
sp<SurfaceControl> SurfaceComposerClient::createSurface(
DisplayID display,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
String8 name;
const size_t SIZE = 128;
char buffer[SIZE];
snprintf(buffer, SIZE, "<pid_%d>", getpid());
name.append(buffer);
return SurfaceComposerClient::createSurface(name, display,
w, h, format, flags);
}
sp<SurfaceControl> SurfaceComposerClient::createSurface(
const String8& name,
DisplayID display,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
sp<SurfaceControl> result;
if (mStatus == NO_ERROR) {
ISurfaceComposerClient::surface_data_t data;
sp<ISurface> surface = mClient->createSurface(&data, name,
display, w, h, format, flags);
if (surface != 0) {
result = new SurfaceControl(this, surface, data, w, h, format, flags);
}
}
return result;
}
status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
{
if (mStatus != NO_ERROR)
return mStatus;
// it's okay to destroy a surface while a transaction is open,
// (transactions really are a client-side concept)
// however, this indicates probably a misuse of the API or a bug
// in the client code.
LOGW_IF(mTransactionOpen,
"Destroying surface while a transaction is open. "
"Client %p: destroying surface %d, mTransactionOpen=%d",
this, sid, mTransactionOpen);
status_t err = mClient->destroySurface(sid);
return err;
}
void SurfaceComposerClient::openGlobalTransaction()
{
Composer::openGlobalTransaction();
}
void SurfaceComposerClient::closeGlobalTransaction()
{
Composer::closeGlobalTransaction();
}
// ----------------------------------------------------------------------------
status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
{
@ -350,199 +501,13 @@ status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
return sm->unfreezeDisplay(dpy, flags);
}
int SurfaceComposerClient::setOrientation(DisplayID dpy,
int SurfaceComposerClient::setOrientation(DisplayID dpy,
int orientation, uint32_t flags)
{
sp<ISurfaceComposer> sm(getComposerService());
return sm->setOrientation(dpy, orientation, flags);
}
status_t SurfaceComposerClient::openTransaction()
{
if (mStatus != NO_ERROR)
return mStatus;
Mutex::Autolock _l(mLock);
mTransactionOpen++;
return NO_ERROR;
}
status_t SurfaceComposerClient::closeTransaction()
{
if (mStatus != NO_ERROR)
return mStatus;
Mutex::Autolock _l(mLock);
if (mTransactionOpen <= 0) {
LOGE( "closeTransaction (client %p, mTransactionOpen=%d) "
"called more times than openTransaction()",
this, mTransactionOpen);
return INVALID_OPERATION;
}
if (mTransactionOpen >= 2) {
mTransactionOpen--;
return NO_ERROR;
}
mTransactionOpen = 0;
const ssize_t count = mStates.size();
if (count) {
mClient->setState(count, mStates.array());
mStates.clear();
}
return NO_ERROR;
}
layer_state_t* SurfaceComposerClient::get_state_l(SurfaceID index)
{
// API usage error, do nothing.
if (mTransactionOpen<=0) {
LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
this, int(index), mTransactionOpen);
return 0;
}
// use mPrebuiltLayerState just to find out if we already have it
layer_state_t& dummy(*mPrebuiltLayerState);
dummy.surface = index;
ssize_t i = mStates.indexOf(dummy);
if (i < 0) {
// we don't have it, add an initialized layer_state to our list
i = mStates.add(dummy);
}
return mStates.editArray() + i;
}
layer_state_t* SurfaceComposerClient::lockLayerState(SurfaceID id)
{
layer_state_t* s;
mLock.lock();
s = get_state_l(id);
if (!s) mLock.unlock();
return s;
}
void SurfaceComposerClient::unlockLayerState()
{
mLock.unlock();
}
status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
{
layer_state_t* s = lockLayerState(id);
if (!s) return BAD_INDEX;
s->what |= ISurfaceComposer::ePositionChanged;
s->x = x;
s->y = y;
unlockLayerState();
return NO_ERROR;
}
status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h)
{
layer_state_t* s = lockLayerState(id);
if (!s) return BAD_INDEX;
s->what |= ISurfaceComposer::eSizeChanged;
s->w = w;
s->h = h;
unlockLayerState();
return NO_ERROR;
}
status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)
{
layer_state_t* s = lockLayerState(id);
if (!s) return BAD_INDEX;
s->what |= ISurfaceComposer::eLayerChanged;
s->z = z;
unlockLayerState();
return NO_ERROR;
}
status_t SurfaceComposerClient::hide(SurfaceID id)
{
return setFlags(id, ISurfaceComposer::eLayerHidden,
ISurfaceComposer::eLayerHidden);
}
status_t SurfaceComposerClient::show(SurfaceID id, int32_t)
{
return setFlags(id, 0, ISurfaceComposer::eLayerHidden);
}
status_t SurfaceComposerClient::freeze(SurfaceID id)
{
return setFlags(id, ISurfaceComposer::eLayerFrozen,
ISurfaceComposer::eLayerFrozen);
}
status_t SurfaceComposerClient::unfreeze(SurfaceID id)
{
return setFlags(id, 0, ISurfaceComposer::eLayerFrozen);
}
status_t SurfaceComposerClient::setFlags(SurfaceID id,
uint32_t flags, uint32_t mask)
{
layer_state_t* s = lockLayerState(id);
if (!s) return BAD_INDEX;
s->what |= ISurfaceComposer::eVisibilityChanged;
s->flags &= ~mask;
s->flags |= (flags & mask);
s->mask |= mask;
unlockLayerState();
return NO_ERROR;
}
status_t SurfaceComposerClient::setTransparentRegionHint(
SurfaceID id, const Region& transparentRegion)
{
layer_state_t* s = lockLayerState(id);
if (!s) return BAD_INDEX;
s->what |= ISurfaceComposer::eTransparentRegionChanged;
s->transparentRegion = transparentRegion;
unlockLayerState();
return NO_ERROR;
}
status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha)
{
layer_state_t* s = lockLayerState(id);
if (!s) return BAD_INDEX;
s->what |= ISurfaceComposer::eAlphaChanged;
s->alpha = alpha;
unlockLayerState();
return NO_ERROR;
}
status_t SurfaceComposerClient::setMatrix(
SurfaceID id,
float dsdx, float dtdx,
float dsdy, float dtdy )
{
layer_state_t* s = lockLayerState(id);
if (!s) return BAD_INDEX;
s->what |= ISurfaceComposer::eMatrixChanged;
layer_state_t::matrix22_t matrix;
matrix.dsdx = dsdx;
matrix.dtdx = dtdx;
matrix.dsdy = dsdy;
matrix.dtdy = dtdy;
s->matrix = matrix;
unlockLayerState();
return NO_ERROR;
}
status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
{
layer_state_t* s = lockLayerState(id);
if (!s) return BAD_INDEX;
s->what |= ISurfaceComposer::eFreezeTintChanged;
s->tint = tint;
unlockLayerState();
return NO_ERROR;
}
// ----------------------------------------------------------------------------
ScreenshotClient::ScreenshotClient()

View File

@ -84,10 +84,10 @@ protected:
ASSERT_TRUE(mSurfaceControl != NULL);
ASSERT_TRUE(mSurfaceControl->isValid());
ASSERT_EQ(NO_ERROR, mComposerClient->openTransaction());
SurfaceComposerClient::openGlobalTransaction();
ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
ASSERT_EQ(NO_ERROR, mComposerClient->closeTransaction());
SurfaceComposerClient::closeGlobalTransaction();
sp<ANativeWindow> window = mSurfaceControl->getSurface();
mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig,

View File

@ -36,10 +36,10 @@ protected:
ASSERT_TRUE(mSurfaceControl != NULL);
ASSERT_TRUE(mSurfaceControl->isValid());
ASSERT_EQ(NO_ERROR, mComposerClient->openTransaction());
SurfaceComposerClient::openGlobalTransaction();
ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(30000));
ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
ASSERT_EQ(NO_ERROR, mComposerClient->closeTransaction());
SurfaceComposerClient::closeGlobalTransaction();
mSurface = mSurfaceControl->getSurface();
ASSERT_TRUE(mSurface != NULL);

View File

@ -78,7 +78,6 @@ const String16 sDump("android.permission.DUMP");
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(), Thread(false),
mTransactionFlags(0),
mTransactionCount(0),
mResizeTransationPending(false),
mLayersRemoved(false),
mBootTime(systemTime()),
@ -385,13 +384,11 @@ bool SurfaceFlinger::threadLoop()
handleConsoleEvents();
}
if (LIKELY(mTransactionCount == 0)) {
// if we're in a global transaction, don't do anything.
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
uint32_t transactionFlags = peekTransactionFlags(mask);
if (LIKELY(transactionFlags)) {
handleTransaction(transactionFlags);
}
// if we're in a global transaction, don't do anything.
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
uint32_t transactionFlags = peekTransactionFlags(mask);
if (UNLIKELY(transactionFlags)) {
handleTransaction(transactionFlags);
}
// post surfaces (if needed)
@ -1176,28 +1173,33 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
return old;
}
void SurfaceFlinger::openGlobalTransaction()
{
android_atomic_inc(&mTransactionCount);
}
void SurfaceFlinger::closeGlobalTransaction()
{
if (android_atomic_dec(&mTransactionCount) == 1) {
signalEvent();
void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state) {
Mutex::Autolock _l(mStateLock);
// if there is a transaction with a resize, wait for it to
// take effect before returning.
Mutex::Autolock _l(mStateLock);
while (mResizeTransationPending) {
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;
break;
}
uint32_t flags = 0;
const size_t count = state.size();
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);
}
if (flags) {
setTransactionFlags(flags);
}
signalEvent();
// if there is a transaction with a resize, wait for it to
// take effect before returning.
while (mResizeTransationPending) {
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;
break;
}
}
}
@ -1393,60 +1395,52 @@ status_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer)
return err;
}
status_t SurfaceFlinger::setClientState(
uint32_t SurfaceFlinger::setClientStateLocked(
const sp<Client>& client,
int32_t count,
const layer_state_t* states)
const layer_state_t& s)
{
Mutex::Autolock _l(mStateLock);
uint32_t flags = 0;
for (int i=0 ; i<count ; i++) {
const layer_state_t& s(states[i]);
sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
if (layer != 0) {
const uint32_t what = s.what;
if (what & ePositionChanged) {
if (layer->setPosition(s.x, s.y))
flags |= eTraversalNeeded;
}
if (what & eLayerChanged) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
if (layer->setLayer(s.z)) {
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
// AND transaction (list changed)
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
if (what & eSizeChanged) {
if (layer->setSize(s.w, s.h)) {
flags |= eTraversalNeeded;
mResizeTransationPending = true;
}
}
if (what & eAlphaChanged) {
if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
flags |= eTraversalNeeded;
}
if (what & eMatrixChanged) {
if (layer->setMatrix(s.matrix))
flags |= eTraversalNeeded;
}
if (what & eTransparentRegionChanged) {
if (layer->setTransparentRegionHint(s.transparentRegion))
flags |= eTraversalNeeded;
}
if (what & eVisibilityChanged) {
if (layer->setFlags(s.flags, s.mask))
flags |= eTraversalNeeded;
sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
if (layer != 0) {
const uint32_t what = s.what;
if (what & ePositionChanged) {
if (layer->setPosition(s.x, s.y))
flags |= eTraversalNeeded;
}
if (what & eLayerChanged) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
if (layer->setLayer(s.z)) {
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
// AND transaction (list changed)
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
if (what & eSizeChanged) {
if (layer->setSize(s.w, s.h)) {
flags |= eTraversalNeeded;
mResizeTransationPending = true;
}
}
if (what & eAlphaChanged) {
if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
flags |= eTraversalNeeded;
}
if (what & eMatrixChanged) {
if (layer->setMatrix(s.matrix))
flags |= eTraversalNeeded;
}
if (what & eTransparentRegionChanged) {
if (layer->setTransparentRegionHint(s.transparentRegion))
flags |= eTraversalNeeded;
}
if (what & eVisibilityChanged) {
if (layer->setFlags(s.flags, s.mask))
flags |= eTraversalNeeded;
}
}
if (flags) {
setTransactionFlags(flags);
}
return NO_ERROR;
return flags;
}
void SurfaceFlinger::screenReleased(int dpy)
@ -1588,8 +1582,7 @@ status_t SurfaceFlinger::onTransact(
{
switch (code) {
case CREATE_CONNECTION:
case OPEN_GLOBAL_TRANSACTION:
case CLOSE_GLOBAL_TRANSACTION:
case SET_TRANSACTION_STATE:
case SET_ORIENTATION:
case FREEZE_DISPLAY:
case UNFREEZE_DISPLAY:
@ -2469,9 +2462,6 @@ sp<ISurface> Client::createSurface(
status_t Client::destroySurface(SurfaceID sid) {
return mFlinger->removeSurface(this, sid);
}
status_t Client::setState(int32_t count, const layer_state_t* states) {
return mFlinger->setClientState(this, count, states);
}
// ---------------------------------------------------------------------------

View File

@ -70,14 +70,12 @@ public:
sp<LayerBaseClient> getLayerUser(int32_t i) const;
private:
// ISurfaceComposerClient interface
virtual sp<ISurface> createSurface(
surface_data_t* params, const String8& name,
DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
uint32_t flags);
virtual status_t destroySurface(SurfaceID surfaceId);
virtual status_t setState(int32_t count, const layer_state_t* states);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
@ -168,8 +166,7 @@ public:
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc();
virtual sp<IMemoryHeap> getCblk() const;
virtual void bootFinished();
virtual void openGlobalTransaction();
virtual void closeGlobalTransaction();
virtual void setTransactionState(const Vector<ComposerState>& state);
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);
@ -220,8 +217,7 @@ private:
status_t removeSurface(const sp<Client>& client, SurfaceID sid);
status_t destroySurface(const wp<LayerBaseClient>& layer);
status_t setClientState(const sp<Client>& client,
int32_t count, const layer_state_t* states);
uint32_t setClientStateLocked(const sp<Client>& client, const layer_state_t& s);
class LayerVector : public SortedVector< sp<LayerBase> > {
public:
@ -337,7 +333,6 @@ private:
mutable Mutex mStateLock;
State mCurrentState;
volatile int32_t mTransactionFlags;
volatile int32_t mTransactionCount;
Condition mTransactionCV;
SortedVector< sp<LayerBase> > mLayerPurgatory;
bool mResizeTransationPending;

View File

@ -43,9 +43,9 @@ int main(int argc, char** argv)
PIXEL_FORMAT_RGB_565);
client->openTransaction();
SurfaceComposerClient::openGlobalTransaction();
surface->setLayer(100000);
client->closeTransaction();
SurfaceComposerClient::closeGlobalTransaction();
Surface::SurfaceInfo info;
surface->lock(&info);
@ -57,9 +57,9 @@ int main(int argc, char** argv)
android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h);
surface->unlockAndPost();
client->openTransaction();
SurfaceComposerClient::openGlobalTransaction();
surface->setSize(320, 240);
client->closeTransaction();
SurfaceComposerClient::closeGlobalTransaction();
IPCThreadState::self()->joinThreadPool();

View File

@ -39,9 +39,9 @@ int main(int argc, char** argv)
sp<SurfaceControl> surfaceControl = client->createSurface(
getpid(), 0, 160, 240, PIXEL_FORMAT_RGB_565);
client->openTransaction();
SurfaceComposerClient::openGlobalTransaction();
surfaceControl->setLayer(100000);
client->closeTransaction();
SurfaceComposerClient::closeGlobalTransaction();
// pretend it went cross-process
Parcel parcel;