diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2017-06-13 16:39:11 -0700 |
---|---|---|
committer | Eino-Ville Talvala <etalvala@google.com> | 2017-06-13 16:39:11 -0700 |
commit | 2672decb92fa24ef012cbbd3690c120530fa3cd3 (patch) | |
tree | b3cc68a6ce90b8aac7a1c2d86c3295154aad6ab8 | |
parent | 2563c0f3b0aa07309d42c0d739880884b8131080 (diff) | |
download | native-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.cpp | 60 |
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; } |