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) {