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,
|
||||
};
|
||||
|
||||
enum {
|
||||
eDisplayIdMain = 0,
|
||||
eDisplayIdHdmi = 1
|
||||
};
|
||||
|
||||
/* create connection with surface flinger, requires
|
||||
* ACCESS_SURFACE_FLINGER permission
|
||||
*/
|
||||
@ -57,6 +62,19 @@ public:
|
||||
*/
|
||||
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 */
|
||||
virtual void setTransactionState(const Vector<ComposerState>& state,
|
||||
const Vector<DisplayState>& displays, uint32_t flags) = 0;
|
||||
@ -66,6 +84,11 @@ public:
|
||||
*/
|
||||
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
|
||||
* 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 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 */
|
||||
virtual void blank() = 0;
|
||||
@ -106,13 +122,15 @@ public:
|
||||
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
|
||||
CREATE_CONNECTION,
|
||||
CREATE_GRAPHIC_BUFFER_ALLOC,
|
||||
GET_DISPLAY_INFO,
|
||||
SET_TRANSACTION_STATE,
|
||||
CAPTURE_SCREEN,
|
||||
AUTHENTICATE_SURFACE,
|
||||
CREATE_DISPLAY_EVENT_CONNECTION,
|
||||
CREATE_DISPLAY,
|
||||
GET_BUILT_IN_DISPLAY,
|
||||
SET_TRANSACTION_STATE,
|
||||
AUTHENTICATE_SURFACE,
|
||||
CAPTURE_SCREEN,
|
||||
BLANK,
|
||||
UNBLANK,
|
||||
GET_DISPLAY_INFO,
|
||||
CONNECT_DISPLAY,
|
||||
};
|
||||
|
||||
|
@ -59,6 +59,13 @@ public:
|
||||
// Forcibly remove connection before all references have gone away.
|
||||
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
|
||||
|
||||
@ -80,13 +87,14 @@ public:
|
||||
uint32_t flags = 0 // usage flags
|
||||
);
|
||||
|
||||
static sp<IBinder> createDisplay();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Composer parameters
|
||||
// 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.
|
||||
// closeGlobalTransaction() usually requires an IPC with the server.
|
||||
// closeGlobalTransaction() requires an IPC with the server.
|
||||
|
||||
//! Open a composer transaction on all active SurfaceComposerClients.
|
||||
static void openGlobalTransaction();
|
||||
@ -97,12 +105,6 @@ public:
|
||||
//! Set the orientation of the given display
|
||||
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 show(SurfaceID id, int32_t layer = -1);
|
||||
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 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:
|
||||
virtual void onFirstRef();
|
||||
Composer& getComposer();
|
||||
|
@ -106,14 +106,21 @@ struct DisplayState {
|
||||
eOrientationSwapMask = 0x01
|
||||
};
|
||||
|
||||
int32_t displayId;
|
||||
enum {
|
||||
eSurfaceChanged = 0x1,
|
||||
eLayerStackChanged = 0x2,
|
||||
eTransformChanged = 0x4
|
||||
};
|
||||
|
||||
uint32_t what;
|
||||
sp<IBinder> token;
|
||||
sp<ISurfaceTexture> surface;
|
||||
uint32_t layerStack;
|
||||
uint32_t orientation;
|
||||
Rect viewport;
|
||||
Rect frame;
|
||||
status_t write(Parcel& output) const;
|
||||
status_t read(const Parcel& input);
|
||||
uint32_t layerStack;
|
||||
uint32_t orientation;
|
||||
Rect viewport;
|
||||
Rect frame;
|
||||
status_t write(Parcel& output) const;
|
||||
status_t read(const Parcel& input);
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
@ -179,6 +179,23 @@ public:
|
||||
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()
|
||||
{
|
||||
Parcel data, reply;
|
||||
@ -286,6 +303,19 @@ status_t BnSurfaceComposer::onTransact(
|
||||
reply->writeStrongBinder(connection->asBinder());
|
||||
return NO_ERROR;
|
||||
} 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: {
|
||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||
blank();
|
||||
|
@ -72,8 +72,9 @@ status_t ComposerState::read(const Parcel& input) {
|
||||
|
||||
|
||||
status_t DisplayState::write(Parcel& output) const {
|
||||
output.writeStrongBinder(token);
|
||||
output.writeStrongBinder(surface->asBinder());
|
||||
output.writeInt32(displayId);
|
||||
output.writeInt32(what);
|
||||
output.writeInt32(layerStack);
|
||||
output.writeInt32(orientation);
|
||||
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) {
|
||||
token = input.readStrongBinder();
|
||||
surface = interface_cast<ISurfaceTexture>(input.readStrongBinder());
|
||||
displayId = input.readInt32();
|
||||
what = input.readInt32();
|
||||
layerStack = input.readInt32();
|
||||
orientation = input.readInt32();
|
||||
memcpy(&viewport, input.readInplace(sizeof(Rect)), sizeof(Rect));
|
||||
|
@ -56,16 +56,10 @@ sp<ISurfaceComposer> ComposerService::getComposerService() {
|
||||
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
|
||||
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.state.surface < rhs.state.surface) return -1;
|
||||
@ -73,17 +67,21 @@ int compare_type( const ComposerState& lhs, const ComposerState& rhs) {
|
||||
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>
|
||||
{
|
||||
friend class Singleton<Composer>;
|
||||
|
||||
mutable Mutex mLock;
|
||||
SortedVector<ComposerState> mStates;
|
||||
int mOrientation;
|
||||
SortedVector<ComposerState> mComposerStates;
|
||||
SortedVector<DisplayState > mDisplayStates;
|
||||
uint32_t mForceSynchronous;
|
||||
|
||||
Composer() : Singleton<Composer>(),
|
||||
mOrientation(DisplayState::eOrientationUnchanged),
|
||||
mForceSynchronous(0)
|
||||
{ }
|
||||
|
||||
@ -92,7 +90,10 @@ class Composer : public Singleton<Composer>
|
||||
layer_state_t* getLayerStateLocked(
|
||||
const sp<SurfaceComposerClient>& client, SurfaceID id);
|
||||
|
||||
DisplayState& getDisplayStateLocked(const sp<IBinder>& token);
|
||||
|
||||
public:
|
||||
sp<IBinder> createDisplay();
|
||||
|
||||
status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,
|
||||
float x, float y);
|
||||
@ -115,6 +116,12 @@ public:
|
||||
status_t setLayerStack(const sp<SurfaceComposerClient>& client,
|
||||
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) {
|
||||
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) {
|
||||
sp<ISurfaceComposer> sm(getComposerService());
|
||||
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
|
||||
|
||||
Vector<ComposerState> transaction;
|
||||
Vector<DisplayState> displayTransaction;
|
||||
@ -133,15 +144,11 @@ void Composer::closeGlobalTransactionImpl(bool synchronous) {
|
||||
|
||||
{ // scope for the lock
|
||||
Mutex::Autolock _l(mLock);
|
||||
transaction = mStates;
|
||||
mStates.clear();
|
||||
transaction = mComposerStates;
|
||||
mComposerStates.clear();
|
||||
|
||||
// FIXME: this should be the displays transaction state here
|
||||
DisplayState item;
|
||||
item.orientation = mOrientation;
|
||||
displayTransaction.add(item);
|
||||
|
||||
mOrientation = DisplayState::eOrientationUnchanged;
|
||||
displayTransaction = mDisplayStates;
|
||||
mDisplayStates.clear();
|
||||
|
||||
if (synchronous || mForceSynchronous) {
|
||||
flags |= ISurfaceComposer::eSynchronous;
|
||||
@ -159,13 +166,13 @@ layer_state_t* Composer::getLayerStateLocked(
|
||||
s.client = client->mClient;
|
||||
s.state.surface = id;
|
||||
|
||||
ssize_t index = mStates.indexOf(s);
|
||||
ssize_t index = mComposerStates.indexOf(s);
|
||||
if (index < 0) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
@ -273,16 +280,6 @@ status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
|
||||
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,
|
||||
SurfaceID id, const Rect& crop) {
|
||||
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()
|
||||
: mStatus(NO_INIT), mComposer(Composer::getInstance())
|
||||
{
|
||||
}
|
||||
|
||||
void SurfaceComposerClient::onFirstRef() {
|
||||
sp<ISurfaceComposer> sm(getComposerService());
|
||||
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
|
||||
if (sm != 0) {
|
||||
sp<ISurfaceComposerClient> conn = sm->createConnection();
|
||||
if (conn != 0) {
|
||||
@ -327,7 +387,7 @@ sp<IBinder> SurfaceComposerClient::connection() const {
|
||||
status_t SurfaceComposerClient::linkToComposerDeath(
|
||||
const sp<IBinder::DeathRecipient>& recipient,
|
||||
void* cookie, uint32_t flags) {
|
||||
sp<ISurfaceComposer> sm(getComposerService());
|
||||
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
|
||||
return sm->asBinder()->linkToDeath(recipient, cookie, flags);
|
||||
}
|
||||
|
||||
@ -379,6 +439,10 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(
|
||||
return result;
|
||||
}
|
||||
|
||||
sp<IBinder> SurfaceComposerClient::createDisplay() {
|
||||
return Composer::getInstance().createDisplay();
|
||||
}
|
||||
|
||||
status_t SurfaceComposerClient::destroySurface(SurfaceID sid) {
|
||||
if (mStatus != NO_ERROR)
|
||||
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(
|
||||
DisplayID dpy, DisplayInfo* info)
|
||||
{
|
||||
return getComposerService()->getDisplayInfo(dpy, info);
|
||||
return ComposerService::getComposerService()->getDisplayInfo(dpy, info);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -51,7 +51,8 @@ public:
|
||||
|
||||
enum {
|
||||
DISPLAY_ID_MAIN = 0,
|
||||
DISPLAY_ID_HDMI = 1
|
||||
DISPLAY_ID_HDMI = 1,
|
||||
DISPLAY_ID_COUNT
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -161,6 +161,39 @@ sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
|
||||
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<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
|
||||
@ -358,7 +391,8 @@ status_t SurfaceFlinger::readyToRun()
|
||||
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
|
||||
int format;
|
||||
@ -368,9 +402,14 @@ status_t SurfaceFlinger::readyToRun()
|
||||
mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
|
||||
|
||||
// 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);
|
||||
mDisplays.add(DisplayDevice::DISPLAY_ID_MAIN, hw);
|
||||
|
||||
for (size_t i=0 ; i<DisplayDevice::DISPLAY_ID_COUNT ; i++) {
|
||||
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
|
||||
EGLSurface surface = hw->getEGLSurface();
|
||||
@ -571,8 +610,7 @@ void SurfaceFlinger::onMessageReceived(int32_t what) {
|
||||
}
|
||||
|
||||
void SurfaceFlinger::handleMessageTransaction() {
|
||||
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
|
||||
uint32_t transactionFlags = peekTransactionFlags(mask);
|
||||
uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
|
||||
if (transactionFlags) {
|
||||
handleTransaction(transactionFlags);
|
||||
}
|
||||
@ -795,8 +833,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
|
||||
// with mStateLock held to guarantee that mCurrentState won't change
|
||||
// until the transaction is committed.
|
||||
|
||||
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
|
||||
transactionFlags = getTransactionFlags(mask);
|
||||
transactionFlags = getTransactionFlags(eTransactionMask);
|
||||
handleTransactionLocked(transactionFlags);
|
||||
|
||||
mLastTransactionTime = systemTime() - now;
|
||||
@ -832,12 +869,12 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
||||
* Perform our own transaction if needed
|
||||
*/
|
||||
|
||||
if (transactionFlags & eTransactionNeeded) {
|
||||
if (transactionFlags & eDisplayTransactionNeeded) {
|
||||
// here we take advantage of Vector's copy-on-write semantics to
|
||||
// improve performance by skipping the transaction entirely when
|
||||
// know that the lists are identical
|
||||
const KeyedVector<int32_t, DisplayDeviceState>& curr(mCurrentState.displays);
|
||||
const KeyedVector<int32_t, DisplayDeviceState>& draw(mDrawingState.displays);
|
||||
const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
|
||||
const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
|
||||
if (!curr.isIdenticalTo(draw)) {
|
||||
mVisibleRegionsDirty = true;
|
||||
const size_t cc = curr.size();
|
||||
@ -848,7 +885,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
||||
// also handle displays that changed
|
||||
// (ie: displays that are in both lists)
|
||||
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
|
||||
if (draw[i].id != DisplayDevice::DISPLAY_ID_MAIN) {
|
||||
mDisplays.removeItem(draw[i].id);
|
||||
@ -857,14 +895,32 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
||||
}
|
||||
} else {
|
||||
// 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) {
|
||||
const sp<DisplayDevice>& disp(getDisplayDevice(state.id));
|
||||
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));
|
||||
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
|
||||
// (ie: in current state but not in drawing state)
|
||||
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
|
||||
sp<DisplayDevice> disp = new DisplayDevice(this, curr[i].id, 0, 0, mEGLConfig);
|
||||
mDisplays.add(curr[i].id, disp);
|
||||
const DisplayDeviceState& state(curr[i]);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void SurfaceFlinger::setTransactionState(
|
||||
const Vector<ComposerState>& state,
|
||||
const Vector<DisplayState>& displays,
|
||||
uint32_t flags)
|
||||
{
|
||||
Mutex::Autolock _l(mStateLock);
|
||||
|
||||
int orientation = DisplayState::eOrientationUnchanged;
|
||||
if (displays.size()) {
|
||||
// TODO: handle all displays
|
||||
orientation = displays[0].orientation;
|
||||
}
|
||||
|
||||
uint32_t transactionFlags = 0;
|
||||
// FIXME: don't hardcode display id here
|
||||
if (mCurrentState.displays.valueFor(0).orientation != orientation) {
|
||||
if (uint32_t(orientation) <= DisplayState::eOrientation270) {
|
||||
mCurrentState.displays.editValueFor(0).orientation = orientation;
|
||||
transactionFlags |= eTransactionNeeded;
|
||||
} else if (orientation != DisplayState::eOrientationUnchanged) {
|
||||
ALOGW("setTransactionState: ignoring unrecognized orientation: %d",
|
||||
orientation);
|
||||
}
|
||||
|
||||
size_t count = displays.size();
|
||||
for (size_t i=0 ; i<count ; i++) {
|
||||
const DisplayState& s(displays[i]);
|
||||
transactionFlags |= setDisplayStateLocked(s);
|
||||
}
|
||||
|
||||
const size_t count = state.size();
|
||||
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()) );
|
||||
@ -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(
|
||||
ISurfaceComposerClient::surface_data_t* params,
|
||||
const String8& name,
|
||||
@ -1554,69 +1701,6 @@ status_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
|
||||
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() {
|
||||
@ -1964,7 +2048,10 @@ status_t SurfaceFlinger::onTransact(
|
||||
return NO_ERROR;
|
||||
}
|
||||
case 1005:{ // force transaction
|
||||
setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
|
||||
setTransactionFlags(
|
||||
eTransactionNeeded|
|
||||
eDisplayTransactionNeeded|
|
||||
eTraversalNeeded);
|
||||
return NO_ERROR;
|
||||
}
|
||||
case 1006:{ // send empty update
|
||||
@ -2305,8 +2392,11 @@ int SurfaceFlinger::LayerVector::do_compare(const void* lhs,
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState()
|
||||
: id(DisplayDevice::DISPLAY_ID_MAIN), layerStack(0), orientation(0) {
|
||||
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState() : id(-1) {
|
||||
}
|
||||
|
||||
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(int32_t id)
|
||||
: id(id), layerStack(0), orientation(0) {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -78,7 +78,10 @@ public:
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
enum {
|
||||
eTransactionNeeded = 0x01, eTraversalNeeded = 0x02
|
||||
eTransactionNeeded = 0x01,
|
||||
eTraversalNeeded = 0x02,
|
||||
eDisplayTransactionNeeded = 0x04,
|
||||
eTransactionMask = 0x07
|
||||
};
|
||||
|
||||
class SurfaceFlinger : public BinderService<SurfaceFlinger>,
|
||||
@ -158,19 +161,18 @@ private:
|
||||
|
||||
struct DisplayDeviceState {
|
||||
DisplayDeviceState();
|
||||
DisplayDeviceState(int32_t id);
|
||||
int32_t id;
|
||||
sp<ISurfaceTexture> surface;
|
||||
uint32_t layerStack;
|
||||
Rect viewport;
|
||||
Rect frame;
|
||||
uint8_t orientation;
|
||||
inline bool operator < (const DisplayDeviceState& rhs) const {
|
||||
return id < rhs.id;
|
||||
}
|
||||
};
|
||||
|
||||
struct State {
|
||||
LayerVector layersSortedByZ;
|
||||
KeyedVector<int32_t, DisplayDeviceState> displays;
|
||||
DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
@ -185,6 +187,8 @@ private:
|
||||
*/
|
||||
virtual sp<ISurfaceComposerClient> createConnection();
|
||||
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc();
|
||||
virtual sp<IBinder> createDisplay();
|
||||
virtual sp<IBinder> getBuiltInDisplay(int32_t id);
|
||||
virtual void setTransactionState(const Vector<ComposerState>& state,
|
||||
const Vector<DisplayState>& displays, uint32_t flags);
|
||||
virtual void bootFinished();
|
||||
@ -256,6 +260,7 @@ private:
|
||||
void commitTransaction();
|
||||
uint32_t setClientStateLocked(const sp<Client>& client,
|
||||
const layer_state_t& s);
|
||||
uint32_t setDisplayStateLocked(const DisplayState& s);
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* Layer management
|
||||
@ -391,6 +396,7 @@ private:
|
||||
EGLContext mEGLContext;
|
||||
EGLConfig mEGLConfig;
|
||||
EGLDisplay mEGLDisplay;
|
||||
sp<IBinder> mDefaultDisplays[DisplayDevice::DISPLAY_ID_COUNT];
|
||||
|
||||
// Can only accessed from the main thread, these members
|
||||
// don't need synchronization
|
||||
|
Loading…
Reference in New Issue
Block a user