summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-06-15 07:11:38 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-06-15 07:11:38 +0000
commit913dd036191f1e2222cf977c47595eeb7af54ad6 (patch)
treee966c89782519c17878f644b51a72ccba5c3a34a
parentfa9d14517a20bc43b6d8b83ef53ccb6c3b0a7f03 (diff)
parentfd43dc6723e721c41fb5e0d84258672a036cc006 (diff)
downloadnative-913dd036191f1e2222cf977c47595eeb7af54ad6.tar.gz
release-request-bfd62fea-ae1d-4d0d-80fd-4ff0d407c488-for-git_oc-release-4102265 snap-temp-L40000000074340189
Change-Id: Ic2e51b29c8f89f4ba9ac0ec03effe8f318bda5d9
-rw-r--r--include/gui/IGraphicBufferConsumer.h2
-rw-r--r--libs/gui/BufferQueueProducer.cpp60
-rw-r--r--libs/gui/ConsumerBase.cpp13
3 files changed, 48 insertions, 27 deletions
diff --git a/include/gui/IGraphicBufferConsumer.h b/include/gui/IGraphicBufferConsumer.h
index 57cce16d10..3d069dfe48 100644
--- a/include/gui/IGraphicBufferConsumer.h
+++ b/include/gui/IGraphicBufferConsumer.h
@@ -267,6 +267,8 @@ public:
// discardFreeBuffers releases all currently-free buffers held by the BufferQueue, in order to
// reduce the memory consumption of the BufferQueue to the minimum possible without
// discarding data.
+ // The consumer invoking this method is responsible for calling getReleasedBuffers() after this
+ // call to free up any of its locally cached buffers.
virtual status_t discardFreeBuffers() = 0;
// dump state into a string
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 3d57769d1a..838586411d 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -632,40 +632,48 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
return BAD_VALUE;
}
- Mutex::Autolock lock(mCore->mMutex);
+ sp<IConsumerListener> listener;
+ {
+ Mutex::Autolock lock(mCore->mMutex);
- if (mCore->mIsAbandoned) {
- BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
- return NO_INIT;
- }
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
+ return NO_INIT;
+ }
- if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
- BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
- return NO_INIT;
- }
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
+ return NO_INIT;
+ }
- if (mCore->mSharedBufferMode) {
- BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer "
- "mode");
- return BAD_VALUE;
- }
+ if (mCore->mSharedBufferMode) {
+ BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer "
+ "mode");
+ return BAD_VALUE;
+ }
- mCore->waitWhileAllocatingLocked();
+ mCore->waitWhileAllocatingLocked();
- if (mCore->mFreeBuffers.empty()) {
- return NO_MEMORY;
- }
+ if (mCore->mFreeBuffers.empty()) {
+ return NO_MEMORY;
+ }
- int found = mCore->mFreeBuffers.front();
- mCore->mFreeBuffers.remove(found);
- mCore->mFreeSlots.insert(found);
+ int found = mCore->mFreeBuffers.front();
+ mCore->mFreeBuffers.remove(found);
+ mCore->mFreeSlots.insert(found);
- BQ_LOGV("detachNextBuffer detached slot %d", found);
+ BQ_LOGV("detachNextBuffer detached slot %d", found);
- *outBuffer = mSlots[found].mGraphicBuffer;
- *outFence = mSlots[found].mFence;
- mCore->clearBufferSlotLocked(found);
- VALIDATE_CONSISTENCY();
+ *outBuffer = mSlots[found].mGraphicBuffer;
+ *outFence = mSlots[found].mFence;
+ mCore->clearBufferSlotLocked(found);
+ VALIDATE_CONSISTENCY();
+ listener = mCore->mConsumerListener;
+ }
+
+ if (listener != NULL) {
+ listener->onBuffersReleased();
+ }
return NO_ERROR;
}
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 5c6158c771..c2b10a91dd 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -253,7 +253,18 @@ status_t ConsumerBase::discardFreeBuffers() {
CB_LOGE("discardFreeBuffers: ConsumerBase is abandoned!");
return NO_INIT;
}
- return mConsumer->discardFreeBuffers();
+ status_t err = mConsumer->discardFreeBuffers();
+ if (err != OK) {
+ return err;
+ }
+ uint64_t mask;
+ mConsumer->getReleasedBuffers(&mask);
+ for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
+ if (mask & (1ULL << i)) {
+ freeBufferLocked(i);
+ }
+ }
+ return OK;
}
void ConsumerBase::dumpState(String8& result) const {