diff options
Diffstat (limited to 'libs/surfaceflinger')
-rw-r--r-- | libs/surfaceflinger/Layer.cpp | 34 | ||||
-rw-r--r-- | libs/surfaceflinger/Layer.h | 2 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBase.cpp | 5 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBase.h | 2 |
4 files changed, 43 insertions, 0 deletions
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 71573ac..1fe997d 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -208,6 +208,30 @@ void Layer::onDraw(const Region& clip) const 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> buffer; @@ -642,6 +666,16 @@ sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) 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; +} + // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index 26fb6c6..80fbd6a 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -89,6 +89,7 @@ private: uint32_t getEffectiveUsage(uint32_t usage) const; sp<GraphicBuffer> requestBuffer(int index, int usage); + status_t setBufferCount(int bufferCount); void destroy(); class SurfaceLayer : public LayerBaseClient::Surface { @@ -98,6 +99,7 @@ private: ~SurfaceLayer(); private: virtual sp<GraphicBuffer> requestBuffer(int index, int usage); + virtual status_t setBufferCount(int bufferCount); sp<Layer> getOwner() const { return static_cast<Layer*>(Surface::getOwner().get()); } diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 7d8d43f..63b9520 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -621,6 +621,11 @@ sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) return NULL; } +status_t LayerBaseClient::Surface::setBufferCount(int bufferCount) +{ + return INVALID_OPERATION; +} + status_t LayerBaseClient::Surface::registerBuffers( const ISurface::BufferHeap& buffers) { diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index c500dcf..53b848f 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -302,6 +302,8 @@ public: private: virtual sp<GraphicBuffer> requestBuffer(int index, int usage); + virtual status_t setBufferCount(int bufferCount); + virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); virtual void postBuffer(ssize_t offset); virtual void unregisterBuffers(); |