From 2672decb92fa24ef012cbbd3690c120530fa3cd3 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Tue, 13 Jun 2017 16:39:11 -0700 Subject: 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 --- libs/gui/BufferQueueProducer.cpp | 60 +++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 26 deletions(-) (limited to 'libs/gui/BufferQueueProducer.cpp') 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* outBuffer, return BAD_VALUE; } - Mutex::Autolock lock(mCore->mMutex); + sp 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; } -- cgit v1.2.3-59-g8ed1b