From 7eb670ae5357ea9f609e1630759a57ea31537271 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Thu, 15 Oct 2020 12:16:10 -0700 Subject: BlastBufferQueue: Add a function to flush the shadow queue If the function is called, the next queue buffer will wait until the the adapter processes the previously queued buffers. Test: enable blast and test split screen resize Change-Id: Ica9b3be9459dd174a7e80311abddb691976e83e3 --- libs/gui/BLASTBufferQueue.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'libs/gui/BLASTBufferQueue.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 87f797200c..c3f045e868 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -254,8 +254,8 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { if (rejectBuffer(bufferItem)) { BQA_LOGE("rejecting buffer:configured size=%dx%d, buffer{size=%dx%d transform=%d}", mWidth, mHeight, buffer->getWidth(), buffer->getHeight(), bufferItem.mTransform); - mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE); - return; + // TODO(b/168917217) temporarily don't reject buffers until we can synchronize buffer size + // changes from ViewRootImpl. } mNumAcquired++; @@ -307,13 +307,16 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& /*item*/) { std::unique_lock _lock{mMutex}; const bool nextTransactionSet = mNextTransaction != nullptr; - BQA_LOGV("onFrameAvailable nextTransactionSet=%s", toString(nextTransactionSet)); + BQA_LOGV("onFrameAvailable nextTransactionSet=%s mFlushShadowQueue=%s", + toString(nextTransactionSet), toString(mFlushShadowQueue)); - if (nextTransactionSet) { + if (nextTransactionSet || mFlushShadowQueue) { while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) { + BQA_LOGV("waiting in onFrameAvailable..."); mCallbackCV.wait(_lock); } } + mFlushShadowQueue = false; // add to shadow queue mNumFrameAvailable++; processNextBufferLocked(true); -- cgit v1.2.3-59-g8ed1b From bf25577c69c51ad2d1fc54532bb54510da5ddc7c Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Fri, 16 Oct 2020 10:54:41 -0700 Subject: BlastBufferQueue: Fix wait in onFrameAvailable Use the same logic in both onFrameAvailable and processNextBufferLocked to check if we can acquire a buffer. Otherwise, there is a chance we will not be waiting long enough in onFrameAvailable. Also add error logs if we return unexpectedly when trying to acquire a buffer. Test: go/wm-smoke with blast enabled Test: atest SurfaceViewBufferTests Change-Id: I2f8afa2fc2efb0371ccc86b422524e474e3f6170 Change-Id: Ibf2733725f7a4334eff38b516f0f5cec87dfd493 --- libs/gui/BLASTBufferQueue.cpp | 20 ++++++++++++++------ libs/gui/include/gui/BLASTBufferQueue.h | 5 +++-- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'libs/gui/BLASTBufferQueue.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index c3f045e868..0b942199c3 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -213,12 +213,9 @@ 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 maximum + // Wait to acquire a buffer if there are no frames available or we have acquired the max // 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. - if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1 || - (!mInitialCallbackReceived && mNumAcquired == 1)) { + if (mNumFrameAvailable == 0 || maxBuffersAcquired()) { BQA_LOGV("processNextBufferLocked waiting for frame available or callback"); return; } @@ -241,6 +238,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { status_t status = mBufferItemConsumer->acquireBuffer(&bufferItem, -1, false); if (status != OK) { + BQA_LOGE("Failed to acquire a buffer, err=%s", statusToString(status).c_str()); return; } auto buffer = bufferItem.mGraphicBuffer; @@ -248,6 +246,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { if (buffer == nullptr) { mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE); + BQA_LOGE("Buffer was empty"); return; } @@ -311,7 +310,7 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& /*item*/) { toString(nextTransactionSet), toString(mFlushShadowQueue)); if (nextTransactionSet || mFlushShadowQueue) { - while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) { + while (mNumFrameAvailable > 0 || maxBuffersAcquired()) { BQA_LOGV("waiting in onFrameAvailable..."); mCallbackCV.wait(_lock); } @@ -344,4 +343,13 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) const { // reject buffers if the buffer size doesn't match. return bufWidth != mWidth || bufHeight != mHeight; } + +// 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); +} + } // namespace android diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h index d1a0eece0d..634a7aa058 100644 --- a/libs/gui/include/gui/BLASTBufferQueue.h +++ b/libs/gui/include/gui/BLASTBufferQueue.h @@ -94,9 +94,10 @@ private: BLASTBufferQueue(const BLASTBufferQueue& rhs); void processNextBufferLocked(bool useNextTransaction) REQUIRES(mMutex); - Rect computeCrop(const BufferItem& item); + Rect computeCrop(const BufferItem& item) REQUIRES(mMutex); // Return true if we need to reject the buffer based on the scaling mode and the buffer size. - bool rejectBuffer(const BufferItem& item) const; + bool rejectBuffer(const BufferItem& item) const REQUIRES(mMutex); + bool maxBuffersAcquired() const REQUIRES(mMutex); std::string mName; sp mSurfaceControl; -- cgit v1.2.3-59-g8ed1b