summaryrefslogtreecommitdiff
path: root/libs/gui/BLASTBufferQueue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/gui/BLASTBufferQueue.cpp')
-rw-r--r--libs/gui/BLASTBufferQueue.cpp30
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");