diff options
author | 2014-11-04 11:37:46 -0800 | |
---|---|---|
committer | 2014-11-07 10:39:13 -0800 | |
commit | 8dc55396fc9bc425b5e2c82e76a38080f2a655ff (patch) | |
tree | 36dfc0172e525db15531c9074a81096862287edf /libs/gui/BufferQueueProducer.cpp | |
parent | 793fc0e13d25bdecda1219999f8be2cb3c121d20 (diff) |
Add a BufferItem parameter to onFrameAvailable
Passes the BufferItem for the queued buffer to the onFrameAvailable
callback so the consumer can track the BufferQueue's contents. Also
adds an onFrameReplaced callback, which is necessary if the consumer
wants to do anything more than simple queue length tracking.
Bug: 18111837
Change-Id: If9d07229c9b586c668e5f99074e9b63b0468feb0
Diffstat (limited to 'libs/gui/BufferQueueProducer.cpp')
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 284ddb2bf4..4d3b008dff 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -39,7 +39,11 @@ BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) : mSlots(core->mSlots), mConsumerName(), mStickyTransform(0), - mLastQueueBufferFence(Fence::NO_FENCE) {} + mLastQueueBufferFence(Fence::NO_FENCE), + mCallbackMutex(), + mNextCallbackTicket(0), + mCurrentCallbackTicket(0), + mCallbackCondition() {} BufferQueueProducer::~BufferQueueProducer() {} @@ -542,7 +546,10 @@ status_t BufferQueueProducer::queueBuffer(int slot, return BAD_VALUE; } - sp<IConsumerListener> listener; + sp<IConsumerListener> frameAvailableListener; + sp<IConsumerListener> frameReplacedListener; + int callbackTicket = 0; + BufferItem item; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); @@ -598,7 +605,6 @@ status_t BufferQueueProducer::queueBuffer(int slot, ++mCore->mFrameCounter; mSlots[slot].mFrameNumber = mCore->mFrameCounter; - BufferItem item; item.mAcquireCalled = mSlots[slot].mAcquireCalled; item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; item.mCrop = crop; @@ -619,7 +625,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, // When the queue is empty, we can ignore mDequeueBufferCannotBlock // and simply queue this buffer mCore->mQueue.push_back(item); - listener = mCore->mConsumerListener; + frameAvailableListener = mCore->mConsumerListener; } else { // When the queue is not empty, we need to look at the front buffer // state to see if we need to replace it @@ -635,9 +641,10 @@ status_t BufferQueueProducer::queueBuffer(int slot, } // Overwrite the droppable buffer with the incoming one *front = item; + frameReplacedListener = mCore->mConsumerListener; } else { mCore->mQueue.push_back(item); - listener = mCore->mConsumerListener; + frameAvailableListener = mCore->mConsumerListener; } } @@ -648,6 +655,9 @@ status_t BufferQueueProducer::queueBuffer(int slot, mCore->mTransformHint, mCore->mQueue.size()); ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); + + // Take a ticket for the callback functions + callbackTicket = mNextCallbackTicket++; } // Autolock scope // Wait without lock held @@ -659,9 +669,27 @@ status_t BufferQueueProducer::queueBuffer(int slot, mLastQueueBufferFence = fence; } - // Call back without lock held - if (listener != NULL) { - listener->onFrameAvailable(); + // Don't send the GraphicBuffer through the callback, and don't send + // the slot number, since the consumer shouldn't need it + item.mGraphicBuffer.clear(); + item.mSlot = BufferItem::INVALID_BUFFER_SLOT; + + // Call back without the main BufferQueue lock held, but with the callback + // lock held so we can ensure that callbacks occur in order + { + Mutex::Autolock lock(mCallbackMutex); + while (callbackTicket != mCurrentCallbackTicket) { + mCallbackCondition.wait(mCallbackMutex); + } + + if (frameAvailableListener != NULL) { + frameAvailableListener->onFrameAvailable(item); + } else if (frameReplacedListener != NULL) { + frameReplacedListener->onFrameReplaced(item); + } + + ++mCurrentCallbackTicket; + mCallbackCondition.broadcast(); } return NO_ERROR; |