Loading include/private/surfaceflinger/SharedBufferStack.h +6 −10 Original line number Diff line number Diff line Loading @@ -44,15 +44,6 @@ namespace android { * dequeue-able buffer. When these various conditions are not met, the caller * waits until the condition is met. * * * CAVEATS: * * In the current implementation there are several limitations: * - buffers must be locked in the same order they've been dequeued * - buffers must be enqueued in the same order they've been locked * - dequeue() is not reentrant * - no error checks are done on the condition above * */ // ---------------------------------------------------------------------------- Loading Loading @@ -269,7 +260,9 @@ private: // ---------------------------------------------------------------------------- class SharedBufferServer : public SharedBufferBase class SharedBufferServer : public SharedBufferBase, public LightRefBase<SharedBufferServer> { public: SharedBufferServer(SharedClient* sharedClient, int surface, int num, Loading @@ -290,6 +283,9 @@ public: private: friend class LightRefBase<SharedBufferServer>; ~SharedBufferServer(); /* * BufferList is basically a fixed-capacity sorted-vector of * unsigned 5-bits ints using a 32-bits int as storage. Loading include/surfaceflinger/Surface.h +3 −3 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ public: static bool isSameSurface( const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); SurfaceID ID() const { return mToken; } uint32_t getFlags() const { return mFlags; } uint32_t getIdentity() const { return mIdentity; } Loading Loading @@ -145,6 +144,9 @@ public: uint32_t reserved[2]; }; static status_t writeToParcel( const sp<Surface>& control, Parcel* parcel); static sp<Surface> readFromParcel( const Parcel& data, const sp<Surface>& other); Loading @@ -153,7 +155,6 @@ public: } bool isValid(); SurfaceID ID() const { return mToken; } uint32_t getFlags() const { return mFlags; } uint32_t getIdentity() const { return mIdentity; } Loading Loading @@ -267,7 +268,6 @@ private: SharedBufferClient* mSharedBufferClient; status_t mInitCheck; sp<ISurface> mSurface; SurfaceID mToken; uint32_t mIdentity; PixelFormat mFormat; uint32_t mFlags; Loading libs/surfaceflinger/Layer.cpp +35 −13 Original line number Diff line number Diff line Loading @@ -76,15 +76,18 @@ Layer::~Layer() status_t Layer::setToken(const sp<UserClient>& userClient, SharedClient* sharedClient, int32_t token) { SharedBufferServer* lcblk = new SharedBufferServer( sp<SharedBufferServer> lcblk = new SharedBufferServer( sharedClient, token, mBufferManager.getDefaultBufferCount(), getIdentity()); status_t err = mUserClientRef.setToken(userClient, lcblk, token); if (err != NO_ERROR) { LOGE("ClientRef::setToken(%p, %p, %u) failed", userClient.get(), lcblk, token); delete lcblk; LOGE_IF(err != NO_ERROR, "ClientRef::setToken(%p, %p, %u) failed", userClient.get(), lcblk.get(), token); if (err == NO_ERROR) { // we need to free the buffers associated with this surface } return err; Loading @@ -95,6 +98,11 @@ int32_t Layer::getToken() const return mUserClientRef.getToken(); } sp<UserClient> Layer::getClient() const { return mUserClientRef.getClient(); } // called with SurfaceFlinger::mStateLock as soon as the layer is entered // in the purgatory list void Layer::onRemoved() Loading Loading @@ -626,11 +634,10 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const // --------------------------------------------------------------------------- Layer::ClientRef::ClientRef() : mToken(-1) { : mControlBlock(0), mToken(-1) { } Layer::ClientRef::~ClientRef() { delete lcblk; } int32_t Layer::ClientRef::getToken() const { Loading @@ -638,14 +645,25 @@ int32_t Layer::ClientRef::getToken() const { return mToken; } sp<UserClient> Layer::ClientRef::getClient() const { Mutex::Autolock _l(mLock); return mUserClient.promote(); } status_t Layer::ClientRef::setToken(const sp<UserClient>& uc, SharedBufferServer* sharedClient, int32_t token) { const sp<SharedBufferServer>& sharedClient, int32_t token) { Mutex::Autolock _l(mLock); if (mToken >= 0) return INVALID_OPERATION; { // scope for strong mUserClient reference sp<UserClient> userClient(mUserClient.promote()); if (mUserClient != 0 && mControlBlock != 0) { mControlBlock->setStatus(NO_INIT); } } mUserClient = uc; mToken = token; lcblk = sharedClient; mControlBlock = sharedClient; return NO_ERROR; } Loading @@ -657,12 +675,16 @@ sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { // it makes sure the UserClient (and its associated shared memory) // won't go away while we're accessing it. Layer::ClientRef::Access::Access(const ClientRef& ref) : lcblk(0) : mControlBlock(0) { Mutex::Autolock _l(ref.mLock); mUserClientStrongRef = ref.mUserClient.promote(); if (mUserClientStrongRef != 0) lcblk = ref.lcblk; mControlBlock = ref.mControlBlock; } Layer::ClientRef::Access::~Access() { } // --------------------------------------------------------------------------- Loading libs/surfaceflinger/Layer.h +7 −4 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ public: // associate a UserClient to this Layer status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx); int32_t getToken() const; sp<UserClient> getClient() const; // Set this Layer's buffers size void setBufferSize(uint32_t w, uint32_t h); Loading Loading @@ -119,24 +120,26 @@ private: ClientRef& operator = (const ClientRef& rhs); mutable Mutex mLock; // binder thread, page-flip thread SharedBufferServer* lcblk; sp<SharedBufferServer> mControlBlock; wp<UserClient> mUserClient; int32_t mToken; public: ClientRef(); ~ClientRef(); int32_t getToken() const; sp<UserClient> getClient() const; status_t setToken(const sp<UserClient>& uc, SharedBufferServer* sharedClient, int32_t token); const sp<SharedBufferServer>& sharedClient, int32_t token); sp<UserClient> getUserClientUnsafe() const; class Access { Access(const Access& rhs); Access& operator = (const Access& rhs); sp<UserClient> mUserClientStrongRef; SharedBufferServer* lcblk; sp<SharedBufferServer> mControlBlock; public: Access(const ClientRef& ref); inline SharedBufferServer* get() const { return lcblk; } ~Access(); inline SharedBufferServer* get() const { return mControlBlock.get(); } }; friend class Access; }; Loading libs/surfaceflinger/SurfaceFlinger.cpp +14 −5 Original line number Diff line number Diff line Loading @@ -1718,7 +1718,10 @@ void UserClient::detachLayer(const Layer* layer) { int32_t name = layer->getToken(); if (name >= 0) { android_atomic_and(~(1LU<<name), &mBitmap); int32_t mask = 1LU<<name; if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) { LOGW("token %d wasn't marked as used %08x", name, int(mBitmap)); } } } Loading @@ -1732,17 +1735,23 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const sp<Layer> layer(mFlinger->getLayer(sur)); if (layer == 0) return name; // this layer already has a token, just return it // FIXME: we should check that this token is for the same client // if this layer already has a token, just return it name = layer->getToken(); if (name >= 0) return name; if ((name >= 0) && (layer->getClient() == this)) return name; name = 0; do { int32_t mask = 1LU<<name; if ((android_atomic_or(mask, &mBitmap) & mask) == 0) { // we found and locked that name layer->setToken(const_cast<UserClient*>(this), ctrlblk, name); status_t err = layer->setToken( const_cast<UserClient*>(this), ctrlblk, name); if (err != NO_ERROR) { // free the name android_atomic_and(~mask, &mBitmap); name = err; } break; } if (++name > 31) Loading Loading
include/private/surfaceflinger/SharedBufferStack.h +6 −10 Original line number Diff line number Diff line Loading @@ -44,15 +44,6 @@ namespace android { * dequeue-able buffer. When these various conditions are not met, the caller * waits until the condition is met. * * * CAVEATS: * * In the current implementation there are several limitations: * - buffers must be locked in the same order they've been dequeued * - buffers must be enqueued in the same order they've been locked * - dequeue() is not reentrant * - no error checks are done on the condition above * */ // ---------------------------------------------------------------------------- Loading Loading @@ -269,7 +260,9 @@ private: // ---------------------------------------------------------------------------- class SharedBufferServer : public SharedBufferBase class SharedBufferServer : public SharedBufferBase, public LightRefBase<SharedBufferServer> { public: SharedBufferServer(SharedClient* sharedClient, int surface, int num, Loading @@ -290,6 +283,9 @@ public: private: friend class LightRefBase<SharedBufferServer>; ~SharedBufferServer(); /* * BufferList is basically a fixed-capacity sorted-vector of * unsigned 5-bits ints using a 32-bits int as storage. Loading
include/surfaceflinger/Surface.h +3 −3 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ public: static bool isSameSurface( const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); SurfaceID ID() const { return mToken; } uint32_t getFlags() const { return mFlags; } uint32_t getIdentity() const { return mIdentity; } Loading Loading @@ -145,6 +144,9 @@ public: uint32_t reserved[2]; }; static status_t writeToParcel( const sp<Surface>& control, Parcel* parcel); static sp<Surface> readFromParcel( const Parcel& data, const sp<Surface>& other); Loading @@ -153,7 +155,6 @@ public: } bool isValid(); SurfaceID ID() const { return mToken; } uint32_t getFlags() const { return mFlags; } uint32_t getIdentity() const { return mIdentity; } Loading Loading @@ -267,7 +268,6 @@ private: SharedBufferClient* mSharedBufferClient; status_t mInitCheck; sp<ISurface> mSurface; SurfaceID mToken; uint32_t mIdentity; PixelFormat mFormat; uint32_t mFlags; Loading
libs/surfaceflinger/Layer.cpp +35 −13 Original line number Diff line number Diff line Loading @@ -76,15 +76,18 @@ Layer::~Layer() status_t Layer::setToken(const sp<UserClient>& userClient, SharedClient* sharedClient, int32_t token) { SharedBufferServer* lcblk = new SharedBufferServer( sp<SharedBufferServer> lcblk = new SharedBufferServer( sharedClient, token, mBufferManager.getDefaultBufferCount(), getIdentity()); status_t err = mUserClientRef.setToken(userClient, lcblk, token); if (err != NO_ERROR) { LOGE("ClientRef::setToken(%p, %p, %u) failed", userClient.get(), lcblk, token); delete lcblk; LOGE_IF(err != NO_ERROR, "ClientRef::setToken(%p, %p, %u) failed", userClient.get(), lcblk.get(), token); if (err == NO_ERROR) { // we need to free the buffers associated with this surface } return err; Loading @@ -95,6 +98,11 @@ int32_t Layer::getToken() const return mUserClientRef.getToken(); } sp<UserClient> Layer::getClient() const { return mUserClientRef.getClient(); } // called with SurfaceFlinger::mStateLock as soon as the layer is entered // in the purgatory list void Layer::onRemoved() Loading Loading @@ -626,11 +634,10 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const // --------------------------------------------------------------------------- Layer::ClientRef::ClientRef() : mToken(-1) { : mControlBlock(0), mToken(-1) { } Layer::ClientRef::~ClientRef() { delete lcblk; } int32_t Layer::ClientRef::getToken() const { Loading @@ -638,14 +645,25 @@ int32_t Layer::ClientRef::getToken() const { return mToken; } sp<UserClient> Layer::ClientRef::getClient() const { Mutex::Autolock _l(mLock); return mUserClient.promote(); } status_t Layer::ClientRef::setToken(const sp<UserClient>& uc, SharedBufferServer* sharedClient, int32_t token) { const sp<SharedBufferServer>& sharedClient, int32_t token) { Mutex::Autolock _l(mLock); if (mToken >= 0) return INVALID_OPERATION; { // scope for strong mUserClient reference sp<UserClient> userClient(mUserClient.promote()); if (mUserClient != 0 && mControlBlock != 0) { mControlBlock->setStatus(NO_INIT); } } mUserClient = uc; mToken = token; lcblk = sharedClient; mControlBlock = sharedClient; return NO_ERROR; } Loading @@ -657,12 +675,16 @@ sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { // it makes sure the UserClient (and its associated shared memory) // won't go away while we're accessing it. Layer::ClientRef::Access::Access(const ClientRef& ref) : lcblk(0) : mControlBlock(0) { Mutex::Autolock _l(ref.mLock); mUserClientStrongRef = ref.mUserClient.promote(); if (mUserClientStrongRef != 0) lcblk = ref.lcblk; mControlBlock = ref.mControlBlock; } Layer::ClientRef::Access::~Access() { } // --------------------------------------------------------------------------- Loading
libs/surfaceflinger/Layer.h +7 −4 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ public: // associate a UserClient to this Layer status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx); int32_t getToken() const; sp<UserClient> getClient() const; // Set this Layer's buffers size void setBufferSize(uint32_t w, uint32_t h); Loading Loading @@ -119,24 +120,26 @@ private: ClientRef& operator = (const ClientRef& rhs); mutable Mutex mLock; // binder thread, page-flip thread SharedBufferServer* lcblk; sp<SharedBufferServer> mControlBlock; wp<UserClient> mUserClient; int32_t mToken; public: ClientRef(); ~ClientRef(); int32_t getToken() const; sp<UserClient> getClient() const; status_t setToken(const sp<UserClient>& uc, SharedBufferServer* sharedClient, int32_t token); const sp<SharedBufferServer>& sharedClient, int32_t token); sp<UserClient> getUserClientUnsafe() const; class Access { Access(const Access& rhs); Access& operator = (const Access& rhs); sp<UserClient> mUserClientStrongRef; SharedBufferServer* lcblk; sp<SharedBufferServer> mControlBlock; public: Access(const ClientRef& ref); inline SharedBufferServer* get() const { return lcblk; } ~Access(); inline SharedBufferServer* get() const { return mControlBlock.get(); } }; friend class Access; }; Loading
libs/surfaceflinger/SurfaceFlinger.cpp +14 −5 Original line number Diff line number Diff line Loading @@ -1718,7 +1718,10 @@ void UserClient::detachLayer(const Layer* layer) { int32_t name = layer->getToken(); if (name >= 0) { android_atomic_and(~(1LU<<name), &mBitmap); int32_t mask = 1LU<<name; if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) { LOGW("token %d wasn't marked as used %08x", name, int(mBitmap)); } } } Loading @@ -1732,17 +1735,23 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const sp<Layer> layer(mFlinger->getLayer(sur)); if (layer == 0) return name; // this layer already has a token, just return it // FIXME: we should check that this token is for the same client // if this layer already has a token, just return it name = layer->getToken(); if (name >= 0) return name; if ((name >= 0) && (layer->getClient() == this)) return name; name = 0; do { int32_t mask = 1LU<<name; if ((android_atomic_or(mask, &mBitmap) & mask) == 0) { // we found and locked that name layer->setToken(const_cast<UserClient*>(this), ctrlblk, name); status_t err = layer->setToken( const_cast<UserClient*>(this), ctrlblk, name); if (err != NO_ERROR) { // free the name android_atomic_and(~mask, &mBitmap); name = err; } break; } if (++name > 31) Loading