diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index 756cd61de..995ed5e81 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -22,6 +22,7 @@ #include #include #include +#include namespace android { @@ -261,42 +262,52 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, return BAD_VALUE; } - Mutex::Autolock lock(mCore->mMutex); + sp listener; + { // Autolock scope + Mutex::Autolock lock(mCore->mMutex); - // If the frame number has changed because the buffer has been reallocated, - // we can ignore this releaseBuffer for the old buffer - if (frameNumber != mSlots[slot].mFrameNumber) { - return STALE_BUFFER_SLOT; - } + // If the frame number has changed because the buffer has been reallocated, + // we can ignore this releaseBuffer for the old buffer + if (frameNumber != mSlots[slot].mFrameNumber) { + return STALE_BUFFER_SLOT; + } - // Make sure this buffer hasn't been queued while acquired by the consumer - BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin()); - while (current != mCore->mQueue.end()) { - if (current->mSlot == slot) { - BQ_LOGE("releaseBuffer: buffer slot %d pending release is " - "currently queued", slot); + // Make sure this buffer hasn't been queued while acquired by the consumer + BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin()); + while (current != mCore->mQueue.end()) { + if (current->mSlot == slot) { + BQ_LOGE("releaseBuffer: buffer slot %d pending release is " + "currently queued", slot); + return BAD_VALUE; + } + ++current; + } + + if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { + mSlots[slot].mEglDisplay = eglDisplay; + mSlots[slot].mEglFence = eglFence; + mSlots[slot].mFence = releaseFence; + mSlots[slot].mBufferState = BufferSlot::FREE; + listener = mCore->mConnectedProducerListener; + BQ_LOGV("releaseBuffer: releasing slot %d", slot); + } else if (mSlots[slot].mNeedsCleanupOnRelease) { + BQ_LOGV("releaseBuffer: releasing a stale buffer slot %d " + "(state = %d)", slot, mSlots[slot].mBufferState); + mSlots[slot].mNeedsCleanupOnRelease = false; + return STALE_BUFFER_SLOT; + } else { + BQ_LOGV("releaseBuffer: attempted to release buffer slot %d " + "but its state was %d", slot, mSlots[slot].mBufferState); return BAD_VALUE; } - ++current; - } - if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { - mSlots[slot].mEglDisplay = eglDisplay; - mSlots[slot].mEglFence = eglFence; - mSlots[slot].mFence = releaseFence; - mSlots[slot].mBufferState = BufferSlot::FREE; - } else if (mSlots[slot].mNeedsCleanupOnRelease) { - BQ_LOGV("releaseBuffer: releasing a stale buffer slot %d " - "(state = %d)", slot, mSlots[slot].mBufferState); - mSlots[slot].mNeedsCleanupOnRelease = false; - return STALE_BUFFER_SLOT; - } else { - BQ_LOGV("releaseBuffer: attempted to release buffer slot %d " - "but its state was %d", slot, mSlots[slot].mBufferState); - return BAD_VALUE; - } + mCore->mDequeueCondition.broadcast(); + } // Autolock scope - mCore->mDequeueCondition.broadcast(); + // Call back without lock held + if (listener != NULL) { + listener->onBufferReleased(); + } return NO_ERROR; }