From c4a40c1c522bb6607fb436d81c9ff32947a37328 Mon Sep 17 00:00:00 2001 From: Vishnu Nair Date: Wed, 23 Dec 2020 09:14:32 -0800 Subject: Added mergeWithNextTransaction to BlastBufferQueue Resurrected abandoned cl Ife2a8c9dbcfac7a5c3b294f64bc8dce40231f652 This is to support SurfaceView synchronizing transactions with ViewRootImpl. Currently, when SurfaceView gets a callback from PositionUpdateListener, it asks ViewRootImpl whether it's waiting on a sync transactions. If so, it will add the SV transactions to the sync transactions. Otherwise, it will apply the transaction on its own. By adding the new function mergeWithNextTransaction, SV can call into BlastBufferQueue and send its own transaction without having to know whether VRI is in a blast sync. As long as blast is enabled, it can always send its transaction to the BlastBufferQueue, which will apply it when the VRI frame comes in. Test: open bubbles with sv blast Test: atest SurfaceViewSyncTest Bug: 175594838 Change-Id: I1d1b6eb3bbcaa844f430dd3a2f7cfbe59e558909 --- libs/gui/BLASTBufferQueue.cpp | 44 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'libs/gui/BLASTBufferQueue.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index 3415d9db61..ee5552f20e 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -151,6 +151,19 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp(mPendingTransactions.size())); + SurfaceComposerClient::Transaction t; + for (auto& [targetFrameNumber, transaction] : mPendingTransactions) { + t.merge(std::move(transaction)); + } + t.apply(); +} + void BLASTBufferQueue::update(const sp& surface, uint32_t width, uint32_t height) { std::unique_lock _lock{mMutex}; mSurfaceControl = surface; @@ -312,6 +325,7 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { incStrong((void*)transactionCallbackThunk); mLastBufferScalingMode = bufferItem.mScalingMode; + mLastAcquiredFrameNumber = bufferItem.mFrameNumber; t->setBuffer(mSurfaceControl, buffer); t->setDataspace(mSurfaceControl, static_cast(bufferItem.mDataSpace)); @@ -341,14 +355,29 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { mAutoRefresh = bufferItem.mAutoRefresh; } + 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()); + if (applyTransaction) { t->apply(); } BQA_LOGV("processNextBufferLocked size=%dx%d mFrameNumber=%" PRIu64 - " applyTransaction=%s mTimestamp=%" PRId64, + " applyTransaction=%s mTimestamp=%" PRId64 " mPendingTransactions.size=%d", mSize.width, mSize.height, bufferItem.mFrameNumber, toString(applyTransaction), - bufferItem.mTimestamp); + bufferItem.mTimestamp, static_cast(mPendingTransactions.size())); } Rect BLASTBufferQueue::computeCrop(const BufferItem& item) { @@ -487,6 +516,17 @@ sp BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) { return new BBQSurface(mProducer, true, scHandle, this); } +void BLASTBufferQueue::mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, + uint64_t frameNumber) { + std::lock_guard _lock{mMutex}; + if (mLastAcquiredFrameNumber >= frameNumber) { + // Apply the transaction since we have already acquired the desired frame. + t->apply(); + } else { + mPendingTransactions.emplace_back(frameNumber, std::move(*t)); + } +} + // Maintains a single worker thread per process that services a list of runnables. class AsyncWorker : public Singleton { private: -- cgit v1.2.3-59-g8ed1b