diff options
Diffstat (limited to 'libs/surfaceflinger_client')
| -rw-r--r-- | libs/surfaceflinger_client/ISurfaceComposer.cpp | 14 | ||||
| -rw-r--r-- | libs/surfaceflinger_client/ISurfaceComposerClient.cpp | 17 | ||||
| -rw-r--r-- | libs/surfaceflinger_client/SharedBufferStack.cpp | 9 | ||||
| -rw-r--r-- | libs/surfaceflinger_client/Surface.cpp | 106 | ||||
| -rw-r--r-- | libs/surfaceflinger_client/SurfaceComposerClient.cpp | 78 |
5 files changed, 121 insertions, 103 deletions
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp index 50495c1..5c111f6 100644 --- a/libs/surfaceflinger_client/ISurfaceComposer.cpp +++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp @@ -55,6 +55,15 @@ public: return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); } + virtual sp<ISurfaceComposerClient> createClientConnection() + { + uint32_t n; + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + remote()->transact(BnSurfaceComposer::CREATE_CLIENT_CONNECTION, data, &reply); + return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder()); + } + virtual sp<IMemoryHeap> getCblk() const { Parcel data, reply; @@ -136,6 +145,11 @@ status_t BnSurfaceComposer::onTransact( sp<IBinder> b = createConnection()->asBinder(); reply->writeStrongBinder(b); } break; + case CREATE_CLIENT_CONNECTION: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + sp<IBinder> b = createClientConnection()->asBinder(); + reply->writeStrongBinder(b); + } break; case OPEN_GLOBAL_TRANSACTION: { CHECK_INTERFACE(ISurfaceComposer, data, reply); openGlobalTransaction(); diff --git a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp index 67c7df8..2cc1f8e 100644 --- a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp +++ b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp @@ -51,6 +51,7 @@ namespace android { enum { GET_CBLK = IBinder::FIRST_CALL_TRANSACTION, + GET_TOKEN, CREATE_SURFACE, DESTROY_SURFACE, SET_STATE @@ -72,6 +73,15 @@ public: return interface_cast<IMemoryHeap>(reply.readStrongBinder()); } + virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const + { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor()); + data.writeStrongBinder(sur->asBinder()); + remote()->transact(GET_TOKEN, data, &reply); + return reply.readInt32(); + } + virtual sp<ISurface> createSurface( surface_data_t* params, int pid, const String8& name, @@ -132,6 +142,13 @@ status_t BnSurfaceComposerClient::onTransact( reply->writeStrongBinder(ctl->asBinder()); return NO_ERROR; } break; + case GET_TOKEN: { + CHECK_INTERFACE(ISurfaceComposerClient, data, reply); + sp<ISurface> sur = interface_cast<ISurface>(data.readStrongBinder()); + ssize_t token = getTokenForSurface(sur); + reply->writeInt32(token); + return NO_ERROR; + } break; } // these must be checked diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp index 8d03145..1dd8642 100644 --- a/libs/surfaceflinger_client/SharedBufferStack.cpp +++ b/libs/surfaceflinger_client/SharedBufferStack.cpp @@ -58,7 +58,7 @@ SharedBufferStack::SharedBufferStack() void SharedBufferStack::init(int32_t i) { - inUse = -1; + inUse = -2; status = NO_ERROR; identity = i; } @@ -282,8 +282,10 @@ SharedBufferServer::UnlockUpdate::UnlockUpdate( } ssize_t SharedBufferServer::UnlockUpdate::operator()() { if (stack.inUse != lockedBuffer) { - LOGE("unlocking %d, but currently locked buffer is %d", - lockedBuffer, stack.inUse); + LOGE("unlocking %d, but currently locked buffer is %d " + "(identity=%d, token=%d)", + lockedBuffer, stack.inUse, + stack.identity, stack.token); return BAD_VALUE; } android_atomic_write(-1, &stack.inUse); @@ -480,6 +482,7 @@ SharedBufferServer::SharedBufferServer(SharedClient* sharedClient, mNumBuffers(num) { mSharedStack->init(identity); + mSharedStack->token = surface; mSharedStack->head = num-1; mSharedStack->available = num; mSharedStack->queued = 0; diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp index ac4b198..01420fe 100644 --- a/libs/surfaceflinger_client/Surface.cpp +++ b/libs/surfaceflinger_client/Surface.cpp @@ -238,14 +238,12 @@ status_t SurfaceControl::writeSurfaceToParcel( { uint32_t flags = 0; uint32_t format = 0; - SurfaceID token = -1; uint32_t identity = 0; uint32_t width = 0; uint32_t height = 0; sp<SurfaceComposerClient> client; sp<ISurface> sur; if (SurfaceControl::isValid(control)) { - token = control->mToken; identity = control->mIdentity; client = control->mClient; sur = control->mSurface; @@ -254,9 +252,7 @@ status_t SurfaceControl::writeSurfaceToParcel( format = control->mFormat; flags = control->mFlags; } - parcel->writeStrongBinder(client!=0 ? client->connection() : NULL); - parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); - parcel->writeInt32(token); + parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL); parcel->writeInt32(identity); parcel->writeInt32(width); parcel->writeInt32(height); @@ -278,31 +274,78 @@ sp<Surface> SurfaceControl::getSurface() const // Surface // ============================================================================ +class SurfaceClient : public Singleton<SurfaceClient> +{ + // all these attributes are constants + sp<ISurfaceComposer> mComposerService; + sp<ISurfaceComposerClient> mClient; + status_t mStatus; + SharedClient* mControl; + sp<IMemoryHeap> mControlMemory; + + SurfaceClient() + : Singleton<SurfaceClient>(), mStatus(NO_INIT) + { + sp<ISurfaceComposer> sf(ComposerService::getComposerService()); + mComposerService = sf; + mClient = sf->createClientConnection(); + if (mClient != NULL) { + mControlMemory = mClient->getControlBlock(); + if (mControlMemory != NULL) { + mControl = static_cast<SharedClient *>( + mControlMemory->getBase()); + if (mControl) { + mStatus = NO_ERROR; + } + } + } + } + friend class Singleton<SurfaceClient>; +public: + status_t initCheck() const { + return mStatus; + } + SharedClient* getSharedClient() const { + return mControl; + } + ssize_t getTokenForSurface(const sp<ISurface>& sur) const { + // TODO: we could cache a few tokens here to avoid an IPC + return mClient->getTokenForSurface(sur); + } + void signalServer() const { + mComposerService->signal(); + } +}; + +ANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient); + +// --------------------------------------------------------------------------- + Surface::Surface(const sp<SurfaceControl>& surface) - : mSurface(surface->mSurface), - mToken(surface->mToken), mIdentity(surface->mIdentity), - mFormat(surface->mFormat), mFlags(surface->mFlags), - mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL), + : mBufferMapper(GraphicBufferMapper::get()), + mClient(SurfaceClient::getInstance()), + mSharedBufferClient(NULL), mInitCheck(NO_INIT), + mSurface(surface->mSurface), + mIdentity(surface->mIdentity), + mFormat(surface->mFormat), mFlags(surface->mFlags), mWidth(surface->mWidth), mHeight(surface->mHeight) { - mClient = new SurfaceClient(surface->mClient); init(); } Surface::Surface(const Parcel& parcel) - : mBufferMapper(GraphicBufferMapper::get()), - mSharedBufferClient(NULL), mInitCheck(NO_INIT) + : mBufferMapper(GraphicBufferMapper::get()), + mClient(SurfaceClient::getInstance()), + mSharedBufferClient(NULL), + mInitCheck(NO_INIT) { - sp<IBinder> conn = parcel.readStrongBinder(); mSurface = interface_cast<ISurface>(parcel.readStrongBinder()); - mToken = parcel.readInt32(); mIdentity = parcel.readInt32(); mWidth = parcel.readInt32(); mHeight = parcel.readInt32(); mFormat = parcel.readInt32(); mFlags = parcel.readInt32(); - mClient = new SurfaceClient(conn); init(); } @@ -330,12 +373,14 @@ void Surface::init() mBuffers.setCapacity(2); mBuffers.insertAt(0, 2); - if (mClient != 0 && mClient->initCheck() == NO_ERROR) { - mSharedBufferClient = new SharedBufferClient( - mClient->getSharedClient(), mToken, 2, mIdentity); + if (mSurface != 0 && mClient.initCheck() == NO_ERROR) { + mToken = mClient.getTokenForSurface(mSurface); + if (mToken >= 0) { + mSharedBufferClient = new SharedBufferClient( + mClient.getSharedClient(), mToken, 2, mIdentity); + mInitCheck = mClient.getSharedClient()->validate(mToken); + } } - - mInitCheck = initCheck(); } Surface::~Surface() @@ -352,25 +397,11 @@ Surface::~Surface() // clear all references and trigger an IPC now, to make sure things // happen without delay, since these resources are quite heavy. mBuffers.clear(); - mClient.clear(); mSurface.clear(); delete mSharedBufferClient; IPCThreadState::self()->flushCommands(); } -status_t Surface::initCheck() const -{ - if (mToken<0 || mClient==0 || mClient->initCheck() != NO_ERROR) { - return NO_INIT; - } - SharedClient const* cblk = mClient->getSharedClient(); - if (cblk == 0) { - LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity); - return NO_INIT; - } - return cblk->validate(mToken); -} - bool Surface::isValid() { return mInitCheck == NO_ERROR; } @@ -379,8 +410,7 @@ status_t Surface::validate() const { // check that we initialized ourself properly if (mInitCheck != NO_ERROR) { - LOGE("invalid token (%d, identity=%u) or client (%p)", - mToken, mIdentity, mClient.get()); + LOGE("invalid token (%d, identity=%u)", mToken, mIdentity); return mInitCheck; } @@ -558,8 +588,8 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err)); if (err == NO_ERROR) { - // FIXME: can we avoid this IPC if we know there is one pending? - mClient->signalServer(); + // TODO: can we avoid this IPC if we know there is one pending? + mClient.signalServer(); } return err; } diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp index 0670d20..5ac0d5d 100644 --- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp +++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp @@ -42,36 +42,26 @@ namespace android { // --------------------------------------------------------------------------- -class ComposerService : public Singleton<ComposerService> -{ - // these are constants - sp<ISurfaceComposer> mComposerService; - sp<IMemoryHeap> mServerCblkMemory; - surface_flinger_cblk_t volatile* mServerCblk; - - ComposerService() : Singleton<ComposerService>() { - const String16 name("SurfaceFlinger"); - while (getService(name, &mComposerService) != NO_ERROR) { - usleep(250000); - } - mServerCblkMemory = mComposerService->getCblk(); - mServerCblk = static_cast<surface_flinger_cblk_t volatile *>( - mServerCblkMemory->getBase()); - } - - friend class Singleton<ComposerService>; +ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService); -public: - static sp<ISurfaceComposer> getComposerService() { - return ComposerService::getInstance().mComposerService; +ComposerService::ComposerService() +: Singleton<ComposerService>() { + const String16 name("SurfaceFlinger"); + while (getService(name, &mComposerService) != NO_ERROR) { + usleep(250000); } - static surface_flinger_cblk_t const volatile * getControlBlock() { - return ComposerService::getInstance().mServerCblk; - } -}; + mServerCblkMemory = mComposerService->getCblk(); + mServerCblk = static_cast<surface_flinger_cblk_t volatile *>( + mServerCblkMemory->getBase()); +} -ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService); +sp<ISurfaceComposer> ComposerService::getComposerService() { + return ComposerService::getInstance().mComposerService; +} +surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() { + return ComposerService::getInstance().mServerCblk; +} static inline sp<ISurfaceComposer> getComposerService() { return ComposerService::getComposerService(); @@ -557,41 +547,5 @@ status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) } // ---------------------------------------------------------------------------- - -SurfaceClient::SurfaceClient(const sp<SurfaceComposerClient>& client) - : mStatus(NO_INIT), mControl(0) -{ - if (client != 0) { - sp<IBinder> conn = client->connection(); - init(conn); - } -} -SurfaceClient::SurfaceClient(const sp<IBinder>& conn) - : mStatus(NO_INIT), mControl(0) -{ - init(conn); -} -void SurfaceClient::init(const sp<IBinder>& conn) -{ - mComposerService = getComposerService(); - sp<ISurfaceComposerClient> sf(interface_cast<ISurfaceComposerClient>(conn)); - if (sf != 0) { - mConnection = conn; - mControlMemory = sf->getControlBlock(); - mControl = static_cast<SharedClient *>(mControlMemory->getBase()); - mStatus = NO_ERROR; - } -} -status_t SurfaceClient::initCheck() const { - return mStatus; -} -SharedClient* SurfaceClient::getSharedClient() const { - return mControl; -} -void SurfaceClient::signalServer() const { - mComposerService->signal(); -} - -// ---------------------------------------------------------------------------- }; // namespace android |
