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