Loading include/surfaceflinger/Surface.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,7 @@ class Surface; class SurfaceComposerClient; class SurfaceComposerClient; class SharedClient; class SharedClient; class SharedBufferClient; class SharedBufferClient; class SurfaceClient; // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading Loading @@ -263,7 +264,7 @@ private: }; }; // constants // constants sp<SurfaceComposerClient> mClient; sp<SurfaceClient> mClient; sp<ISurface> mSurface; sp<ISurface> mSurface; SurfaceID mToken; SurfaceID mToken; uint32_t mIdentity; uint32_t mIdentity; Loading include/surfaceflinger/SurfaceComposerClient.h +25 −18 Original line number Original line Diff line number Diff line Loading @@ -40,7 +40,9 @@ class SharedClient; class ISurfaceComposer; class ISurfaceComposer; class DisplayInfo; class DisplayInfo; class SurfaceComposerClient : virtual public RefBase // --------------------------------------------------------------------------- class SurfaceComposerClient : public RefBase { { public: public: SurfaceComposerClient(); SurfaceComposerClient(); Loading @@ -52,10 +54,6 @@ public: // Return the connection of this client // Return the connection of this client sp<IBinder> connection() const; sp<IBinder> connection() const; // Retrieve a client for an existing connection. static sp<SurfaceComposerClient> clientForConnection(const sp<IBinder>& conn); // Forcibly remove connection before all references have gone away. // Forcibly remove connection before all references have gone away. void dispose(); void dispose(); Loading Loading @@ -135,36 +133,45 @@ public: status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy); status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy); status_t setPosition(SurfaceID id, int32_t x, int32_t y); status_t setPosition(SurfaceID id, int32_t x, int32_t y); status_t setSize(SurfaceID id, uint32_t w, uint32_t h); status_t setSize(SurfaceID id, uint32_t w, uint32_t h); void signalServer(); status_t destroySurface(SurfaceID sid); status_t destroySurface(SurfaceID sid); SharedClient* getSharedClient() const; private: private: SurfaceComposerClient(const sp<ISurfaceComposer>& sm, virtual void onFirstRef(); const sp<IBinder>& conn); void init(const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn); inline layer_state_t* get_state_l(SurfaceID id); inline layer_state_t* get_state_l(SurfaceID id); layer_state_t* lockLayerState(SurfaceID id); layer_state_t* lockLayerState(SurfaceID id); inline void unlockLayerState(); inline void unlockLayerState(); mutable Mutex mLock; mutable Mutex mLock; layer_state_t* mPrebuiltLayerState; SortedVector<layer_state_t> mStates; SortedVector<layer_state_t> mStates; int32_t mTransactionOpen; int32_t mTransactionOpen; layer_state_t* mPrebuiltLayerState; // these don't need to be protected because they never change // these don't need to be protected because they never change // after assignment // after assignment status_t mStatus; status_t mStatus; sp<ISurfaceFlingerClient> mClient; }; // --------------------------------------------------------------------------- class SurfaceClient : public RefBase { // all these attributes are constants status_t mStatus; SharedClient* mControl; SharedClient* mControl; sp<IMemoryHeap> mControlMemory; sp<IMemoryHeap> mControlMemory; sp<ISurfaceFlingerClient> mClient; sp<IBinder> mConnection; sp<ISurfaceComposer> mSignalServer; sp<ISurfaceComposer> mSignalServer; void init(const sp<IBinder>& conn); public: explicit SurfaceClient(const sp<IBinder>& conn); explicit SurfaceClient(const sp<SurfaceComposerClient>& client); status_t initCheck() const; SharedClient* getSharedClient() const; void signalServer() const; }; }; // --------------------------------------------------------------------------- }; // namespace android }; // namespace android #endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H #endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H Loading libs/surfaceflinger_client/Surface.cpp +8 −12 Original line number Original line Diff line number Diff line Loading @@ -278,14 +278,16 @@ sp<Surface> SurfaceControl::getSurface() const // Surface // Surface // ============================================================================ // ============================================================================ Surface::Surface(const sp<SurfaceControl>& surface) Surface::Surface(const sp<SurfaceControl>& surface) : mClient(surface->mClient), mSurface(surface->mSurface), : mSurface(surface->mSurface), mToken(surface->mToken), mIdentity(surface->mIdentity), mToken(surface->mToken), mIdentity(surface->mIdentity), mFormat(surface->mFormat), mFlags(surface->mFlags), mFormat(surface->mFormat), mFlags(surface->mFlags), mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL), mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL), mInitCheck(NO_INIT), mInitCheck(NO_INIT), mWidth(surface->mWidth), mHeight(surface->mHeight) mWidth(surface->mWidth), mHeight(surface->mHeight) { { mClient = new SurfaceClient(surface->mClient); init(); init(); } } Loading @@ -293,7 +295,7 @@ Surface::Surface(const Parcel& parcel) : mBufferMapper(GraphicBufferMapper::get()), : mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL), mInitCheck(NO_INIT) mSharedBufferClient(NULL), mInitCheck(NO_INIT) { { sp<IBinder> clientBinder = parcel.readStrongBinder(); sp<IBinder> conn = parcel.readStrongBinder(); mSurface = interface_cast<ISurface>(parcel.readStrongBinder()); mSurface = interface_cast<ISurface>(parcel.readStrongBinder()); mToken = parcel.readInt32(); mToken = parcel.readInt32(); mIdentity = parcel.readInt32(); mIdentity = parcel.readInt32(); Loading @@ -301,12 +303,7 @@ Surface::Surface(const Parcel& parcel) mHeight = parcel.readInt32(); mHeight = parcel.readInt32(); mFormat = parcel.readInt32(); mFormat = parcel.readInt32(); mFlags = parcel.readInt32(); mFlags = parcel.readInt32(); mClient = new SurfaceClient(conn); // FIXME: what does that mean if clientBinder is NULL here? if (clientBinder != NULL) { mClient = SurfaceComposerClient::clientForConnection(clientBinder); } init(); init(); } } Loading Loading @@ -334,7 +331,7 @@ void Surface::init() mBuffers.setCapacity(2); mBuffers.setCapacity(2); mBuffers.insertAt(0, 2); mBuffers.insertAt(0, 2); if (mClient != 0) { if (mClient != 0 && mClient->initCheck() == NO_ERROR) { mSharedBufferClient = new SharedBufferClient( mSharedBufferClient = new SharedBufferClient( mClient->getSharedClient(), mToken, 2, mIdentity); mClient->getSharedClient(), mToken, 2, mIdentity); } } Loading Loading @@ -364,7 +361,7 @@ Surface::~Surface() status_t Surface::initCheck() const status_t Surface::initCheck() const { { if (mToken<0 || mClient==0) { if (mToken<0 || mClient==0 || mClient->initCheck() != NO_ERROR) { return NO_INIT; return NO_INIT; } } SharedClient const* cblk = mClient->getSharedClient(); SharedClient const* cblk = mClient->getSharedClient(); Loading Loading @@ -565,8 +562,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) if (err == NO_ERROR) { if (err == NO_ERROR) { // FIXME: can we avoid this IPC if we know there is one pending? // FIXME: can we avoid this IPC if we know there is one pending? const sp<SurfaceComposerClient>& client(mClient); mClient->signalServer(); client->signalServer(); } } return err; return err; } } Loading libs/surfaceflinger_client/SurfaceComposerClient.cpp +162 −226 Original line number Original line Diff line number Diff line Loading @@ -17,25 +17,18 @@ #define LOG_TAG "SurfaceComposerClient" #define LOG_TAG "SurfaceComposerClient" #include <stdint.h> #include <stdint.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/types.h> #include <sys/types.h> #include <sys/stat.h> #include <cutils/memory.h> #include <utils/Atomic.h> #include <utils/Errors.h> #include <utils/Errors.h> #include <utils/threads.h> #include <utils/threads.h> #include <utils/KeyedVector.h> #include <utils/SortedVector.h> #include <utils/Log.h> #include <utils/Log.h> #include <utils/Singleton.h> #include <binder/IServiceManager.h> #include <binder/IServiceManager.h> #include <binder/IMemory.h> #include <binder/IMemory.h> #include <ui/DisplayInfo.h> #include <ui/DisplayInfo.h> #include <ui/Rect.h> #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/ISurfaceFlingerClient.h> #include <surfaceflinger/ISurfaceFlingerClient.h> Loading @@ -45,69 +38,110 @@ #include <private/surfaceflinger/LayerState.h> #include <private/surfaceflinger/LayerState.h> #include <private/surfaceflinger/SharedBufferStack.h> #include <private/surfaceflinger/SharedBufferStack.h> #define VERBOSE(...) ((void)0) //#define VERBOSE LOGD #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) namespace android { namespace android { // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // Must not be holding SurfaceComposerClient::mLock when acquiring gLock here. class Composer : public Singleton<Composer> static Mutex gLock; { static sp<ISurfaceComposer> gSurfaceManager; // these are constants static DefaultKeyedVector< sp<IBinder>, wp<SurfaceComposerClient> > gActiveConnections; sp<ISurfaceComposer> mComposerService; static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions; sp<IMemoryHeap> mServerCblkMemory; static sp<IMemoryHeap> gServerCblkMemory; surface_flinger_cblk_t volatile* mServerCblk; static volatile surface_flinger_cblk_t* gServerCblk; Mutex mLock; SortedVector< wp<SurfaceComposerClient> > mActiveConnections; SortedVector<sp<SurfaceComposerClient> > mOpenTransactions; Composer() : Singleton<Composer>() { 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()); } void addClientImpl(const sp<SurfaceComposerClient>& client) { Mutex::Autolock _l(mLock); mActiveConnections.add(client); } static sp<ISurfaceComposer> getComposerService() void removeClientImpl(const sp<SurfaceComposerClient>& client) { Mutex::Autolock _l(mLock); mActiveConnections.remove(client); } void openGlobalTransactionImpl() { { sp<ISurfaceComposer> sc; Mutex::Autolock _l(mLock); Mutex::Autolock _l(gLock); if (mOpenTransactions.size()) { if (gSurfaceManager != 0) { LOGE("openGlobalTransaction() called more than once. skipping."); sc = gSurfaceManager; return; } else { } // release the lock while we're waiting... const size_t N = mActiveConnections.size(); gLock.unlock(); for (size_t i=0; i<N; i++) { sp<SurfaceComposerClient> client(mActiveConnections[i].promote()); sp<IBinder> binder; if (client != 0 && mOpenTransactions.indexOf(client) < 0) { sp<IServiceManager> sm = defaultServiceManager(); if (client->openTransaction() == NO_ERROR) { do { mOpenTransactions.add(client); binder = sm->getService(String16("SurfaceFlinger")); if (binder == 0) { LOGW("SurfaceFlinger not published, waiting..."); usleep(500000); // 0.5 s } } while(binder == 0); // grab the lock again for updating gSurfaceManager gLock.lock(); if (gSurfaceManager == 0) { sc = interface_cast<ISurfaceComposer>(binder); gSurfaceManager = sc; } else { } else { sc = gSurfaceManager; LOGE("openTransaction on client %p failed", client.get()); // let it go, it'll fail later when the user // tries to do something with the transaction } } } } } return sc; } } static volatile surface_flinger_cblk_t const * get_cblk() void closeGlobalTransactionImpl() { { if (gServerCblk == 0) { mLock.lock(); sp<ISurfaceComposer> sm(getComposerService()); SortedVector< sp<SurfaceComposerClient> > clients(mOpenTransactions); Mutex::Autolock _l(gLock); mOpenTransactions.clear(); if (gServerCblk == 0) { mLock.unlock(); gServerCblkMemory = sm->getCblk(); LOGE_IF(gServerCblkMemory==0, "Can't get server control block"); sp<ISurfaceComposer> sm(mComposerService); gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase(); sm->openGlobalTransaction(); LOGE_IF(gServerCblk==0, "Can't get server control block address"); const size_t N = clients.size(); for (size_t i=0; i<N; i++) { clients[i]->closeTransaction(); } sm->closeGlobalTransaction(); } friend class Singleton<Composer>; public: static sp<ISurfaceComposer> getComposerService() { return Composer::getInstance().mComposerService; } static surface_flinger_cblk_t const volatile * getControlBlock() { return Composer::getInstance().mServerCblk; } static void addClient(const sp<SurfaceComposerClient>& client) { Composer::getInstance().addClientImpl(client); } static void removeClient(const sp<SurfaceComposerClient>& client) { Composer::getInstance().removeClientImpl(client); } } static void openGlobalTransaction() { Composer::getInstance().openGlobalTransactionImpl(); } } return gServerCblk; static void closeGlobalTransaction() { Composer::getInstance().closeGlobalTransactionImpl(); } }; ANDROID_SINGLETON_STATIC_INSTANCE(Composer); static inline sp<ISurfaceComposer> getComposerService() { return Composer::getComposerService(); } static inline surface_flinger_cblk_t const volatile * get_cblk() { return Composer::getControlBlock(); } } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading @@ -120,66 +154,28 @@ static inline int compare_type( const layer_state_t& lhs, } } SurfaceComposerClient::SurfaceComposerClient() SurfaceComposerClient::SurfaceComposerClient() : mTransactionOpen(0), mPrebuiltLayerState(0), mStatus(NO_INIT) { { sp<ISurfaceComposer> sm(getComposerService()); if (sm == 0) { init(0, 0); return; } } init(sm, sm->createConnection()); void SurfaceComposerClient::onFirstRef() if (mClient != 0) { Mutex::Autolock _l(gLock); VERBOSE("Adding client %p to map", this); gActiveConnections.add(mClient->asBinder(), this); } } SurfaceComposerClient::SurfaceComposerClient( const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn) { init(sm, interface_cast<ISurfaceFlingerClient>(conn)); } SurfaceComposerClient::~SurfaceComposerClient() { VERBOSE("Destroying client %p, conn %p", this, mClient.get()); dispose(); } status_t SurfaceComposerClient::linkToComposerDeath( const sp<IBinder::DeathRecipient>& recipient, void* cookie, uint32_t flags) { { sp<ISurfaceComposer> sm(getComposerService()); sp<ISurfaceComposer> sm(getComposerService()); return sm->asBinder()->linkToDeath(recipient, cookie, flags); if (sm != 0) { } sp<ISurfaceFlingerClient> conn = sm->createConnection(); if (conn != 0) { void SurfaceComposerClient::init( const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn) { VERBOSE("Creating client %p, conn %p", this, conn.get()); mPrebuiltLayerState = 0; mTransactionOpen = 0; mStatus = NO_ERROR; mControl = 0; mClient = conn; mClient = conn; if (mClient == 0) { Composer::addClient(this); mStatus = NO_INIT; mPrebuiltLayerState = new layer_state_t; return; mStatus = NO_ERROR; } } } mControlMemory = mClient->getControlBlock(); mSignalServer = sm; mControl = static_cast<SharedClient *>(mControlMemory->getBase()); } } SharedClient* SurfaceComposerClient::getSharedClient() const SurfaceComposerClient::~SurfaceComposerClient() { { return mControl; delete mPrebuiltLayerState; dispose(); } } status_t SurfaceComposerClient::initCheck() const status_t SurfaceComposerClient::initCheck() const Loading @@ -192,64 +188,26 @@ sp<IBinder> SurfaceComposerClient::connection() const return (mClient != 0) ? mClient->asBinder() : 0; return (mClient != 0) ? mClient->asBinder() : 0; } } sp<SurfaceComposerClient> status_t SurfaceComposerClient::linkToComposerDeath( SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn) const sp<IBinder::DeathRecipient>& recipient, void* cookie, uint32_t flags) { { sp<SurfaceComposerClient> client; { // scope for lock Mutex::Autolock _l(gLock); client = gActiveConnections.valueFor(conn).promote(); } if (client == 0) { // Need to make a new client. sp<ISurfaceComposer> sm(getComposerService()); sp<ISurfaceComposer> sm(getComposerService()); client = new SurfaceComposerClient(sm, conn); return sm->asBinder()->linkToDeath(recipient, cookie, flags); if (client != 0 && client->initCheck() == NO_ERROR) { Mutex::Autolock _l(gLock); gActiveConnections.add(conn, client); //LOGD("we have %d connections", gActiveConnections.size()); } else { client.clear(); } } return client; } } void SurfaceComposerClient::dispose() void SurfaceComposerClient::dispose() { { // this can be called more than once. // this can be called more than once. sp<IMemoryHeap> controlMemory; sp<ISurfaceFlingerClient> client; sp<ISurfaceFlingerClient> client; { Mutex::Autolock _lg(gLock); Mutex::Autolock _lm(mLock); Mutex::Autolock _lm(mLock); mSignalServer = 0; if (mClient != 0) { if (mClient != 0) { client = mClient; Composer::removeClient(this); client = mClient; // hold ref while lock is held mClient.clear(); mClient.clear(); ssize_t i = gActiveConnections.indexOfKey(client->asBinder()); if (i >= 0 && gActiveConnections.valueAt(i) == this) { VERBOSE("Removing client %p from map at %d", this, int(i)); gActiveConnections.removeItemsAt(i); } } } delete mPrebuiltLayerState; mPrebuiltLayerState = 0; controlMemory = mControlMemory; mControlMemory.clear(); mControl = 0; mStatus = NO_INIT; mStatus = NO_INIT; } } } status_t SurfaceComposerClient::getDisplayInfo( status_t SurfaceComposerClient::getDisplayInfo( DisplayID dpy, DisplayInfo* info) DisplayID dpy, DisplayInfo* info) Loading Loading @@ -309,12 +267,6 @@ ssize_t SurfaceComposerClient::getNumberOfDisplays() return n; return n; } } void SurfaceComposerClient::signalServer() { mSignalServer->signal(); } sp<SurfaceControl> SurfaceComposerClient::createSurface( sp<SurfaceControl> SurfaceComposerClient::createSurface( int pid, int pid, DisplayID display, DisplayID display, Loading @@ -331,7 +283,6 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface( return SurfaceComposerClient::createSurface(pid, name, display, return SurfaceComposerClient::createSurface(pid, name, display, w, h, format, flags); w, h, format, flags); } } sp<SurfaceControl> SurfaceComposerClient::createSurface( sp<SurfaceControl> SurfaceComposerClient::createSurface( Loading Loading @@ -377,55 +328,13 @@ status_t SurfaceComposerClient::destroySurface(SurfaceID sid) void SurfaceComposerClient::openGlobalTransaction() void SurfaceComposerClient::openGlobalTransaction() { { Mutex::Autolock _l(gLock); Composer::openGlobalTransaction(); if (gOpenTransactions.size()) { LOGE("openGlobalTransaction() called more than once. skipping."); return; } const size_t N = gActiveConnections.size(); VERBOSE("openGlobalTransaction (%ld clients)", N); for (size_t i=0; i<N; i++) { sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i).promote()); if (client != 0 && gOpenTransactions.indexOf(client) < 0) { if (client->openTransaction() == NO_ERROR) { if (gOpenTransactions.add(client) < 0) { // Ooops! LOGE( "Unable to add a SurfaceComposerClient " "to the global transaction set (out of memory?)"); client->closeTransaction(); // let it go, it'll fail later when the user // tries to do something with the transaction } } else { LOGE("openTransaction on client %p failed", client.get()); // let it go, it'll fail later when the user // tries to do something with the transaction } } } } } void SurfaceComposerClient::closeGlobalTransaction() void SurfaceComposerClient::closeGlobalTransaction() { { gLock.lock(); Composer::closeGlobalTransaction(); SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions); gOpenTransactions.clear(); gLock.unlock(); const size_t N = clients.size(); VERBOSE("closeGlobalTransaction (%ld clients)", N); sp<ISurfaceComposer> sm(getComposerService()); sm->openGlobalTransaction(); for (size_t i=0; i<N; i++) { clients[i]->closeTransaction(); } } sm->closeGlobalTransaction(); } status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags) status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags) { { Loading @@ -451,26 +360,16 @@ status_t SurfaceComposerClient::openTransaction() if (mStatus != NO_ERROR) if (mStatus != NO_ERROR) return mStatus; return mStatus; Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); VERBOSE( "openTransaction (client %p, mTransactionOpen=%d)", this, mTransactionOpen); mTransactionOpen++; mTransactionOpen++; if (mPrebuiltLayerState == 0) { mPrebuiltLayerState = new layer_state_t; } return NO_ERROR; return NO_ERROR; } } status_t SurfaceComposerClient::closeTransaction() status_t SurfaceComposerClient::closeTransaction() { { if (mStatus != NO_ERROR) if (mStatus != NO_ERROR) return mStatus; return mStatus; Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); VERBOSE( "closeTransaction (client %p, mTransactionOpen=%d)", this, mTransactionOpen); if (mTransactionOpen <= 0) { if (mTransactionOpen <= 0) { LOGE( "closeTransaction (client %p, mTransactionOpen=%d) " LOGE( "closeTransaction (client %p, mTransactionOpen=%d) " "called more times than openTransaction()", "called more times than openTransaction()", Loading Loading @@ -502,7 +401,7 @@ layer_state_t* SurfaceComposerClient::get_state_l(SurfaceID index) } } // use mPrebuiltLayerState just to find out if we already have it // use mPrebuiltLayerState just to find out if we already have it layer_state_t& dummy = *mPrebuiltLayerState; layer_state_t& dummy(*mPrebuiltLayerState); dummy.surface = index; dummy.surface = index; ssize_t i = mStates.indexOf(dummy); ssize_t i = mStates.indexOf(dummy); if (i < 0) { if (i < 0) { Loading Loading @@ -642,5 +541,42 @@ status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) return NO_ERROR; return NO_ERROR; } } // ---------------------------------------------------------------------------- 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) { mSignalServer = getComposerService(); sp<ISurfaceFlingerClient> sf(interface_cast<ISurfaceFlingerClient>(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 { mSignalServer->signal(); } // ---------------------------------------------------------------------------- }; // namespace android }; // namespace android Loading
include/surfaceflinger/Surface.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -44,6 +44,7 @@ class Surface; class SurfaceComposerClient; class SurfaceComposerClient; class SharedClient; class SharedClient; class SharedBufferClient; class SharedBufferClient; class SurfaceClient; // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading Loading @@ -263,7 +264,7 @@ private: }; }; // constants // constants sp<SurfaceComposerClient> mClient; sp<SurfaceClient> mClient; sp<ISurface> mSurface; sp<ISurface> mSurface; SurfaceID mToken; SurfaceID mToken; uint32_t mIdentity; uint32_t mIdentity; Loading
include/surfaceflinger/SurfaceComposerClient.h +25 −18 Original line number Original line Diff line number Diff line Loading @@ -40,7 +40,9 @@ class SharedClient; class ISurfaceComposer; class ISurfaceComposer; class DisplayInfo; class DisplayInfo; class SurfaceComposerClient : virtual public RefBase // --------------------------------------------------------------------------- class SurfaceComposerClient : public RefBase { { public: public: SurfaceComposerClient(); SurfaceComposerClient(); Loading @@ -52,10 +54,6 @@ public: // Return the connection of this client // Return the connection of this client sp<IBinder> connection() const; sp<IBinder> connection() const; // Retrieve a client for an existing connection. static sp<SurfaceComposerClient> clientForConnection(const sp<IBinder>& conn); // Forcibly remove connection before all references have gone away. // Forcibly remove connection before all references have gone away. void dispose(); void dispose(); Loading Loading @@ -135,36 +133,45 @@ public: status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy); status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy); status_t setPosition(SurfaceID id, int32_t x, int32_t y); status_t setPosition(SurfaceID id, int32_t x, int32_t y); status_t setSize(SurfaceID id, uint32_t w, uint32_t h); status_t setSize(SurfaceID id, uint32_t w, uint32_t h); void signalServer(); status_t destroySurface(SurfaceID sid); status_t destroySurface(SurfaceID sid); SharedClient* getSharedClient() const; private: private: SurfaceComposerClient(const sp<ISurfaceComposer>& sm, virtual void onFirstRef(); const sp<IBinder>& conn); void init(const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn); inline layer_state_t* get_state_l(SurfaceID id); inline layer_state_t* get_state_l(SurfaceID id); layer_state_t* lockLayerState(SurfaceID id); layer_state_t* lockLayerState(SurfaceID id); inline void unlockLayerState(); inline void unlockLayerState(); mutable Mutex mLock; mutable Mutex mLock; layer_state_t* mPrebuiltLayerState; SortedVector<layer_state_t> mStates; SortedVector<layer_state_t> mStates; int32_t mTransactionOpen; int32_t mTransactionOpen; layer_state_t* mPrebuiltLayerState; // these don't need to be protected because they never change // these don't need to be protected because they never change // after assignment // after assignment status_t mStatus; status_t mStatus; sp<ISurfaceFlingerClient> mClient; }; // --------------------------------------------------------------------------- class SurfaceClient : public RefBase { // all these attributes are constants status_t mStatus; SharedClient* mControl; SharedClient* mControl; sp<IMemoryHeap> mControlMemory; sp<IMemoryHeap> mControlMemory; sp<ISurfaceFlingerClient> mClient; sp<IBinder> mConnection; sp<ISurfaceComposer> mSignalServer; sp<ISurfaceComposer> mSignalServer; void init(const sp<IBinder>& conn); public: explicit SurfaceClient(const sp<IBinder>& conn); explicit SurfaceClient(const sp<SurfaceComposerClient>& client); status_t initCheck() const; SharedClient* getSharedClient() const; void signalServer() const; }; }; // --------------------------------------------------------------------------- }; // namespace android }; // namespace android #endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H #endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H Loading
libs/surfaceflinger_client/Surface.cpp +8 −12 Original line number Original line Diff line number Diff line Loading @@ -278,14 +278,16 @@ sp<Surface> SurfaceControl::getSurface() const // Surface // Surface // ============================================================================ // ============================================================================ Surface::Surface(const sp<SurfaceControl>& surface) Surface::Surface(const sp<SurfaceControl>& surface) : mClient(surface->mClient), mSurface(surface->mSurface), : mSurface(surface->mSurface), mToken(surface->mToken), mIdentity(surface->mIdentity), mToken(surface->mToken), mIdentity(surface->mIdentity), mFormat(surface->mFormat), mFlags(surface->mFlags), mFormat(surface->mFormat), mFlags(surface->mFlags), mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL), mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL), mInitCheck(NO_INIT), mInitCheck(NO_INIT), mWidth(surface->mWidth), mHeight(surface->mHeight) mWidth(surface->mWidth), mHeight(surface->mHeight) { { mClient = new SurfaceClient(surface->mClient); init(); init(); } } Loading @@ -293,7 +295,7 @@ Surface::Surface(const Parcel& parcel) : mBufferMapper(GraphicBufferMapper::get()), : mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL), mInitCheck(NO_INIT) mSharedBufferClient(NULL), mInitCheck(NO_INIT) { { sp<IBinder> clientBinder = parcel.readStrongBinder(); sp<IBinder> conn = parcel.readStrongBinder(); mSurface = interface_cast<ISurface>(parcel.readStrongBinder()); mSurface = interface_cast<ISurface>(parcel.readStrongBinder()); mToken = parcel.readInt32(); mToken = parcel.readInt32(); mIdentity = parcel.readInt32(); mIdentity = parcel.readInt32(); Loading @@ -301,12 +303,7 @@ Surface::Surface(const Parcel& parcel) mHeight = parcel.readInt32(); mHeight = parcel.readInt32(); mFormat = parcel.readInt32(); mFormat = parcel.readInt32(); mFlags = parcel.readInt32(); mFlags = parcel.readInt32(); mClient = new SurfaceClient(conn); // FIXME: what does that mean if clientBinder is NULL here? if (clientBinder != NULL) { mClient = SurfaceComposerClient::clientForConnection(clientBinder); } init(); init(); } } Loading Loading @@ -334,7 +331,7 @@ void Surface::init() mBuffers.setCapacity(2); mBuffers.setCapacity(2); mBuffers.insertAt(0, 2); mBuffers.insertAt(0, 2); if (mClient != 0) { if (mClient != 0 && mClient->initCheck() == NO_ERROR) { mSharedBufferClient = new SharedBufferClient( mSharedBufferClient = new SharedBufferClient( mClient->getSharedClient(), mToken, 2, mIdentity); mClient->getSharedClient(), mToken, 2, mIdentity); } } Loading Loading @@ -364,7 +361,7 @@ Surface::~Surface() status_t Surface::initCheck() const status_t Surface::initCheck() const { { if (mToken<0 || mClient==0) { if (mToken<0 || mClient==0 || mClient->initCheck() != NO_ERROR) { return NO_INIT; return NO_INIT; } } SharedClient const* cblk = mClient->getSharedClient(); SharedClient const* cblk = mClient->getSharedClient(); Loading Loading @@ -565,8 +562,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) if (err == NO_ERROR) { if (err == NO_ERROR) { // FIXME: can we avoid this IPC if we know there is one pending? // FIXME: can we avoid this IPC if we know there is one pending? const sp<SurfaceComposerClient>& client(mClient); mClient->signalServer(); client->signalServer(); } } return err; return err; } } Loading
libs/surfaceflinger_client/SurfaceComposerClient.cpp +162 −226 Original line number Original line Diff line number Diff line Loading @@ -17,25 +17,18 @@ #define LOG_TAG "SurfaceComposerClient" #define LOG_TAG "SurfaceComposerClient" #include <stdint.h> #include <stdint.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/types.h> #include <sys/types.h> #include <sys/stat.h> #include <cutils/memory.h> #include <utils/Atomic.h> #include <utils/Errors.h> #include <utils/Errors.h> #include <utils/threads.h> #include <utils/threads.h> #include <utils/KeyedVector.h> #include <utils/SortedVector.h> #include <utils/Log.h> #include <utils/Log.h> #include <utils/Singleton.h> #include <binder/IServiceManager.h> #include <binder/IServiceManager.h> #include <binder/IMemory.h> #include <binder/IMemory.h> #include <ui/DisplayInfo.h> #include <ui/DisplayInfo.h> #include <ui/Rect.h> #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/ISurfaceFlingerClient.h> #include <surfaceflinger/ISurfaceFlingerClient.h> Loading @@ -45,69 +38,110 @@ #include <private/surfaceflinger/LayerState.h> #include <private/surfaceflinger/LayerState.h> #include <private/surfaceflinger/SharedBufferStack.h> #include <private/surfaceflinger/SharedBufferStack.h> #define VERBOSE(...) ((void)0) //#define VERBOSE LOGD #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) namespace android { namespace android { // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // Must not be holding SurfaceComposerClient::mLock when acquiring gLock here. class Composer : public Singleton<Composer> static Mutex gLock; { static sp<ISurfaceComposer> gSurfaceManager; // these are constants static DefaultKeyedVector< sp<IBinder>, wp<SurfaceComposerClient> > gActiveConnections; sp<ISurfaceComposer> mComposerService; static SortedVector<sp<SurfaceComposerClient> > gOpenTransactions; sp<IMemoryHeap> mServerCblkMemory; static sp<IMemoryHeap> gServerCblkMemory; surface_flinger_cblk_t volatile* mServerCblk; static volatile surface_flinger_cblk_t* gServerCblk; Mutex mLock; SortedVector< wp<SurfaceComposerClient> > mActiveConnections; SortedVector<sp<SurfaceComposerClient> > mOpenTransactions; Composer() : Singleton<Composer>() { 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()); } void addClientImpl(const sp<SurfaceComposerClient>& client) { Mutex::Autolock _l(mLock); mActiveConnections.add(client); } static sp<ISurfaceComposer> getComposerService() void removeClientImpl(const sp<SurfaceComposerClient>& client) { Mutex::Autolock _l(mLock); mActiveConnections.remove(client); } void openGlobalTransactionImpl() { { sp<ISurfaceComposer> sc; Mutex::Autolock _l(mLock); Mutex::Autolock _l(gLock); if (mOpenTransactions.size()) { if (gSurfaceManager != 0) { LOGE("openGlobalTransaction() called more than once. skipping."); sc = gSurfaceManager; return; } else { } // release the lock while we're waiting... const size_t N = mActiveConnections.size(); gLock.unlock(); for (size_t i=0; i<N; i++) { sp<SurfaceComposerClient> client(mActiveConnections[i].promote()); sp<IBinder> binder; if (client != 0 && mOpenTransactions.indexOf(client) < 0) { sp<IServiceManager> sm = defaultServiceManager(); if (client->openTransaction() == NO_ERROR) { do { mOpenTransactions.add(client); binder = sm->getService(String16("SurfaceFlinger")); if (binder == 0) { LOGW("SurfaceFlinger not published, waiting..."); usleep(500000); // 0.5 s } } while(binder == 0); // grab the lock again for updating gSurfaceManager gLock.lock(); if (gSurfaceManager == 0) { sc = interface_cast<ISurfaceComposer>(binder); gSurfaceManager = sc; } else { } else { sc = gSurfaceManager; LOGE("openTransaction on client %p failed", client.get()); // let it go, it'll fail later when the user // tries to do something with the transaction } } } } } return sc; } } static volatile surface_flinger_cblk_t const * get_cblk() void closeGlobalTransactionImpl() { { if (gServerCblk == 0) { mLock.lock(); sp<ISurfaceComposer> sm(getComposerService()); SortedVector< sp<SurfaceComposerClient> > clients(mOpenTransactions); Mutex::Autolock _l(gLock); mOpenTransactions.clear(); if (gServerCblk == 0) { mLock.unlock(); gServerCblkMemory = sm->getCblk(); LOGE_IF(gServerCblkMemory==0, "Can't get server control block"); sp<ISurfaceComposer> sm(mComposerService); gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase(); sm->openGlobalTransaction(); LOGE_IF(gServerCblk==0, "Can't get server control block address"); const size_t N = clients.size(); for (size_t i=0; i<N; i++) { clients[i]->closeTransaction(); } sm->closeGlobalTransaction(); } friend class Singleton<Composer>; public: static sp<ISurfaceComposer> getComposerService() { return Composer::getInstance().mComposerService; } static surface_flinger_cblk_t const volatile * getControlBlock() { return Composer::getInstance().mServerCblk; } static void addClient(const sp<SurfaceComposerClient>& client) { Composer::getInstance().addClientImpl(client); } static void removeClient(const sp<SurfaceComposerClient>& client) { Composer::getInstance().removeClientImpl(client); } } static void openGlobalTransaction() { Composer::getInstance().openGlobalTransactionImpl(); } } return gServerCblk; static void closeGlobalTransaction() { Composer::getInstance().closeGlobalTransactionImpl(); } }; ANDROID_SINGLETON_STATIC_INSTANCE(Composer); static inline sp<ISurfaceComposer> getComposerService() { return Composer::getComposerService(); } static inline surface_flinger_cblk_t const volatile * get_cblk() { return Composer::getControlBlock(); } } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading @@ -120,66 +154,28 @@ static inline int compare_type( const layer_state_t& lhs, } } SurfaceComposerClient::SurfaceComposerClient() SurfaceComposerClient::SurfaceComposerClient() : mTransactionOpen(0), mPrebuiltLayerState(0), mStatus(NO_INIT) { { sp<ISurfaceComposer> sm(getComposerService()); if (sm == 0) { init(0, 0); return; } } init(sm, sm->createConnection()); void SurfaceComposerClient::onFirstRef() if (mClient != 0) { Mutex::Autolock _l(gLock); VERBOSE("Adding client %p to map", this); gActiveConnections.add(mClient->asBinder(), this); } } SurfaceComposerClient::SurfaceComposerClient( const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn) { init(sm, interface_cast<ISurfaceFlingerClient>(conn)); } SurfaceComposerClient::~SurfaceComposerClient() { VERBOSE("Destroying client %p, conn %p", this, mClient.get()); dispose(); } status_t SurfaceComposerClient::linkToComposerDeath( const sp<IBinder::DeathRecipient>& recipient, void* cookie, uint32_t flags) { { sp<ISurfaceComposer> sm(getComposerService()); sp<ISurfaceComposer> sm(getComposerService()); return sm->asBinder()->linkToDeath(recipient, cookie, flags); if (sm != 0) { } sp<ISurfaceFlingerClient> conn = sm->createConnection(); if (conn != 0) { void SurfaceComposerClient::init( const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn) { VERBOSE("Creating client %p, conn %p", this, conn.get()); mPrebuiltLayerState = 0; mTransactionOpen = 0; mStatus = NO_ERROR; mControl = 0; mClient = conn; mClient = conn; if (mClient == 0) { Composer::addClient(this); mStatus = NO_INIT; mPrebuiltLayerState = new layer_state_t; return; mStatus = NO_ERROR; } } } mControlMemory = mClient->getControlBlock(); mSignalServer = sm; mControl = static_cast<SharedClient *>(mControlMemory->getBase()); } } SharedClient* SurfaceComposerClient::getSharedClient() const SurfaceComposerClient::~SurfaceComposerClient() { { return mControl; delete mPrebuiltLayerState; dispose(); } } status_t SurfaceComposerClient::initCheck() const status_t SurfaceComposerClient::initCheck() const Loading @@ -192,64 +188,26 @@ sp<IBinder> SurfaceComposerClient::connection() const return (mClient != 0) ? mClient->asBinder() : 0; return (mClient != 0) ? mClient->asBinder() : 0; } } sp<SurfaceComposerClient> status_t SurfaceComposerClient::linkToComposerDeath( SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn) const sp<IBinder::DeathRecipient>& recipient, void* cookie, uint32_t flags) { { sp<SurfaceComposerClient> client; { // scope for lock Mutex::Autolock _l(gLock); client = gActiveConnections.valueFor(conn).promote(); } if (client == 0) { // Need to make a new client. sp<ISurfaceComposer> sm(getComposerService()); sp<ISurfaceComposer> sm(getComposerService()); client = new SurfaceComposerClient(sm, conn); return sm->asBinder()->linkToDeath(recipient, cookie, flags); if (client != 0 && client->initCheck() == NO_ERROR) { Mutex::Autolock _l(gLock); gActiveConnections.add(conn, client); //LOGD("we have %d connections", gActiveConnections.size()); } else { client.clear(); } } return client; } } void SurfaceComposerClient::dispose() void SurfaceComposerClient::dispose() { { // this can be called more than once. // this can be called more than once. sp<IMemoryHeap> controlMemory; sp<ISurfaceFlingerClient> client; sp<ISurfaceFlingerClient> client; { Mutex::Autolock _lg(gLock); Mutex::Autolock _lm(mLock); Mutex::Autolock _lm(mLock); mSignalServer = 0; if (mClient != 0) { if (mClient != 0) { client = mClient; Composer::removeClient(this); client = mClient; // hold ref while lock is held mClient.clear(); mClient.clear(); ssize_t i = gActiveConnections.indexOfKey(client->asBinder()); if (i >= 0 && gActiveConnections.valueAt(i) == this) { VERBOSE("Removing client %p from map at %d", this, int(i)); gActiveConnections.removeItemsAt(i); } } } delete mPrebuiltLayerState; mPrebuiltLayerState = 0; controlMemory = mControlMemory; mControlMemory.clear(); mControl = 0; mStatus = NO_INIT; mStatus = NO_INIT; } } } status_t SurfaceComposerClient::getDisplayInfo( status_t SurfaceComposerClient::getDisplayInfo( DisplayID dpy, DisplayInfo* info) DisplayID dpy, DisplayInfo* info) Loading Loading @@ -309,12 +267,6 @@ ssize_t SurfaceComposerClient::getNumberOfDisplays() return n; return n; } } void SurfaceComposerClient::signalServer() { mSignalServer->signal(); } sp<SurfaceControl> SurfaceComposerClient::createSurface( sp<SurfaceControl> SurfaceComposerClient::createSurface( int pid, int pid, DisplayID display, DisplayID display, Loading @@ -331,7 +283,6 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface( return SurfaceComposerClient::createSurface(pid, name, display, return SurfaceComposerClient::createSurface(pid, name, display, w, h, format, flags); w, h, format, flags); } } sp<SurfaceControl> SurfaceComposerClient::createSurface( sp<SurfaceControl> SurfaceComposerClient::createSurface( Loading Loading @@ -377,55 +328,13 @@ status_t SurfaceComposerClient::destroySurface(SurfaceID sid) void SurfaceComposerClient::openGlobalTransaction() void SurfaceComposerClient::openGlobalTransaction() { { Mutex::Autolock _l(gLock); Composer::openGlobalTransaction(); if (gOpenTransactions.size()) { LOGE("openGlobalTransaction() called more than once. skipping."); return; } const size_t N = gActiveConnections.size(); VERBOSE("openGlobalTransaction (%ld clients)", N); for (size_t i=0; i<N; i++) { sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i).promote()); if (client != 0 && gOpenTransactions.indexOf(client) < 0) { if (client->openTransaction() == NO_ERROR) { if (gOpenTransactions.add(client) < 0) { // Ooops! LOGE( "Unable to add a SurfaceComposerClient " "to the global transaction set (out of memory?)"); client->closeTransaction(); // let it go, it'll fail later when the user // tries to do something with the transaction } } else { LOGE("openTransaction on client %p failed", client.get()); // let it go, it'll fail later when the user // tries to do something with the transaction } } } } } void SurfaceComposerClient::closeGlobalTransaction() void SurfaceComposerClient::closeGlobalTransaction() { { gLock.lock(); Composer::closeGlobalTransaction(); SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions); gOpenTransactions.clear(); gLock.unlock(); const size_t N = clients.size(); VERBOSE("closeGlobalTransaction (%ld clients)", N); sp<ISurfaceComposer> sm(getComposerService()); sm->openGlobalTransaction(); for (size_t i=0; i<N; i++) { clients[i]->closeTransaction(); } } sm->closeGlobalTransaction(); } status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags) status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags) { { Loading @@ -451,26 +360,16 @@ status_t SurfaceComposerClient::openTransaction() if (mStatus != NO_ERROR) if (mStatus != NO_ERROR) return mStatus; return mStatus; Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); VERBOSE( "openTransaction (client %p, mTransactionOpen=%d)", this, mTransactionOpen); mTransactionOpen++; mTransactionOpen++; if (mPrebuiltLayerState == 0) { mPrebuiltLayerState = new layer_state_t; } return NO_ERROR; return NO_ERROR; } } status_t SurfaceComposerClient::closeTransaction() status_t SurfaceComposerClient::closeTransaction() { { if (mStatus != NO_ERROR) if (mStatus != NO_ERROR) return mStatus; return mStatus; Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock); VERBOSE( "closeTransaction (client %p, mTransactionOpen=%d)", this, mTransactionOpen); if (mTransactionOpen <= 0) { if (mTransactionOpen <= 0) { LOGE( "closeTransaction (client %p, mTransactionOpen=%d) " LOGE( "closeTransaction (client %p, mTransactionOpen=%d) " "called more times than openTransaction()", "called more times than openTransaction()", Loading Loading @@ -502,7 +401,7 @@ layer_state_t* SurfaceComposerClient::get_state_l(SurfaceID index) } } // use mPrebuiltLayerState just to find out if we already have it // use mPrebuiltLayerState just to find out if we already have it layer_state_t& dummy = *mPrebuiltLayerState; layer_state_t& dummy(*mPrebuiltLayerState); dummy.surface = index; dummy.surface = index; ssize_t i = mStates.indexOf(dummy); ssize_t i = mStates.indexOf(dummy); if (i < 0) { if (i < 0) { Loading Loading @@ -642,5 +541,42 @@ status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) return NO_ERROR; return NO_ERROR; } } // ---------------------------------------------------------------------------- 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) { mSignalServer = getComposerService(); sp<ISurfaceFlingerClient> sf(interface_cast<ISurfaceFlingerClient>(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 { mSignalServer->signal(); } // ---------------------------------------------------------------------------- }; // namespace android }; // namespace android