diff options
| author | 2020-12-23 09:14:32 -0800 | |
|---|---|---|
| committer | 2020-12-28 11:02:18 -0800 | |
| commit | c4a40c1c522bb6607fb436d81c9ff32947a37328 (patch) | |
| tree | b32525754ea294357779280e4848eaad66923b84 /libs/gui/BLASTBufferQueue.cpp | |
| parent | 13197182489ab3ed4ff4a57c685d40b35f0feaab (diff) | |
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
Diffstat (limited to 'libs/gui/BLASTBufferQueue.cpp')
| -rw-r--r-- | libs/gui/BLASTBufferQueue.cpp | 44 |
1 files changed, 42 insertions, 2 deletions
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<SurfaceCont mPendingReleaseItem.releaseFence = nullptr; } +BLASTBufferQueue::~BLASTBufferQueue() { + if (mPendingTransactions.empty()) { + return; + } + BQA_LOGE("Applying pending transactions on dtor %d", + static_cast<uint32_t>(mPendingTransactions.size())); + SurfaceComposerClient::Transaction t; + for (auto& [targetFrameNumber, transaction] : mPendingTransactions) { + t.merge(std::move(transaction)); + } + t.apply(); +} + void BLASTBufferQueue::update(const sp<SurfaceControl>& 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<ui::Dataspace>(bufferItem.mDataSpace)); @@ -341,14 +355,29 @@ void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) { mAutoRefresh = bufferItem.mAutoRefresh; } + auto mergeTransaction = + [&t, currentFrameNumber = bufferItem.mFrameNumber]( + std::tuple<uint64_t, SurfaceComposerClient::Transaction> 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<uint32_t>(mPendingTransactions.size())); } Rect BLASTBufferQueue::computeCrop(const BufferItem& item) { @@ -487,6 +516,17 @@ sp<Surface> 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<AsyncWorker> { private: |