summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2017-06-14 08:09:40 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2017-06-14 08:09:42 +0000
commitfd43dc6723e721c41fb5e0d84258672a036cc006 (patch)
treee966c89782519c17878f644b51a72ccba5c3a34a
parent638055ef41f6d248290c8867dd85c8a4690fa584 (diff)
parentc6ff79830b9126f948791f03164a58ad079e9e5d (diff)
downloadnative-fd43dc6723e721c41fb5e0d84258672a036cc006.tar.gz
Merge changes Ibc1444b8,I14c200d1 into oc-dev
* changes: ConsumerBase: discardFreeBuffers() also needs to dump its own cache BufferQueueProducer: Call onBuffersReleased() in detachNextBuffer
-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 {