Loading include/gui/Surface.h +18 −0 Original line number Diff line number Diff line Loading @@ -257,10 +257,25 @@ public: virtual int query(int what, int* value) const; virtual int connect(int api, const sp<IProducerListener>& listener); // When reportBufferRemoval is true, clients must call getAndFlushRemovedBuffers to fetch // GraphicBuffers removed from this surface after a dequeueBuffer, detachNextBuffer or // attachBuffer call. This allows clients with their own buffer caches to free up buffers no // longer in use by this surface. virtual int connect( int api, const sp<IProducerListener>& listener, bool reportBufferRemoval); virtual int detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence); virtual int attachBuffer(ANativeWindowBuffer*); // When client connects to Surface with reportBufferRemoval set to true, any buffers removed // from this Surface will be collected and returned here. Once this method returns, these // buffers will no longer be referenced by this Surface unless they are attached to this // Surface later. The list of removed buffers will only be stored until the next dequeueBuffer, // detachNextBuffer, or attachBuffer call. status_t getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out); protected: enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS }; enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; Loading Loading @@ -414,6 +429,9 @@ protected: // A cached copy of the FrameEventHistory maintained by the consumer. bool mEnableFrameTimestamps = false; std::unique_ptr<ProducerFrameEventHistory> mFrameEventHistory; bool mReportRemovedBuffers = false; std::vector<sp<GraphicBuffer>> mRemovedBuffers; }; } // namespace android Loading libs/gui/Surface.cpp +35 −1 Original line number Diff line number Diff line Loading @@ -505,7 +505,11 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { mFrameEventHistory->applyDelta(frameTimestamps); } if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) { if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) { if (mReportRemovedBuffers && (gbuf != nullptr)) { mRemovedBuffers.clear(); mRemovedBuffers.push_back(gbuf); } result = mGraphicBufferProducer->requestBuffer(buf, &gbuf); if (result != NO_ERROR) { ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result); Loading Loading @@ -1075,10 +1079,16 @@ int Surface::connect(int api) { } int Surface::connect(int api, const sp<IProducerListener>& listener) { return connect(api, listener, false); } int Surface::connect( int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) { ATRACE_CALL(); ALOGV("Surface::connect"); Mutex::Autolock lock(mMutex); IGraphicBufferProducer::QueueBufferOutput output; mReportRemovedBuffers = reportBufferRemoval; int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); if (err == NO_ERROR) { mDefaultWidth = output.width; Loading Loading @@ -1109,6 +1119,7 @@ int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) { ATRACE_CALL(); ALOGV("Surface::disconnect"); Mutex::Autolock lock(mMutex); mRemovedBuffers.clear(); mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; mSharedBufferHasBeenQueued = false; freeAllBuffers(); Loading Loading @@ -1156,9 +1167,16 @@ int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer, *outFence = Fence::NO_FENCE; } if (mReportRemovedBuffers) { mRemovedBuffers.clear(); } for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { if (mSlots[i].buffer != NULL && mSlots[i].buffer->handle == buffer->handle) { if (mReportRemovedBuffers) { mRemovedBuffers.push_back(mSlots[i].buffer); } mSlots[i].buffer = NULL; } } Loading @@ -1184,6 +1202,10 @@ int Surface::attachBuffer(ANativeWindowBuffer* buffer) graphicBuffer->mGenerationNumber = priorGeneration; return result; } if (mReportRemovedBuffers && (mSlots[attachedSlot].buffer != nullptr)) { mRemovedBuffers.clear(); mRemovedBuffers.push_back(mSlots[attachedSlot].buffer); } mSlots[attachedSlot].buffer = graphicBuffer; return NO_ERROR; Loading Loading @@ -1617,4 +1639,16 @@ status_t Surface::getUniqueId(uint64_t* outId) const { return mGraphicBufferProducer->getUniqueId(outId); } status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) { if (out == nullptr) { ALOGE("%s: out must not be null!", __FUNCTION__); return BAD_VALUE; } Mutex::Autolock lock(mMutex); *out = mRemovedBuffers; mRemovedBuffers.clear(); return OK; } }; // namespace android Loading
include/gui/Surface.h +18 −0 Original line number Diff line number Diff line Loading @@ -257,10 +257,25 @@ public: virtual int query(int what, int* value) const; virtual int connect(int api, const sp<IProducerListener>& listener); // When reportBufferRemoval is true, clients must call getAndFlushRemovedBuffers to fetch // GraphicBuffers removed from this surface after a dequeueBuffer, detachNextBuffer or // attachBuffer call. This allows clients with their own buffer caches to free up buffers no // longer in use by this surface. virtual int connect( int api, const sp<IProducerListener>& listener, bool reportBufferRemoval); virtual int detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence); virtual int attachBuffer(ANativeWindowBuffer*); // When client connects to Surface with reportBufferRemoval set to true, any buffers removed // from this Surface will be collected and returned here. Once this method returns, these // buffers will no longer be referenced by this Surface unless they are attached to this // Surface later. The list of removed buffers will only be stored until the next dequeueBuffer, // detachNextBuffer, or attachBuffer call. status_t getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out); protected: enum { NUM_BUFFER_SLOTS = BufferQueueDefs::NUM_BUFFER_SLOTS }; enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; Loading Loading @@ -414,6 +429,9 @@ protected: // A cached copy of the FrameEventHistory maintained by the consumer. bool mEnableFrameTimestamps = false; std::unique_ptr<ProducerFrameEventHistory> mFrameEventHistory; bool mReportRemovedBuffers = false; std::vector<sp<GraphicBuffer>> mRemovedBuffers; }; } // namespace android Loading
libs/gui/Surface.cpp +35 −1 Original line number Diff line number Diff line Loading @@ -505,7 +505,11 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { mFrameEventHistory->applyDelta(frameTimestamps); } if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) { if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) { if (mReportRemovedBuffers && (gbuf != nullptr)) { mRemovedBuffers.clear(); mRemovedBuffers.push_back(gbuf); } result = mGraphicBufferProducer->requestBuffer(buf, &gbuf); if (result != NO_ERROR) { ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result); Loading Loading @@ -1075,10 +1079,16 @@ int Surface::connect(int api) { } int Surface::connect(int api, const sp<IProducerListener>& listener) { return connect(api, listener, false); } int Surface::connect( int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) { ATRACE_CALL(); ALOGV("Surface::connect"); Mutex::Autolock lock(mMutex); IGraphicBufferProducer::QueueBufferOutput output; mReportRemovedBuffers = reportBufferRemoval; int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); if (err == NO_ERROR) { mDefaultWidth = output.width; Loading Loading @@ -1109,6 +1119,7 @@ int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) { ATRACE_CALL(); ALOGV("Surface::disconnect"); Mutex::Autolock lock(mMutex); mRemovedBuffers.clear(); mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; mSharedBufferHasBeenQueued = false; freeAllBuffers(); Loading Loading @@ -1156,9 +1167,16 @@ int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer, *outFence = Fence::NO_FENCE; } if (mReportRemovedBuffers) { mRemovedBuffers.clear(); } for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { if (mSlots[i].buffer != NULL && mSlots[i].buffer->handle == buffer->handle) { if (mReportRemovedBuffers) { mRemovedBuffers.push_back(mSlots[i].buffer); } mSlots[i].buffer = NULL; } } Loading @@ -1184,6 +1202,10 @@ int Surface::attachBuffer(ANativeWindowBuffer* buffer) graphicBuffer->mGenerationNumber = priorGeneration; return result; } if (mReportRemovedBuffers && (mSlots[attachedSlot].buffer != nullptr)) { mRemovedBuffers.clear(); mRemovedBuffers.push_back(mSlots[attachedSlot].buffer); } mSlots[attachedSlot].buffer = graphicBuffer; return NO_ERROR; Loading Loading @@ -1617,4 +1639,16 @@ status_t Surface::getUniqueId(uint64_t* outId) const { return mGraphicBufferProducer->getUniqueId(outId); } status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) { if (out == nullptr) { ALOGE("%s: out must not be null!", __FUNCTION__); return BAD_VALUE; } Mutex::Autolock lock(mMutex); *out = mRemovedBuffers; mRemovedBuffers.clear(); return OK; } }; // namespace android