summaryrefslogtreecommitdiff
path: root/libs/gui/BLASTBufferQueue.cpp
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2020-12-23 09:14:32 -0800
committer Vishnu Nair <vishnun@google.com> 2020-12-28 11:02:18 -0800
commitc4a40c1c522bb6607fb436d81c9ff32947a37328 (patch)
treeb32525754ea294357779280e4848eaad66923b84 /libs/gui/BLASTBufferQueue.cpp
parent13197182489ab3ed4ff4a57c685d40b35f0feaab (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.cpp44
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: