make multi-display more real
- displays are represented by a binder on the client side - c++ clients can now create and modify displays Change-Id: I203ea5b4beae0819d742ec5171c27568f4e8354b
This commit is contained in:
parent
ef7b9c7eac
commit
e57f292595
|
@ -48,6 +48,11 @@ public:
|
||||||
eSynchronous = 0x01,
|
eSynchronous = 0x01,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
eDisplayIdMain = 0,
|
||||||
|
eDisplayIdHdmi = 1
|
||||||
|
};
|
||||||
|
|
||||||
/* create connection with surface flinger, requires
|
/* create connection with surface flinger, requires
|
||||||
* ACCESS_SURFACE_FLINGER permission
|
* ACCESS_SURFACE_FLINGER permission
|
||||||
*/
|
*/
|
||||||
|
@ -57,6 +62,19 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() = 0;
|
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() = 0;
|
||||||
|
|
||||||
|
/* return an IDisplayEventConnection */
|
||||||
|
virtual sp<IDisplayEventConnection> createDisplayEventConnection() = 0;
|
||||||
|
|
||||||
|
/* create a display with given id.
|
||||||
|
* requires ACCESS_SURFACE_FLINGER permission.
|
||||||
|
*/
|
||||||
|
virtual sp<IBinder> createDisplay() = 0;
|
||||||
|
|
||||||
|
/* get the token for the existing default displays. possible values
|
||||||
|
* for id are eDisplayIdMain and eDisplayIdHdmi.
|
||||||
|
*/
|
||||||
|
virtual sp<IBinder> getBuiltInDisplay(int32_t id) = 0;
|
||||||
|
|
||||||
/* 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,
|
||||||
const Vector<DisplayState>& displays, uint32_t flags) = 0;
|
const Vector<DisplayState>& displays, uint32_t flags) = 0;
|
||||||
|
@ -66,6 +84,11 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void bootFinished() = 0;
|
virtual void bootFinished() = 0;
|
||||||
|
|
||||||
|
/* verify that an ISurfaceTexture was created by SurfaceFlinger.
|
||||||
|
*/
|
||||||
|
virtual bool authenticateSurfaceTexture(
|
||||||
|
const sp<ISurfaceTexture>& surface) const = 0;
|
||||||
|
|
||||||
/* Capture the specified screen. requires READ_FRAME_BUFFER permission
|
/* Capture the specified screen. requires READ_FRAME_BUFFER permission
|
||||||
* This function will fail if there is a secure window on screen.
|
* This function will fail if there is a secure window on screen.
|
||||||
*/
|
*/
|
||||||
|
@ -74,13 +97,6 @@ public:
|
||||||
uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
|
uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
|
||||||
uint32_t maxLayerZ) = 0;
|
uint32_t maxLayerZ) = 0;
|
||||||
|
|
||||||
/* verify that an ISurfaceTexture was created by SurfaceFlinger.
|
|
||||||
*/
|
|
||||||
virtual bool authenticateSurfaceTexture(
|
|
||||||
const sp<ISurfaceTexture>& surface) const = 0;
|
|
||||||
|
|
||||||
/* return an IDisplayEventConnection */
|
|
||||||
virtual sp<IDisplayEventConnection> createDisplayEventConnection() = 0;
|
|
||||||
|
|
||||||
/* triggers screen off and waits for it to complete */
|
/* triggers screen off and waits for it to complete */
|
||||||
virtual void blank() = 0;
|
virtual void blank() = 0;
|
||||||
|
@ -106,13 +122,15 @@ public:
|
||||||
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
|
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
|
||||||
CREATE_CONNECTION,
|
CREATE_CONNECTION,
|
||||||
CREATE_GRAPHIC_BUFFER_ALLOC,
|
CREATE_GRAPHIC_BUFFER_ALLOC,
|
||||||
GET_DISPLAY_INFO,
|
|
||||||
SET_TRANSACTION_STATE,
|
|
||||||
CAPTURE_SCREEN,
|
|
||||||
AUTHENTICATE_SURFACE,
|
|
||||||
CREATE_DISPLAY_EVENT_CONNECTION,
|
CREATE_DISPLAY_EVENT_CONNECTION,
|
||||||
|
CREATE_DISPLAY,
|
||||||
|
GET_BUILT_IN_DISPLAY,
|
||||||
|
SET_TRANSACTION_STATE,
|
||||||
|
AUTHENTICATE_SURFACE,
|
||||||
|
CAPTURE_SCREEN,
|
||||||
BLANK,
|
BLANK,
|
||||||
UNBLANK,
|
UNBLANK,
|
||||||
|
GET_DISPLAY_INFO,
|
||||||
CONNECT_DISPLAY,
|
CONNECT_DISPLAY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,13 @@ public:
|
||||||
// Forcibly remove connection before all references have gone away.
|
// Forcibly remove connection before all references have gone away.
|
||||||
void dispose();
|
void dispose();
|
||||||
|
|
||||||
|
// callback when the composer is dies
|
||||||
|
status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
|
||||||
|
void* cookie = NULL, uint32_t flags = 0);
|
||||||
|
|
||||||
|
// Get information about a display
|
||||||
|
static status_t getDisplayInfo(DisplayID dpy, DisplayInfo* info);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// surface creation / destruction
|
// surface creation / destruction
|
||||||
|
|
||||||
|
@ -80,13 +87,14 @@ public:
|
||||||
uint32_t flags = 0 // usage flags
|
uint32_t flags = 0 // usage flags
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static sp<IBinder> createDisplay();
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Composer parameters
|
// Composer parameters
|
||||||
// All composer parameters must be changed within a transaction
|
// All composer parameters must be changed within a transaction
|
||||||
// several surfaces can be updated in one transaction, all changes are
|
// several surfaces can be updated in one transaction, all changes are
|
||||||
// committed at once when the transaction is closed.
|
// committed at once when the transaction is closed.
|
||||||
// closeGlobalTransaction() usually requires an IPC with the server.
|
// closeGlobalTransaction() requires an IPC with the server.
|
||||||
|
|
||||||
//! Open a composer transaction on all active SurfaceComposerClients.
|
//! Open a composer transaction on all active SurfaceComposerClients.
|
||||||
static void openGlobalTransaction();
|
static void openGlobalTransaction();
|
||||||
|
@ -97,12 +105,6 @@ public:
|
||||||
//! Set the orientation of the given display
|
//! Set the orientation of the given display
|
||||||
static int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
|
static int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
|
||||||
|
|
||||||
// Get information about a display
|
|
||||||
static status_t getDisplayInfo(DisplayID dpy, DisplayInfo* info);
|
|
||||||
|
|
||||||
status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
|
|
||||||
void* cookie = NULL, uint32_t flags = 0);
|
|
||||||
|
|
||||||
status_t hide(SurfaceID id);
|
status_t hide(SurfaceID id);
|
||||||
status_t show(SurfaceID id, int32_t layer = -1);
|
status_t show(SurfaceID id, int32_t layer = -1);
|
||||||
status_t setFlags(SurfaceID id, uint32_t flags, uint32_t mask);
|
status_t setFlags(SurfaceID id, uint32_t flags, uint32_t mask);
|
||||||
|
@ -116,6 +118,16 @@ public:
|
||||||
status_t setLayerStack(SurfaceID id, uint32_t layerStack);
|
status_t setLayerStack(SurfaceID id, uint32_t layerStack);
|
||||||
status_t destroySurface(SurfaceID sid);
|
status_t destroySurface(SurfaceID sid);
|
||||||
|
|
||||||
|
static void setDisplaySurface(const sp<IBinder>& token,
|
||||||
|
const sp<ISurfaceTexture>& surface);
|
||||||
|
static void setDisplayLayerStack(const sp<IBinder>& token,
|
||||||
|
uint32_t layerStack);
|
||||||
|
static void setDisplayOrientation(const sp<IBinder>& token,
|
||||||
|
uint32_t orientation);
|
||||||
|
static void setDisplayViewport(const sp<IBinder>& token,
|
||||||
|
const Rect& viewport);
|
||||||
|
static void setDisplayFrame(const sp<IBinder>& token, const Rect& frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void onFirstRef();
|
virtual void onFirstRef();
|
||||||
Composer& getComposer();
|
Composer& getComposer();
|
||||||
|
|
|
@ -106,14 +106,21 @@ struct DisplayState {
|
||||||
eOrientationSwapMask = 0x01
|
eOrientationSwapMask = 0x01
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t displayId;
|
enum {
|
||||||
|
eSurfaceChanged = 0x1,
|
||||||
|
eLayerStackChanged = 0x2,
|
||||||
|
eTransformChanged = 0x4
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t what;
|
||||||
|
sp<IBinder> token;
|
||||||
sp<ISurfaceTexture> surface;
|
sp<ISurfaceTexture> surface;
|
||||||
uint32_t layerStack;
|
uint32_t layerStack;
|
||||||
uint32_t orientation;
|
uint32_t orientation;
|
||||||
Rect viewport;
|
Rect viewport;
|
||||||
Rect frame;
|
Rect frame;
|
||||||
status_t write(Parcel& output) const;
|
status_t write(Parcel& output) const;
|
||||||
status_t read(const Parcel& input);
|
status_t read(const Parcel& input);
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|
|
@ -179,6 +179,23 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual sp<IBinder> createDisplay()
|
||||||
|
{
|
||||||
|
Parcel data, reply;
|
||||||
|
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
|
||||||
|
remote()->transact(BnSurfaceComposer::CREATE_DISPLAY, data, &reply);
|
||||||
|
return reply.readStrongBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual sp<IBinder> getBuiltInDisplay(int32_t id)
|
||||||
|
{
|
||||||
|
Parcel data, reply;
|
||||||
|
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
|
||||||
|
data.writeInt32(id);
|
||||||
|
remote()->transact(BnSurfaceComposer::GET_BUILT_IN_DISPLAY, data, &reply);
|
||||||
|
return reply.readStrongBinder();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void blank()
|
virtual void blank()
|
||||||
{
|
{
|
||||||
Parcel data, reply;
|
Parcel data, reply;
|
||||||
|
@ -286,6 +303,19 @@ status_t BnSurfaceComposer::onTransact(
|
||||||
reply->writeStrongBinder(connection->asBinder());
|
reply->writeStrongBinder(connection->asBinder());
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
} break;
|
} break;
|
||||||
|
case CREATE_DISPLAY: {
|
||||||
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
|
sp<IBinder> display(createDisplay());
|
||||||
|
reply->writeStrongBinder(display);
|
||||||
|
return NO_ERROR;
|
||||||
|
} break;
|
||||||
|
case GET_BUILT_IN_DISPLAY: {
|
||||||
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
|
int32_t id = data.readInt32();
|
||||||
|
sp<IBinder> display(getBuiltInDisplay(id));
|
||||||
|
reply->writeStrongBinder(display);
|
||||||
|
return NO_ERROR;
|
||||||
|
} break;
|
||||||
case BLANK: {
|
case BLANK: {
|
||||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
blank();
|
blank();
|
||||||
|
|
|
@ -72,8 +72,9 @@ status_t ComposerState::read(const Parcel& input) {
|
||||||
|
|
||||||
|
|
||||||
status_t DisplayState::write(Parcel& output) const {
|
status_t DisplayState::write(Parcel& output) const {
|
||||||
|
output.writeStrongBinder(token);
|
||||||
output.writeStrongBinder(surface->asBinder());
|
output.writeStrongBinder(surface->asBinder());
|
||||||
output.writeInt32(displayId);
|
output.writeInt32(what);
|
||||||
output.writeInt32(layerStack);
|
output.writeInt32(layerStack);
|
||||||
output.writeInt32(orientation);
|
output.writeInt32(orientation);
|
||||||
memcpy(output.writeInplace(sizeof(Rect)), &viewport, sizeof(Rect));
|
memcpy(output.writeInplace(sizeof(Rect)), &viewport, sizeof(Rect));
|
||||||
|
@ -82,8 +83,9 @@ status_t DisplayState::write(Parcel& output) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t DisplayState::read(const Parcel& input) {
|
status_t DisplayState::read(const Parcel& input) {
|
||||||
|
token = input.readStrongBinder();
|
||||||
surface = interface_cast<ISurfaceTexture>(input.readStrongBinder());
|
surface = interface_cast<ISurfaceTexture>(input.readStrongBinder());
|
||||||
displayId = input.readInt32();
|
what = input.readInt32();
|
||||||
layerStack = input.readInt32();
|
layerStack = input.readInt32();
|
||||||
orientation = input.readInt32();
|
orientation = input.readInt32();
|
||||||
memcpy(&viewport, input.readInplace(sizeof(Rect)), sizeof(Rect));
|
memcpy(&viewport, input.readInplace(sizeof(Rect)), sizeof(Rect));
|
||||||
|
|
|
@ -56,16 +56,10 @@ sp<ISurfaceComposer> ComposerService::getComposerService() {
|
||||||
return ComposerService::getInstance().mComposerService;
|
return ComposerService::getInstance().mComposerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline sp<ISurfaceComposer> getComposerService() {
|
|
||||||
return ComposerService::getComposerService();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// NOTE: this is NOT a member function (it's a friend defined with its
|
|
||||||
// declaration).
|
|
||||||
static inline
|
static inline
|
||||||
int compare_type( const ComposerState& lhs, const ComposerState& rhs) {
|
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.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;
|
||||||
|
@ -73,17 +67,21 @@ int compare_type( const ComposerState& lhs, const ComposerState& rhs) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
int compare_type(const DisplayState& lhs, const DisplayState& rhs) {
|
||||||
|
return compare_type(lhs.token, rhs.token);
|
||||||
|
}
|
||||||
|
|
||||||
class Composer : public Singleton<Composer>
|
class Composer : public Singleton<Composer>
|
||||||
{
|
{
|
||||||
friend class Singleton<Composer>;
|
friend class Singleton<Composer>;
|
||||||
|
|
||||||
mutable Mutex mLock;
|
mutable Mutex mLock;
|
||||||
SortedVector<ComposerState> mStates;
|
SortedVector<ComposerState> mComposerStates;
|
||||||
int mOrientation;
|
SortedVector<DisplayState > mDisplayStates;
|
||||||
uint32_t mForceSynchronous;
|
uint32_t mForceSynchronous;
|
||||||
|
|
||||||
Composer() : Singleton<Composer>(),
|
Composer() : Singleton<Composer>(),
|
||||||
mOrientation(DisplayState::eOrientationUnchanged),
|
|
||||||
mForceSynchronous(0)
|
mForceSynchronous(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
@ -92,7 +90,10 @@ class Composer : public Singleton<Composer>
|
||||||
layer_state_t* getLayerStateLocked(
|
layer_state_t* getLayerStateLocked(
|
||||||
const sp<SurfaceComposerClient>& client, SurfaceID id);
|
const sp<SurfaceComposerClient>& client, SurfaceID id);
|
||||||
|
|
||||||
|
DisplayState& getDisplayStateLocked(const sp<IBinder>& token);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
sp<IBinder> createDisplay();
|
||||||
|
|
||||||
status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
|
status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
|
||||||
float x, float y);
|
float x, float y);
|
||||||
|
@ -115,6 +116,12 @@ public:
|
||||||
status_t setLayerStack(const sp<SurfaceComposerClient>& client,
|
status_t setLayerStack(const sp<SurfaceComposerClient>& client,
|
||||||
SurfaceID id, uint32_t layerStack);
|
SurfaceID id, uint32_t layerStack);
|
||||||
|
|
||||||
|
void setDisplaySurface(const sp<IBinder>& token, const sp<ISurfaceTexture>& surface);
|
||||||
|
void setDisplayLayerStack(const sp<IBinder>& token, uint32_t layerStack);
|
||||||
|
void setDisplayOrientation(const sp<IBinder>& token, uint32_t orientation);
|
||||||
|
void setDisplayViewport(const sp<IBinder>& token, const Rect& viewport);
|
||||||
|
void setDisplayFrame(const sp<IBinder>& token, const Rect& frame);
|
||||||
|
|
||||||
static void closeGlobalTransaction(bool synchronous) {
|
static void closeGlobalTransaction(bool synchronous) {
|
||||||
Composer::getInstance().closeGlobalTransactionImpl(synchronous);
|
Composer::getInstance().closeGlobalTransactionImpl(synchronous);
|
||||||
}
|
}
|
||||||
|
@ -124,8 +131,12 @@ ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
sp<IBinder> Composer::createDisplay() {
|
||||||
|
return ComposerService::getComposerService()->createDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
void Composer::closeGlobalTransactionImpl(bool synchronous) {
|
void Composer::closeGlobalTransactionImpl(bool synchronous) {
|
||||||
sp<ISurfaceComposer> sm(getComposerService());
|
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
|
||||||
|
|
||||||
Vector<ComposerState> transaction;
|
Vector<ComposerState> transaction;
|
||||||
Vector<DisplayState> displayTransaction;
|
Vector<DisplayState> displayTransaction;
|
||||||
|
@ -133,15 +144,11 @@ void Composer::closeGlobalTransactionImpl(bool synchronous) {
|
||||||
|
|
||||||
{ // scope for the lock
|
{ // scope for the lock
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
transaction = mStates;
|
transaction = mComposerStates;
|
||||||
mStates.clear();
|
mComposerStates.clear();
|
||||||
|
|
||||||
// FIXME: this should be the displays transaction state here
|
displayTransaction = mDisplayStates;
|
||||||
DisplayState item;
|
mDisplayStates.clear();
|
||||||
item.orientation = mOrientation;
|
|
||||||
displayTransaction.add(item);
|
|
||||||
|
|
||||||
mOrientation = DisplayState::eOrientationUnchanged;
|
|
||||||
|
|
||||||
if (synchronous || mForceSynchronous) {
|
if (synchronous || mForceSynchronous) {
|
||||||
flags |= ISurfaceComposer::eSynchronous;
|
flags |= ISurfaceComposer::eSynchronous;
|
||||||
|
@ -159,13 +166,13 @@ layer_state_t* Composer::getLayerStateLocked(
|
||||||
s.client = client->mClient;
|
s.client = client->mClient;
|
||||||
s.state.surface = id;
|
s.state.surface = id;
|
||||||
|
|
||||||
ssize_t index = mStates.indexOf(s);
|
ssize_t index = mComposerStates.indexOf(s);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
// we don't have it, add an initialized layer_state to our list
|
// we don't have it, add an initialized layer_state to our list
|
||||||
index = mStates.add(s);
|
index = mComposerStates.add(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
ComposerState* const out = mStates.editArray();
|
ComposerState* const out = mComposerStates.editArray();
|
||||||
return &(out[index].state);
|
return &(out[index].state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,16 +280,6 @@ status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t Composer::setOrientation(int orientation) {
|
|
||||||
Mutex::Autolock _l(mLock);
|
|
||||||
mOrientation = orientation;
|
|
||||||
|
|
||||||
// Changing the orientation makes the transaction synchronous.
|
|
||||||
mForceSynchronous = true;
|
|
||||||
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t Composer::setCrop(const sp<SurfaceComposerClient>& client,
|
status_t Composer::setCrop(const sp<SurfaceComposerClient>& client,
|
||||||
SurfaceID id, const Rect& crop) {
|
SurfaceID id, const Rect& crop) {
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
|
@ -296,13 +293,76 @@ status_t Composer::setCrop(const sp<SurfaceComposerClient>& client,
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) {
|
||||||
|
DisplayState s;
|
||||||
|
s.token = token;
|
||||||
|
ssize_t index = mDisplayStates.indexOf(s);
|
||||||
|
if (index < 0) {
|
||||||
|
// we don't have it, add an initialized layer_state to our list
|
||||||
|
s.what = 0;
|
||||||
|
index = mDisplayStates.add(s);
|
||||||
|
}
|
||||||
|
return mDisplayStates.editItemAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Composer::setDisplaySurface(const sp<IBinder>& token,
|
||||||
|
const sp<ISurfaceTexture>& surface) {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
DisplayState& s(getDisplayStateLocked(token));
|
||||||
|
s.surface = surface;
|
||||||
|
s.what |= DisplayState::eSurfaceChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Composer::setDisplayLayerStack(const sp<IBinder>& token,
|
||||||
|
uint32_t layerStack) {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
DisplayState& s(getDisplayStateLocked(token));
|
||||||
|
s.layerStack = layerStack;
|
||||||
|
s.what |= DisplayState::eLayerStackChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Composer::setDisplayOrientation(const sp<IBinder>& token,
|
||||||
|
uint32_t orientation) {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
DisplayState& s(getDisplayStateLocked(token));
|
||||||
|
s.orientation = orientation;
|
||||||
|
s.what |= DisplayState::eTransformChanged;
|
||||||
|
mForceSynchronous = true; // TODO: do we actually still need this?
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: get rid of this eventually
|
||||||
|
status_t Composer::setOrientation(int orientation) {
|
||||||
|
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
|
||||||
|
sp<IBinder> token(sm->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
|
||||||
|
Composer::setDisplayOrientation(token, orientation);
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Composer::setDisplayViewport(const sp<IBinder>& token,
|
||||||
|
const Rect& viewport) {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
DisplayState& s(getDisplayStateLocked(token));
|
||||||
|
s.viewport = viewport;
|
||||||
|
s.what |= DisplayState::eTransformChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Composer::setDisplayFrame(const sp<IBinder>& token,
|
||||||
|
const Rect& frame) {
|
||||||
|
Mutex::Autolock _l(mLock);
|
||||||
|
DisplayState& s(getDisplayStateLocked(token));
|
||||||
|
s.frame = frame;
|
||||||
|
s.what |= DisplayState::eTransformChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
SurfaceComposerClient::SurfaceComposerClient()
|
SurfaceComposerClient::SurfaceComposerClient()
|
||||||
: mStatus(NO_INIT), mComposer(Composer::getInstance())
|
: mStatus(NO_INIT), mComposer(Composer::getInstance())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceComposerClient::onFirstRef() {
|
void SurfaceComposerClient::onFirstRef() {
|
||||||
sp<ISurfaceComposer> sm(getComposerService());
|
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
|
||||||
if (sm != 0) {
|
if (sm != 0) {
|
||||||
sp<ISurfaceComposerClient> conn = sm->createConnection();
|
sp<ISurfaceComposerClient> conn = sm->createConnection();
|
||||||
if (conn != 0) {
|
if (conn != 0) {
|
||||||
|
@ -327,7 +387,7 @@ sp<IBinder> SurfaceComposerClient::connection() const {
|
||||||
status_t SurfaceComposerClient::linkToComposerDeath(
|
status_t SurfaceComposerClient::linkToComposerDeath(
|
||||||
const sp<IBinder::DeathRecipient>& recipient,
|
const sp<IBinder::DeathRecipient>& recipient,
|
||||||
void* cookie, uint32_t flags) {
|
void* cookie, uint32_t flags) {
|
||||||
sp<ISurfaceComposer> sm(getComposerService());
|
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
|
||||||
return sm->asBinder()->linkToDeath(recipient, cookie, flags);
|
return sm->asBinder()->linkToDeath(recipient, cookie, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,6 +439,10 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sp<IBinder> SurfaceComposerClient::createDisplay() {
|
||||||
|
return Composer::getInstance().createDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
|
status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
|
||||||
if (mStatus != NO_ERROR)
|
if (mStatus != NO_ERROR)
|
||||||
return mStatus;
|
return mStatus;
|
||||||
|
@ -461,10 +525,37 @@ status_t SurfaceComposerClient::setOrientation(DisplayID dpy,
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token,
|
||||||
|
const sp<ISurfaceTexture>& surface) {
|
||||||
|
Composer::getInstance().setDisplaySurface(token, surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceComposerClient::setDisplayLayerStack(const sp<IBinder>& token,
|
||||||
|
uint32_t layerStack) {
|
||||||
|
Composer::getInstance().setDisplayLayerStack(token, layerStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceComposerClient::setDisplayOrientation(const sp<IBinder>& token,
|
||||||
|
uint32_t orientation) {
|
||||||
|
Composer::getInstance().setDisplayOrientation(token, orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceComposerClient::setDisplayViewport(const sp<IBinder>& token,
|
||||||
|
const Rect& viewport) {
|
||||||
|
Composer::getInstance().setDisplayViewport(token, viewport);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceComposerClient::setDisplayFrame(const sp<IBinder>& token,
|
||||||
|
const Rect& frame) {
|
||||||
|
Composer::getInstance().setDisplayFrame(token, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
status_t SurfaceComposerClient::getDisplayInfo(
|
status_t SurfaceComposerClient::getDisplayInfo(
|
||||||
DisplayID dpy, DisplayInfo* info)
|
DisplayID dpy, DisplayInfo* info)
|
||||||
{
|
{
|
||||||
return getComposerService()->getDisplayInfo(dpy, info);
|
return ComposerService::getComposerService()->getDisplayInfo(dpy, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -51,7 +51,8 @@ public:
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DISPLAY_ID_MAIN = 0,
|
DISPLAY_ID_MAIN = 0,
|
||||||
DISPLAY_ID_HDMI = 1
|
DISPLAY_ID_HDMI = 1,
|
||||||
|
DISPLAY_ID_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -161,6 +161,39 @@ sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
|
||||||
return bclient;
|
return bclient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sp<IBinder> SurfaceFlinger::createDisplay()
|
||||||
|
{
|
||||||
|
class DisplayToken : public BBinder {
|
||||||
|
sp<SurfaceFlinger> flinger;
|
||||||
|
virtual ~DisplayToken() {
|
||||||
|
// no more references, this display must be terminated
|
||||||
|
Mutex::Autolock _l(flinger->mStateLock);
|
||||||
|
flinger->mCurrentState.displays.removeItem(this);
|
||||||
|
flinger->setTransactionFlags(eDisplayTransactionNeeded);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
DisplayToken(const sp<SurfaceFlinger>& flinger)
|
||||||
|
: flinger(flinger) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sp<BBinder> token = new DisplayToken(this);
|
||||||
|
|
||||||
|
Mutex::Autolock _l(mStateLock);
|
||||||
|
DisplayDeviceState info(intptr_t(token.get())); // FIXME: we shouldn't use the address for the id
|
||||||
|
mCurrentState.displays.add(token, info);
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) {
|
||||||
|
if (uint32_t(id) >= DisplayDevice::DISPLAY_ID_COUNT) {
|
||||||
|
ALOGE("getDefaultDisplay: id=%d is not a valid default display id", id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return mDefaultDisplays[id];
|
||||||
|
}
|
||||||
|
|
||||||
sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
|
sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
|
||||||
{
|
{
|
||||||
sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
|
sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
|
||||||
|
@ -358,7 +391,8 @@ status_t SurfaceFlinger::readyToRun()
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
sp<SurfaceTextureClient> stc(new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(fbs->getBufferQueue())));
|
sp<SurfaceTextureClient> stc(new SurfaceTextureClient(
|
||||||
|
static_cast<sp<ISurfaceTexture> >(fbs->getBufferQueue())));
|
||||||
|
|
||||||
// initialize the config and context
|
// initialize the config and context
|
||||||
int format;
|
int format;
|
||||||
|
@ -368,9 +402,14 @@ status_t SurfaceFlinger::readyToRun()
|
||||||
mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
|
mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
|
||||||
|
|
||||||
// initialize our main display hardware
|
// initialize our main display hardware
|
||||||
mCurrentState.displays.add(DisplayDevice::DISPLAY_ID_MAIN, DisplayDeviceState());
|
|
||||||
sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_ID_MAIN, anw, fbs, mEGLConfig);
|
for (size_t i=0 ; i<DisplayDevice::DISPLAY_ID_COUNT ; i++) {
|
||||||
mDisplays.add(DisplayDevice::DISPLAY_ID_MAIN, hw);
|
mDefaultDisplays[i] = new BBinder();
|
||||||
|
mCurrentState.displays.add(mDefaultDisplays[i], DisplayDeviceState(i));
|
||||||
|
}
|
||||||
|
sp<DisplayDevice> hw = new DisplayDevice(this,
|
||||||
|
DisplayDevice::DISPLAY_ID_MAIN, anw, fbs, mEGLConfig);
|
||||||
|
mDisplays.add(hw->getDisplayId(), hw);
|
||||||
|
|
||||||
// initialize OpenGL ES
|
// initialize OpenGL ES
|
||||||
EGLSurface surface = hw->getEGLSurface();
|
EGLSurface surface = hw->getEGLSurface();
|
||||||
|
@ -571,8 +610,7 @@ void SurfaceFlinger::onMessageReceived(int32_t what) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::handleMessageTransaction() {
|
void SurfaceFlinger::handleMessageTransaction() {
|
||||||
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
|
uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
|
||||||
uint32_t transactionFlags = peekTransactionFlags(mask);
|
|
||||||
if (transactionFlags) {
|
if (transactionFlags) {
|
||||||
handleTransaction(transactionFlags);
|
handleTransaction(transactionFlags);
|
||||||
}
|
}
|
||||||
|
@ -795,8 +833,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
|
||||||
// with mStateLock held to guarantee that mCurrentState won't change
|
// with mStateLock held to guarantee that mCurrentState won't change
|
||||||
// until the transaction is committed.
|
// until the transaction is committed.
|
||||||
|
|
||||||
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
|
transactionFlags = getTransactionFlags(eTransactionMask);
|
||||||
transactionFlags = getTransactionFlags(mask);
|
|
||||||
handleTransactionLocked(transactionFlags);
|
handleTransactionLocked(transactionFlags);
|
||||||
|
|
||||||
mLastTransactionTime = systemTime() - now;
|
mLastTransactionTime = systemTime() - now;
|
||||||
|
@ -832,12 +869,12 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
||||||
* Perform our own transaction if needed
|
* Perform our own transaction if needed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (transactionFlags & eTransactionNeeded) {
|
if (transactionFlags & eDisplayTransactionNeeded) {
|
||||||
// here we take advantage of Vector's copy-on-write semantics to
|
// here we take advantage of Vector's copy-on-write semantics to
|
||||||
// improve performance by skipping the transaction entirely when
|
// improve performance by skipping the transaction entirely when
|
||||||
// know that the lists are identical
|
// know that the lists are identical
|
||||||
const KeyedVector<int32_t, DisplayDeviceState>& curr(mCurrentState.displays);
|
const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
|
||||||
const KeyedVector<int32_t, DisplayDeviceState>& draw(mDrawingState.displays);
|
const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
|
||||||
if (!curr.isIdenticalTo(draw)) {
|
if (!curr.isIdenticalTo(draw)) {
|
||||||
mVisibleRegionsDirty = true;
|
mVisibleRegionsDirty = true;
|
||||||
const size_t cc = curr.size();
|
const size_t cc = curr.size();
|
||||||
|
@ -848,7 +885,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
||||||
// also handle displays that changed
|
// also handle displays that changed
|
||||||
// (ie: displays that are in both lists)
|
// (ie: displays that are in both lists)
|
||||||
for (size_t i=0 ; i<dc ; i++) {
|
for (size_t i=0 ; i<dc ; i++) {
|
||||||
if (curr.indexOfKey(draw[i].id) < 0) {
|
const ssize_t j = curr.indexOfKey(draw.keyAt(i));
|
||||||
|
if (j < 0) {
|
||||||
// in drawing state but not in current state
|
// in drawing state but not in current state
|
||||||
if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) {
|
if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) {
|
||||||
mDisplays.removeItem(draw[i].id);
|
mDisplays.removeItem(draw[i].id);
|
||||||
|
@ -857,14 +895,32 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// this display is in both lists. see if something changed.
|
// this display is in both lists. see if something changed.
|
||||||
const DisplayDeviceState& state(curr[i]);
|
const DisplayDeviceState& state(curr[j]);
|
||||||
|
if (state.surface != draw[i].surface) {
|
||||||
|
// changing the surface is like destroying and
|
||||||
|
// recreating the DisplayDevice
|
||||||
|
|
||||||
|
sp<SurfaceTextureClient> stc(
|
||||||
|
new SurfaceTextureClient(state.surface));
|
||||||
|
|
||||||
|
sp<DisplayDevice> disp = new DisplayDevice(this,
|
||||||
|
state.id, stc, 0, mEGLConfig);
|
||||||
|
|
||||||
|
disp->setLayerStack(state.layerStack);
|
||||||
|
disp->setOrientation(state.orientation);
|
||||||
|
// TODO: take viewport and frame into account
|
||||||
|
mDisplays.replaceValueFor(state.id, disp);
|
||||||
|
}
|
||||||
if (state.layerStack != draw[i].layerStack) {
|
if (state.layerStack != draw[i].layerStack) {
|
||||||
const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
|
const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
|
||||||
disp->setLayerStack(state.layerStack);
|
disp->setLayerStack(state.layerStack);
|
||||||
}
|
}
|
||||||
if (curr[i].orientation != draw[i].orientation) {
|
if (state.orientation != draw[i].orientation ||
|
||||||
|
state.viewport != draw[i].viewport ||
|
||||||
|
state.frame != draw[i].frame) {
|
||||||
const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
|
const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
|
||||||
disp->setOrientation(state.orientation);
|
disp->setOrientation(state.orientation);
|
||||||
|
// TODO: take viewport and frame into account
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -872,10 +928,14 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
||||||
// find displays that were added
|
// find displays that were added
|
||||||
// (ie: in current state but not in drawing state)
|
// (ie: in current state but not in drawing state)
|
||||||
for (size_t i=0 ; i<cc ; i++) {
|
for (size_t i=0 ; i<cc ; i++) {
|
||||||
if (mDrawingState.displays.indexOfKey(curr[i].id) < 0) {
|
if (draw.indexOfKey(curr.keyAt(i)) < 0) {
|
||||||
// FIXME: we need to pass the surface here
|
// FIXME: we need to pass the surface here
|
||||||
sp<DisplayDevice> disp = new DisplayDevice(this, curr[i].id, 0, 0, mEGLConfig);
|
const DisplayDeviceState& state(curr[i]);
|
||||||
mDisplays.add(curr[i].id, disp);
|
sp<SurfaceTextureClient> stc(
|
||||||
|
new SurfaceTextureClient(state.surface));
|
||||||
|
sp<DisplayDevice> disp = new DisplayDevice(this, state.id,
|
||||||
|
stc, 0, mEGLConfig);
|
||||||
|
mDisplays.add(state.id, disp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1358,33 +1418,21 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SurfaceFlinger::setTransactionState(
|
void SurfaceFlinger::setTransactionState(
|
||||||
const Vector<ComposerState>& state,
|
const Vector<ComposerState>& state,
|
||||||
const Vector<DisplayState>& displays,
|
const Vector<DisplayState>& displays,
|
||||||
uint32_t flags)
|
uint32_t flags)
|
||||||
{
|
{
|
||||||
Mutex::Autolock _l(mStateLock);
|
Mutex::Autolock _l(mStateLock);
|
||||||
|
|
||||||
int orientation = DisplayState::eOrientationUnchanged;
|
|
||||||
if (displays.size()) {
|
|
||||||
// TODO: handle all displays
|
|
||||||
orientation = displays[0].orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t transactionFlags = 0;
|
uint32_t transactionFlags = 0;
|
||||||
// FIXME: don't hardcode display id here
|
|
||||||
if (mCurrentState.displays.valueFor(0).orientation != orientation) {
|
size_t count = displays.size();
|
||||||
if (uint32_t(orientation) <= DisplayState::eOrientation270) {
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
mCurrentState.displays.editValueFor(0).orientation = orientation;
|
const DisplayState& s(displays[i]);
|
||||||
transactionFlags |= eTransactionNeeded;
|
transactionFlags |= setDisplayStateLocked(s);
|
||||||
} else if (orientation != DisplayState::eOrientationUnchanged) {
|
|
||||||
ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
|
|
||||||
orientation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t count = state.size();
|
count = state.size();
|
||||||
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()) );
|
||||||
|
@ -1413,6 +1461,105 @@ void SurfaceFlinger::setTransactionState(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
|
||||||
|
{
|
||||||
|
uint32_t flags = 0;
|
||||||
|
DisplayDeviceState& disp(mCurrentState.displays.editValueFor(s.token));
|
||||||
|
if (disp.id >= 0) {
|
||||||
|
const uint32_t what = s.what;
|
||||||
|
if (what & DisplayState::eSurfaceChanged) {
|
||||||
|
if (disp.surface->asBinder() != s.surface->asBinder()) {
|
||||||
|
disp.surface = s.surface;
|
||||||
|
flags |= eDisplayTransactionNeeded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (what & DisplayState::eLayerStackChanged) {
|
||||||
|
if (disp.layerStack != s.layerStack) {
|
||||||
|
disp.layerStack = s.layerStack;
|
||||||
|
flags |= eDisplayTransactionNeeded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (what & DisplayState::eTransformChanged) {
|
||||||
|
if (disp.orientation != s.orientation) {
|
||||||
|
disp.orientation = s.orientation;
|
||||||
|
flags |= eDisplayTransactionNeeded;
|
||||||
|
}
|
||||||
|
if (disp.frame != s.frame) {
|
||||||
|
disp.frame = s.frame;
|
||||||
|
flags |= eDisplayTransactionNeeded;
|
||||||
|
}
|
||||||
|
if (disp.viewport != s.viewport) {
|
||||||
|
disp.viewport = s.viewport;
|
||||||
|
flags |= eDisplayTransactionNeeded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SurfaceFlinger::setClientStateLocked(
|
||||||
|
const sp<Client>& client,
|
||||||
|
const layer_state_t& s)
|
||||||
|
{
|
||||||
|
uint32_t flags = 0;
|
||||||
|
sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
|
||||||
|
if (layer != 0) {
|
||||||
|
const uint32_t what = s.what;
|
||||||
|
if (what & layer_state_t::ePositionChanged) {
|
||||||
|
if (layer->setPosition(s.x, s.y))
|
||||||
|
flags |= eTraversalNeeded;
|
||||||
|
}
|
||||||
|
if (what & layer_state_t::eLayerChanged) {
|
||||||
|
// NOTE: index needs to be calculated before we update the state
|
||||||
|
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 & layer_state_t::eSizeChanged) {
|
||||||
|
if (layer->setSize(s.w, s.h)) {
|
||||||
|
flags |= eTraversalNeeded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (what & layer_state_t::eAlphaChanged) {
|
||||||
|
if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
|
||||||
|
flags |= eTraversalNeeded;
|
||||||
|
}
|
||||||
|
if (what & layer_state_t::eMatrixChanged) {
|
||||||
|
if (layer->setMatrix(s.matrix))
|
||||||
|
flags |= eTraversalNeeded;
|
||||||
|
}
|
||||||
|
if (what & layer_state_t::eTransparentRegionChanged) {
|
||||||
|
if (layer->setTransparentRegionHint(s.transparentRegion))
|
||||||
|
flags |= eTraversalNeeded;
|
||||||
|
}
|
||||||
|
if (what & layer_state_t::eVisibilityChanged) {
|
||||||
|
if (layer->setFlags(s.flags, s.mask))
|
||||||
|
flags |= eTraversalNeeded;
|
||||||
|
}
|
||||||
|
if (what & layer_state_t::eCropChanged) {
|
||||||
|
if (layer->setCrop(s.crop))
|
||||||
|
flags |= eTraversalNeeded;
|
||||||
|
}
|
||||||
|
if (what & layer_state_t::eLayerStackChanged) {
|
||||||
|
// NOTE: index needs to be calculated before we update the state
|
||||||
|
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
|
||||||
|
if (layer->setLayerStack(s.layerStack)) {
|
||||||
|
mCurrentState.layersSortedByZ.removeAt(idx);
|
||||||
|
mCurrentState.layersSortedByZ.add(layer);
|
||||||
|
// we need traversal (state changed)
|
||||||
|
// AND transaction (list changed)
|
||||||
|
flags |= eTransactionNeeded|eTraversalNeeded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
sp<ISurface> SurfaceFlinger::createLayer(
|
sp<ISurface> SurfaceFlinger::createLayer(
|
||||||
ISurfaceComposerClient::surface_data_t* params,
|
ISurfaceComposerClient::surface_data_t* params,
|
||||||
const String8& name,
|
const String8& name,
|
||||||
|
@ -1554,69 +1701,6 @@ status_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SurfaceFlinger::setClientStateLocked(
|
|
||||||
const sp<Client>& client,
|
|
||||||
const layer_state_t& s)
|
|
||||||
{
|
|
||||||
uint32_t flags = 0;
|
|
||||||
sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
|
|
||||||
if (layer != 0) {
|
|
||||||
const uint32_t what = s.what;
|
|
||||||
if (what & layer_state_t::ePositionChanged) {
|
|
||||||
if (layer->setPosition(s.x, s.y))
|
|
||||||
flags |= eTraversalNeeded;
|
|
||||||
}
|
|
||||||
if (what & layer_state_t::eLayerChanged) {
|
|
||||||
// NOTE: index needs to be calculated before we update the state
|
|
||||||
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 & layer_state_t::eSizeChanged) {
|
|
||||||
if (layer->setSize(s.w, s.h)) {
|
|
||||||
flags |= eTraversalNeeded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (what & layer_state_t::eAlphaChanged) {
|
|
||||||
if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
|
|
||||||
flags |= eTraversalNeeded;
|
|
||||||
}
|
|
||||||
if (what & layer_state_t::eMatrixChanged) {
|
|
||||||
if (layer->setMatrix(s.matrix))
|
|
||||||
flags |= eTraversalNeeded;
|
|
||||||
}
|
|
||||||
if (what & layer_state_t::eTransparentRegionChanged) {
|
|
||||||
if (layer->setTransparentRegionHint(s.transparentRegion))
|
|
||||||
flags |= eTraversalNeeded;
|
|
||||||
}
|
|
||||||
if (what & layer_state_t::eVisibilityChanged) {
|
|
||||||
if (layer->setFlags(s.flags, s.mask))
|
|
||||||
flags |= eTraversalNeeded;
|
|
||||||
}
|
|
||||||
if (what & layer_state_t::eCropChanged) {
|
|
||||||
if (layer->setCrop(s.crop))
|
|
||||||
flags |= eTraversalNeeded;
|
|
||||||
}
|
|
||||||
if (what & layer_state_t::eLayerStackChanged) {
|
|
||||||
// NOTE: index needs to be calculated before we update the state
|
|
||||||
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
|
|
||||||
if (layer->setLayerStack(s.layerStack)) {
|
|
||||||
mCurrentState.layersSortedByZ.removeAt(idx);
|
|
||||||
mCurrentState.layersSortedByZ.add(layer);
|
|
||||||
// we need traversal (state changed)
|
|
||||||
// AND transaction (list changed)
|
|
||||||
flags |= eTransactionNeeded|eTraversalNeeded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
void SurfaceFlinger::onScreenAcquired() {
|
void SurfaceFlinger::onScreenAcquired() {
|
||||||
|
@ -1964,7 +2048,10 @@ status_t SurfaceFlinger::onTransact(
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
case 1005:{ // force transaction
|
case 1005:{ // force transaction
|
||||||
setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
|
setTransactionFlags(
|
||||||
|
eTransactionNeeded|
|
||||||
|
eDisplayTransactionNeeded|
|
||||||
|
eTraversalNeeded);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
case 1006:{ // send empty update
|
case 1006:{ // send empty update
|
||||||
|
@ -2305,8 +2392,11 @@ int SurfaceFlinger::LayerVector::do_compare(const void* lhs,
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
|
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState() : id(-1) {
|
||||||
: id(DisplayDevice::DISPLAY_ID_MAIN), layerStack(0), orientation(0) {
|
}
|
||||||
|
|
||||||
|
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(int32_t id)
|
||||||
|
: id(id), layerStack(0), orientation(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -78,7 +78,10 @@ public:
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
eTransactionNeeded = 0x01, eTraversalNeeded = 0x02
|
eTransactionNeeded = 0x01,
|
||||||
|
eTraversalNeeded = 0x02,
|
||||||
|
eDisplayTransactionNeeded = 0x04,
|
||||||
|
eTransactionMask = 0x07
|
||||||
};
|
};
|
||||||
|
|
||||||
class SurfaceFlinger : public BinderService<SurfaceFlinger>,
|
class SurfaceFlinger : public BinderService<SurfaceFlinger>,
|
||||||
|
@ -158,19 +161,18 @@ private:
|
||||||
|
|
||||||
struct DisplayDeviceState {
|
struct DisplayDeviceState {
|
||||||
DisplayDeviceState();
|
DisplayDeviceState();
|
||||||
|
DisplayDeviceState(int32_t id);
|
||||||
int32_t id;
|
int32_t id;
|
||||||
|
sp<ISurfaceTexture> surface;
|
||||||
uint32_t layerStack;
|
uint32_t layerStack;
|
||||||
Rect viewport;
|
Rect viewport;
|
||||||
Rect frame;
|
Rect frame;
|
||||||
uint8_t orientation;
|
uint8_t orientation;
|
||||||
inline bool operator < (const DisplayDeviceState& rhs) const {
|
|
||||||
return id < rhs.id;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
LayerVector layersSortedByZ;
|
LayerVector layersSortedByZ;
|
||||||
KeyedVector<int32_t, DisplayDeviceState> displays;
|
DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
|
@ -185,6 +187,8 @@ private:
|
||||||
*/
|
*/
|
||||||
virtual sp<ISurfaceComposerClient> createConnection();
|
virtual sp<ISurfaceComposerClient> createConnection();
|
||||||
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc();
|
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc();
|
||||||
|
virtual sp<IBinder> createDisplay();
|
||||||
|
virtual sp<IBinder> getBuiltInDisplay(int32_t id);
|
||||||
virtual void setTransactionState(const Vector<ComposerState>& state,
|
virtual void setTransactionState(const Vector<ComposerState>& state,
|
||||||
const Vector<DisplayState>& displays, uint32_t flags);
|
const Vector<DisplayState>& displays, uint32_t flags);
|
||||||
virtual void bootFinished();
|
virtual void bootFinished();
|
||||||
|
@ -256,6 +260,7 @@ private:
|
||||||
void commitTransaction();
|
void commitTransaction();
|
||||||
uint32_t setClientStateLocked(const sp<Client>& client,
|
uint32_t setClientStateLocked(const sp<Client>& client,
|
||||||
const layer_state_t& s);
|
const layer_state_t& s);
|
||||||
|
uint32_t setDisplayStateLocked(const DisplayState& s);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
* Layer management
|
* Layer management
|
||||||
|
@ -391,6 +396,7 @@ private:
|
||||||
EGLContext mEGLContext;
|
EGLContext mEGLContext;
|
||||||
EGLConfig mEGLConfig;
|
EGLConfig mEGLConfig;
|
||||||
EGLDisplay mEGLDisplay;
|
EGLDisplay mEGLDisplay;
|
||||||
|
sp<IBinder> mDefaultDisplays[DisplayDevice::DISPLAY_ID_COUNT];
|
||||||
|
|
||||||
// Can only accessed from the main thread, these members
|
// Can only accessed from the main thread, these members
|
||||||
// don't need synchronization
|
// don't need synchronization
|
||||||
|
|
Loading…
Reference in New Issue