diff options
Diffstat (limited to 'libs/gui/BLASTBufferQueue.cpp')
-rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 0a3d44d336..f9b152cce5 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -248,7 +248,7 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence mPendingReleaseItem.item = std::move(mSubmitted.front()); mSubmitted.pop(); - processNextBufferLocked(false); + processNextBufferLocked(false /* useNextTransaction */); currFrameNumber = mPendingReleaseItem.item.mFrameNumber; if (mTransactionCompleteCallback && mTransactionCompleteFrameNumber == currFrameNumber) { @@ -269,9 +269,10 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { ATRACE_CALL(); BQA_LOGV("processNextBufferLocked useNextTransaction=%s", toString(useNextTransaction)); - // Wait to acquire a buffer if there are no frames available or we have acquired the max - // number of buffers. - if (mNumFrameAvailable == 0 || maxBuffersAcquired()) { + // If the next transaction is set, we want to guarantee the our acquire will not fail, so don't + // include the extra buffer when checking if we can acquire the next buffer. + const bool includeExtraAcquire = !useNextTransaction; + if (mNumFrameAvailable == 0 || maxBuffersAcquired(includeExtraAcquire)) { BQA_LOGV("processNextBufferLocked waiting for frame available or callback"); mCallbackCV.notify_all(); return; @@ -295,7 +296,10 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { status_t status = mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false); - if (status != OK) { + if (status == BufferQueue::NO_BUFFER_AVAILABLE) { + BQA_LOGV("Failed to acquire a buffer, err=NO_BUFFER_AVAILABLE"); + return; + } else if (status != OK) { BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str()); return; } @@ -414,7 +418,7 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { item.mFrameNumber, toString(nextTransactionSet), toString(mFlushShadowQueue)); if (nextTransactionSet || mFlushShadowQueue) { - while (mNumFrameAvailable > 0 || maxBuffersAcquired()) { + while (mNumFrameAvailable > 0 || maxBuffersAcquired(false /* includeExtraAcquire */)) { BQA_LOGV("waiting in onFrameAvailable..."); mCallbackCV.wait(_lock); } @@ -422,7 +426,7 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) { mFlushShadowQueue = false; // add to shadow queue mNumFrameAvailable++; - processNextBufferLocked(true); + processNextBufferLocked(nextTransactionSet /* useNextTransaction */); } void BLASTBufferQueue::onFrameReplaced(const BufferItem& item) { @@ -482,9 +486,12 @@ void BLASTBufferQueue::setTransactionCompleteCallback( // Check if we have acquired the maximum number of buffers. // As a special case, we wait for the first callback before acquiring the second buffer so we // can ensure the first buffer is presented if multiple buffers are queued in succession. -bool BLASTBufferQueue::maxBuffersAcquired() const { - return mNumAcquired == MAX_ACQUIRED_BUFFERS + 1 || - (!mInitialCallbackReceived && mNumAcquired == 1); +// Consumer can acquire an additional buffer if that buffer is not droppable. Set +// includeExtraAcquire is true to include this buffer to the count. Since this depends on the state +// of the buffer, the next acquire may return with NO_BUFFER_AVAILABLE. +bool BLASTBufferQueue::maxBuffersAcquired(bool includeExtraAcquire) const { + int maxAcquiredBuffers = MAX_ACQUIRED_BUFFERS + (includeExtraAcquire ? 2 : 1); + return mNumAcquired == maxAcquiredBuffers || (!mInitialCallbackReceived && mNumAcquired == 1); } class BBQSurface : public Surface { @@ -654,7 +661,8 @@ void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer LOG_ALWAYS_FATAL_IF(producer == nullptr, "BLASTBufferQueue: failed to create BBQBufferQueueProducer"); - sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core)); + sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core)); + consumer->setAllowExtraAcquire(true); LOG_ALWAYS_FATAL_IF(consumer == nullptr, "BLASTBufferQueue: failed to create BufferQueueConsumer"); |