Merge "SF transactions are now O(1) wrt IPC instead of O(N)."
This commit is contained in:
commit
e6786c92d7
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -32,6 +32,8 @@ namespace android {
|
||||
template <class TYPE>
|
||||
class SortedVector : private SortedVectorImpl
|
||||
{
|
||||
friend class Vector<TYPE>;
|
||||
|
||||
public:
|
||||
typedef TYPE value_type;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user