summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2017-06-13 16:39:11 -0700
committerEino-Ville Talvala <etalvala@google.com>2017-06-13 16:39:11 -0700
commit2672decb92fa24ef012cbbd3690c120530fa3cd3 (patch)
treeb3cc68a6ce90b8aac7a1c2d86c3295154aad6ab8
parent2563c0f3b0aa07309d42c0d739880884b8131080 (diff)
downloadnative-2672decb92fa24ef012cbbd3690c120530fa3cd3.tar.gz
BufferQueueProducer: Call onBuffersReleased() in detachNextBuffer
Like detachBuffer(), detachNextBuffer() needs to inform the consumer, who generally has a cache of buffer items, that a buffer is no longer owned by the buffer queue. Otherwise the consumer layer can leak the buffer reference until consumer teardown/disconnect. Test: Camera CTS is fine, using a camera app shows correct memory behavior Bug: 62591036 Change-Id: I14c200d13e60dbbe21261343941f84fb786db117
-rw-r--r--libs/gui/BufferQueueProducer.cpp60
1 files changed, 34 insertions, 26 deletions
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;
}