Loading include/private/surfaceflinger/SharedBufferStack.h +52 −3 Original line number Original line Diff line number Diff line Loading @@ -129,7 +129,7 @@ public: // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // 4 KB max // 32 KB max class SharedClient class SharedClient { { public: public: Loading Loading @@ -166,7 +166,7 @@ public: protected: protected: SharedClient* const mSharedClient; SharedClient* const mSharedClient; SharedBufferStack* const mSharedStack; SharedBufferStack* const mSharedStack; const int mNumBuffers; int mNumBuffers; const int mIdentity; const int mIdentity; int32_t computeTail() const; int32_t computeTail() const; Loading Loading @@ -217,6 +217,7 @@ public: bool needNewBuffer(int buffer) const; bool needNewBuffer(int buffer) const; status_t setDirtyRegion(int buffer, const Region& reg); status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); status_t setCrop(int buffer, const Rect& reg); status_t setBufferCount(int bufferCount); private: private: friend struct Condition; friend struct Condition; Loading Loading @@ -269,13 +270,61 @@ public: status_t reallocate(); status_t reallocate(); status_t assertReallocate(int buffer); status_t assertReallocate(int buffer); int32_t getQueuedCount() const; int32_t getQueuedCount() const; Region getDirtyRegion(int buffer) const; Region getDirtyRegion(int buffer) const; status_t resize(int newNumBuffers); SharedBufferStack::Statistics getStats() const; SharedBufferStack::Statistics getStats() const; private: private: /* * BufferList is basically a fixed-capacity sorted-vector of * unsigned 5-bits ints using a 32-bits int as storage. * it has efficient iterators to find items in the list and not in the list. */ class BufferList { size_t mCapacity; uint32_t mList; public: BufferList(size_t c = NUM_BUFFER_MAX) : mCapacity(c), mList(0) { } status_t add(int value); status_t remove(int value); class const_iterator { friend class BufferList; uint32_t mask, curr; const_iterator(uint32_t mask) : mask(mask), curr(31 - __builtin_clz(mask)) { } public: inline bool operator == (const const_iterator& rhs) const { return mask == rhs.mask; } inline bool operator != (const const_iterator& rhs) const { return mask != rhs.mask; } inline int operator *() const { return curr; } inline const const_iterator& operator ++(int) { mask &= ~curr; curr = 31 - __builtin_clz(mask); return *this; } }; inline const_iterator begin() const { return const_iterator(mList); } inline const_iterator end() const { return const_iterator(0); } inline const_iterator free_begin() const { uint32_t mask = (1 << (32-mCapacity)) - 1; return const_iterator( ~(mList | mask) ); } }; BufferList mBufferList; struct UnlockUpdate : public UpdateBase { struct UnlockUpdate : public UpdateBase { const int lockedBuffer; const int lockedBuffer; inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer); inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer); Loading include/surfaceflinger/ISurface.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -47,12 +47,14 @@ protected: POST_BUFFER, // one-way transaction POST_BUFFER, // one-way transaction CREATE_OVERLAY, CREATE_OVERLAY, REQUEST_BUFFER, REQUEST_BUFFER, SET_BUFFER_COUNT, }; }; public: public: DECLARE_META_INTERFACE(Surface); DECLARE_META_INTERFACE(Surface); virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0; virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0; virtual status_t setBufferCount(int bufferCount) = 0; class BufferHeap { class BufferHeap { public: public: Loading include/surfaceflinger/Surface.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -217,6 +217,7 @@ private: int connect(int api); int connect(int api); int disconnect(int api); int disconnect(int api); int crop(Rect const* rect); int crop(Rect const* rect); int setBufferCount(int bufferCount); /* /* * private stuff... * private stuff... Loading libs/surfaceflinger/Layer.cpp +34 −0 Original line number Original line Diff line number Diff line Loading @@ -208,6 +208,30 @@ void Layer::onDraw(const Region& clip) const drawWithOpenGL(clip, tex); drawWithOpenGL(clip, tex); } } status_t Layer::setBufferCount(int bufferCount) { // this ensures our client doesn't go away while we're accessing // the shared area. sp<Client> ourClient(client.promote()); if (ourClient == 0) { // oops, the client is already gone return DEAD_OBJECT; } status_t err; // FIXME: resize() below is NOT thread-safe, we need to synchronize // the users of lcblk in our process (ie: retire), and we assume the // client is not mucking with the SharedStack, which is only enforced // by construction, therefore we need to protect ourselves against // buggy and malicious client (as always) err = lcblk->resize(bufferCount); return err; } sp<GraphicBuffer> Layer::requestBuffer(int index, int usage) sp<GraphicBuffer> Layer::requestBuffer(int index, int usage) { { sp<GraphicBuffer> buffer; sp<GraphicBuffer> buffer; Loading Loading @@ -642,6 +666,16 @@ sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) return buffer; return buffer; } } status_t Layer::SurfaceLayer::setBufferCount(int bufferCount) { status_t err = DEAD_OBJECT; sp<Layer> owner(getOwner()); if (owner != 0) { err = owner->setBufferCount(bufferCount); } return err; } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading libs/surfaceflinger/Layer.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -89,6 +89,7 @@ private: uint32_t getEffectiveUsage(uint32_t usage) const; uint32_t getEffectiveUsage(uint32_t usage) const; sp<GraphicBuffer> requestBuffer(int index, int usage); sp<GraphicBuffer> requestBuffer(int index, int usage); status_t setBufferCount(int bufferCount); void destroy(); void destroy(); class SurfaceLayer : public LayerBaseClient::Surface { class SurfaceLayer : public LayerBaseClient::Surface { Loading @@ -98,6 +99,7 @@ private: ~SurfaceLayer(); ~SurfaceLayer(); private: private: virtual sp<GraphicBuffer> requestBuffer(int index, int usage); virtual sp<GraphicBuffer> requestBuffer(int index, int usage); virtual status_t setBufferCount(int bufferCount); sp<Layer> getOwner() const { sp<Layer> getOwner() const { return static_cast<Layer*>(Surface::getOwner().get()); return static_cast<Layer*>(Surface::getOwner().get()); } } Loading Loading
include/private/surfaceflinger/SharedBufferStack.h +52 −3 Original line number Original line Diff line number Diff line Loading @@ -129,7 +129,7 @@ public: // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // 4 KB max // 32 KB max class SharedClient class SharedClient { { public: public: Loading Loading @@ -166,7 +166,7 @@ public: protected: protected: SharedClient* const mSharedClient; SharedClient* const mSharedClient; SharedBufferStack* const mSharedStack; SharedBufferStack* const mSharedStack; const int mNumBuffers; int mNumBuffers; const int mIdentity; const int mIdentity; int32_t computeTail() const; int32_t computeTail() const; Loading Loading @@ -217,6 +217,7 @@ public: bool needNewBuffer(int buffer) const; bool needNewBuffer(int buffer) const; status_t setDirtyRegion(int buffer, const Region& reg); status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); status_t setCrop(int buffer, const Rect& reg); status_t setBufferCount(int bufferCount); private: private: friend struct Condition; friend struct Condition; Loading Loading @@ -269,13 +270,61 @@ public: status_t reallocate(); status_t reallocate(); status_t assertReallocate(int buffer); status_t assertReallocate(int buffer); int32_t getQueuedCount() const; int32_t getQueuedCount() const; Region getDirtyRegion(int buffer) const; Region getDirtyRegion(int buffer) const; status_t resize(int newNumBuffers); SharedBufferStack::Statistics getStats() const; SharedBufferStack::Statistics getStats() const; private: private: /* * BufferList is basically a fixed-capacity sorted-vector of * unsigned 5-bits ints using a 32-bits int as storage. * it has efficient iterators to find items in the list and not in the list. */ class BufferList { size_t mCapacity; uint32_t mList; public: BufferList(size_t c = NUM_BUFFER_MAX) : mCapacity(c), mList(0) { } status_t add(int value); status_t remove(int value); class const_iterator { friend class BufferList; uint32_t mask, curr; const_iterator(uint32_t mask) : mask(mask), curr(31 - __builtin_clz(mask)) { } public: inline bool operator == (const const_iterator& rhs) const { return mask == rhs.mask; } inline bool operator != (const const_iterator& rhs) const { return mask != rhs.mask; } inline int operator *() const { return curr; } inline const const_iterator& operator ++(int) { mask &= ~curr; curr = 31 - __builtin_clz(mask); return *this; } }; inline const_iterator begin() const { return const_iterator(mList); } inline const_iterator end() const { return const_iterator(0); } inline const_iterator free_begin() const { uint32_t mask = (1 << (32-mCapacity)) - 1; return const_iterator( ~(mList | mask) ); } }; BufferList mBufferList; struct UnlockUpdate : public UpdateBase { struct UnlockUpdate : public UpdateBase { const int lockedBuffer; const int lockedBuffer; inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer); inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer); Loading
include/surfaceflinger/ISurface.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -47,12 +47,14 @@ protected: POST_BUFFER, // one-way transaction POST_BUFFER, // one-way transaction CREATE_OVERLAY, CREATE_OVERLAY, REQUEST_BUFFER, REQUEST_BUFFER, SET_BUFFER_COUNT, }; }; public: public: DECLARE_META_INTERFACE(Surface); DECLARE_META_INTERFACE(Surface); virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0; virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0; virtual status_t setBufferCount(int bufferCount) = 0; class BufferHeap { class BufferHeap { public: public: Loading
include/surfaceflinger/Surface.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -217,6 +217,7 @@ private: int connect(int api); int connect(int api); int disconnect(int api); int disconnect(int api); int crop(Rect const* rect); int crop(Rect const* rect); int setBufferCount(int bufferCount); /* /* * private stuff... * private stuff... Loading
libs/surfaceflinger/Layer.cpp +34 −0 Original line number Original line Diff line number Diff line Loading @@ -208,6 +208,30 @@ void Layer::onDraw(const Region& clip) const drawWithOpenGL(clip, tex); drawWithOpenGL(clip, tex); } } status_t Layer::setBufferCount(int bufferCount) { // this ensures our client doesn't go away while we're accessing // the shared area. sp<Client> ourClient(client.promote()); if (ourClient == 0) { // oops, the client is already gone return DEAD_OBJECT; } status_t err; // FIXME: resize() below is NOT thread-safe, we need to synchronize // the users of lcblk in our process (ie: retire), and we assume the // client is not mucking with the SharedStack, which is only enforced // by construction, therefore we need to protect ourselves against // buggy and malicious client (as always) err = lcblk->resize(bufferCount); return err; } sp<GraphicBuffer> Layer::requestBuffer(int index, int usage) sp<GraphicBuffer> Layer::requestBuffer(int index, int usage) { { sp<GraphicBuffer> buffer; sp<GraphicBuffer> buffer; Loading Loading @@ -642,6 +666,16 @@ sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) return buffer; return buffer; } } status_t Layer::SurfaceLayer::setBufferCount(int bufferCount) { status_t err = DEAD_OBJECT; sp<Layer> owner(getOwner()); if (owner != 0) { err = owner->setBufferCount(bufferCount); } return err; } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading
libs/surfaceflinger/Layer.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -89,6 +89,7 @@ private: uint32_t getEffectiveUsage(uint32_t usage) const; uint32_t getEffectiveUsage(uint32_t usage) const; sp<GraphicBuffer> requestBuffer(int index, int usage); sp<GraphicBuffer> requestBuffer(int index, int usage); status_t setBufferCount(int bufferCount); void destroy(); void destroy(); class SurfaceLayer : public LayerBaseClient::Surface { class SurfaceLayer : public LayerBaseClient::Surface { Loading @@ -98,6 +99,7 @@ private: ~SurfaceLayer(); ~SurfaceLayer(); private: private: virtual sp<GraphicBuffer> requestBuffer(int index, int usage); virtual sp<GraphicBuffer> requestBuffer(int index, int usage); virtual status_t setBufferCount(int bufferCount); sp<Layer> getOwner() const { sp<Layer> getOwner() const { return static_cast<Layer*>(Surface::getOwner().get()); return static_cast<Layer*>(Surface::getOwner().get()); } } Loading