From f7acf162f8d682c6ebc9af41ca76795b79509193 Mon Sep 17 00:00:00 2001 From: Jamie Gennis Date: Wed, 12 Jan 2011 18:30:40 -0800 Subject: Fix remote GraphicBuffer allocation in SurfaceFlinger. This change fixes a horrible hack that I did to allow application processes to create GraphicBuffer objects by making a binder call to SurfaceFlinger. This change introduces a new binder interface specifically for doing this, and does it in such a way that SurfaceFlinger will maintain a reference to the buffers until the app is done with them. Change-Id: Icb240397c6c206d7f69124c1497a829f051cb49b --- services/surfaceflinger/SurfaceFlinger.cpp | 57 ++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 19 deletions(-) (limited to 'services/surfaceflinger/SurfaceFlinger.cpp') diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index c982ea589634..967ff1a8362f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -144,6 +144,11 @@ sp SurfaceFlinger::createClientConnection() return bclient; } +sp SurfaceFlinger::createGraphicBufferAlloc() +{ + sp gba(new GraphicBufferAlloc()); + return gba; +} const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const { @@ -2267,25 +2272,6 @@ sp SurfaceFlinger::getLayer(const sp& sur) const // --------------------------------------------------------------------------- -sp SurfaceFlinger::createGraphicBuffer(uint32_t w, uint32_t h, - PixelFormat format, uint32_t usage) const { - // XXX: HACK HACK HACK!!! This should NOT be static, but it is to fix a - // race between SurfaceFlinger unref'ing the buffer and the client ref'ing - // it. - static sp graphicBuffer(new GraphicBuffer(w, h, format, usage)); - status_t err = graphicBuffer->initCheck(); - if (err != 0) { - LOGE("createGraphicBuffer: init check failed: %d", err); - return 0; - } else if (graphicBuffer->handle == 0) { - LOGE("createGraphicBuffer: unable to create GraphicBuffer"); - return 0; - } - return graphicBuffer; -} - -// --------------------------------------------------------------------------- - Client::Client(const sp& flinger) : mFlinger(flinger), mNameGenerator(1) { @@ -2465,6 +2451,39 @@ status_t UserClient::setState(int32_t count, const layer_state_t* states) { // --------------------------------------------------------------------------- +GraphicBufferAlloc::GraphicBufferAlloc() {} + +GraphicBufferAlloc::~GraphicBufferAlloc() {} + +sp GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, + PixelFormat format, uint32_t usage) { + sp graphicBuffer(new GraphicBuffer(w, h, format, usage)); + status_t err = graphicBuffer->initCheck(); + if (err != 0) { + LOGE("createGraphicBuffer: init check failed: %d", err); + return 0; + } else if (graphicBuffer->handle == 0) { + LOGE("createGraphicBuffer: unable to create GraphicBuffer"); + return 0; + } + Mutex::Autolock _l(mLock); + mBuffers.add(graphicBuffer); + return graphicBuffer; +} + +void GraphicBufferAlloc::freeAllGraphicBuffersExcept(int bufIdx) { + Mutex::Autolock _l(mLock); + if (0 <= bufIdx && bufIdx < mBuffers.size()) { + sp b(mBuffers[bufIdx]); + mBuffers.clear(); + mBuffers.add(b); + } else { + mBuffers.clear(); + } +} + +// --------------------------------------------------------------------------- + GraphicPlane::GraphicPlane() : mHw(0) { -- cgit v1.2.3-59-g8ed1b