From 1b20cde313b5ef8acdace742328df867956d24cb Mon Sep 17 00:00:00 2001 From: Jamie Gennis Date: Wed, 2 Feb 2011 15:31:47 -0800 Subject: [PATCH] Pass the IGraphicBufferAlloc to SurfaceTextureClient. This change passes a reference to the IGraphicBufferAlloc binder object to SurfaceTextureClient objects. When STC objects are created they query their associated ISurfaceTexture object for the IGraphicBufferAlloc that the SurfaceTexture uses to allocate buffers. Having the SurfaceTextureClient hold this reference prevents the GraphicBufferAlloc in SurfaceFlinger from freeing the allocated buffers before the SurfaceTextureClient is done with them. Change-Id: Ib8e30e8b37fdd60438cbb4cb7e9174d0ba6d661c related-bug: 3362519 --- include/gui/ISurfaceTexture.h | 6 ++++++ include/gui/SurfaceTexture.h | 6 ++++++ include/gui/SurfaceTextureClient.h | 4 ++++ libs/gui/ISurfaceTexture.cpp | 14 ++++++++++++++ libs/gui/SurfaceTexture.cpp | 5 +++++ libs/gui/SurfaceTextureClient.cpp | 7 +++++-- 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h index 77d37f13c..168310cf0 100644 --- a/include/gui/ISurfaceTexture.h +++ b/include/gui/ISurfaceTexture.h @@ -72,6 +72,12 @@ public: virtual status_t setCrop(const Rect& reg) = 0; virtual status_t setTransform(uint32_t transform) = 0; + + // getAllocator retrieves the binder object that must be referenced as long + // as the GraphicBuffers dequeued from this ISurfaceTexture are referenced. + // Holding this binder reference prevents SurfaceFlinger from freeing the + // buffers before the client is done with them. + virtual sp getAllocator() = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h index 79c33f54f..31615d008 100644 --- a/include/gui/SurfaceTexture.h +++ b/include/gui/SurfaceTexture.h @@ -101,6 +101,12 @@ public: // when a new frame becomes available. void setFrameAvailableListener(const sp& l); + // getAllocator retrieves the binder object that must be referenced as long + // as the GraphicBuffers dequeued from this SurfaceTexture are referenced. + // Holding this binder reference prevents SurfaceFlinger from freeing the + // buffers before the client is done with them. + sp getAllocator(); + private: // freeAllBuffers frees the resources (both GraphicBuffer and EGLImage) for diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h index dd1d490ae..ff2251d89 100644 --- a/include/gui/SurfaceTextureClient.h +++ b/include/gui/SurfaceTextureClient.h @@ -83,6 +83,10 @@ private: // interactions with the server using this interface. sp mSurfaceTexture; + // mAllocator is the binder object that is referenced to prevent the + // dequeued buffers from being freed prematurely. + sp mAllocator; + // mSlots stores the buffers that have been allocated for each buffer slot. // It is initialized to null pointers, and gets filled in with the result of // ISurfaceTexture::requestBuffer when the client dequeues a buffer from a diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp index 90bca3ca4..d661fd579 100644 --- a/libs/gui/ISurfaceTexture.cpp +++ b/libs/gui/ISurfaceTexture.cpp @@ -38,6 +38,7 @@ enum { CANCEL_BUFFER, SET_CROP, SET_TRANSFORM, + GET_ALLOCATOR, }; @@ -123,6 +124,13 @@ public: status_t result = reply.readInt32(); return result; } + + virtual sp getAllocator() { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); + remote()->transact(GET_ALLOCATOR, data, &reply); + return reply.readStrongBinder(); + } }; IMPLEMENT_META_INTERFACE(SurfaceTexture, "android.gui.SurfaceTexture"); @@ -195,6 +203,12 @@ status_t BnSurfaceTexture::onTransact( reply->writeInt32(result); return NO_ERROR; } break; + case GET_ALLOCATOR: { + CHECK_INTERFACE(ISurfaceTexture, data, reply); + sp result = getAllocator(); + reply->writeStrongBinder(result); + return NO_ERROR; + } break; } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index 1dadd5389..3c4b565d4 100644 --- a/libs/gui/SurfaceTexture.cpp +++ b/libs/gui/SurfaceTexture.cpp @@ -304,6 +304,11 @@ void SurfaceTexture::setFrameAvailableListener( mFrameAvailableListener = l; } +sp SurfaceTexture::getAllocator() { + LOGV("SurfaceTexture::getAllocator"); + return mGraphicBufferAlloc->asBinder(); +} + void SurfaceTexture::freeAllBuffers() { for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { mSlots[i].mGraphicBuffer = 0; diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp index 50cbdb8f3..ee14ac900 100644 --- a/libs/gui/SurfaceTextureClient.cpp +++ b/libs/gui/SurfaceTextureClient.cpp @@ -25,8 +25,8 @@ namespace android { SurfaceTextureClient::SurfaceTextureClient( const sp& surfaceTexture): - mSurfaceTexture(surfaceTexture), mReqWidth(1), mReqHeight(1), - mReqFormat(DEFAULT_FORMAT), mReqUsage(0), mMutex() { + mSurfaceTexture(surfaceTexture), mAllocator(0), mReqWidth(1), + mReqHeight(1), mReqFormat(DEFAULT_FORMAT), mReqUsage(0), mMutex() { // Initialize the ANativeWindow function pointers. ANativeWindow::setSwapInterval = setSwapInterval; ANativeWindow::dequeueBuffer = dequeueBuffer; @@ -35,6 +35,9 @@ SurfaceTextureClient::SurfaceTextureClient( ANativeWindow::queueBuffer = queueBuffer; ANativeWindow::query = query; ANativeWindow::perform = perform; + + // Get a reference to the allocator. + mAllocator = mSurfaceTexture->getAllocator(); } int SurfaceTextureClient::setSwapInterval(ANativeWindow* window, int interval) {