From 6a1952737262e9584098f37ade1f4406172c890f Mon Sep 17 00:00:00 2001 From: chaviw Date: Fri, 3 Sep 2021 16:14:25 -0500 Subject: Add applyPendingTransactions It's possible for a caller to request mergeWithNextTransaction, but the main frame had nothing new to draw. If that's the case, the mergeWithNextTransactions will be stuck and never applied (or applied much later). Since this could end up blocking Transactions, it's better to force apply these when we know a frame wasn't going to draw this vsync. Adding applyPendingTransactions to allows callers to force apply these transactions. Test: Existing tests pass Bug: 195262673 Change-Id: I3082b54e35dfae2b3f7fe589c6f665f781d8b07b --- libs/gui/BLASTBufferQueue.cpp | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) (limited to 'libs/gui/BLASTBufferQueue.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 982dd63a8c..379b090c5b 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -508,21 +508,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { } } - auto mergeTransaction = - [&t, currentFrameNumber = bufferItem.mFrameNumber]( - std::tuple pendingTransaction) { - auto& [targetFrameNumber, transaction] = pendingTransaction; - if (currentFrameNumber < targetFrameNumber) { - return false; - } - t->merge(std::move(transaction)); - return true; - }; - - mPendingTransactions.erase(std::remove_if(mPendingTransactions.begin(), - mPendingTransactions.end(), mergeTransaction), - mPendingTransactions.end()); - + mergePendingTransactions(t, bufferItem.mFrameNumber); if (applyTransaction) { t->setApplyToken(mApplyToken).apply(); } @@ -726,6 +712,32 @@ void BLASTBufferQueue::mergeWithNextTransaction(SurfaceComposerClient::Transacti } } +void BLASTBufferQueue::applyPendingTransactions(uint64_t frameNumber) { + std::lock_guard _lock{mMutex}; + + SurfaceComposerClient::Transaction t; + mergePendingTransactions(&t, frameNumber); + t.setApplyToken(mApplyToken).apply(); +} + +void BLASTBufferQueue::mergePendingTransactions(SurfaceComposerClient::Transaction* t, + uint64_t frameNumber) { + auto mergeTransaction = + [&t, currentFrameNumber = frameNumber]( + std::tuple pendingTransaction) { + auto& [targetFrameNumber, transaction] = pendingTransaction; + if (currentFrameNumber < targetFrameNumber) { + return false; + } + t->merge(std::move(transaction)); + return true; + }; + + mPendingTransactions.erase(std::remove_if(mPendingTransactions.begin(), + mPendingTransactions.end(), mergeTransaction), + mPendingTransactions.end()); +} + // Maintains a single worker thread per process that services a list of runnables. class AsyncWorker : public Singleton { private: -- cgit v1.2.3-59-g8ed1b