From 3b4bdcf601ef90634c172ce239fc75ddd5b63b84 Mon Sep 17 00:00:00 2001 From: chaviw Date: Thu, 17 Mar 2022 09:27:03 -0500 Subject: Invoke sync transaction callback if overwritten If a caller invokes the syncNextTransaction it will overwrite any callback that was set before. This can break since the caller expects to receive the callback. The change invokes the old callback when a new callback overwrites it. It also invokes the callback when the blast buffer queue is torn down in case there's one still pending. Test: Chrome in split + rotation Test: BLASTBufferQueueTest Fixes: 223329500 Change-Id: I91d1d7c47f4eca014c66ba8c2f773ef8be5c674e --- libs/gui/BLASTBufferQueue.cpp | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) (limited to 'libs/gui/BLASTBufferQueue.cpp') diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp index ec4c7c10a4..c2793ac5de 100644 --- a/libs/gui/BLASTBufferQueue.cpp +++ b/libs/gui/BLASTBufferQueue.cpp @@ -184,6 +184,10 @@ BLASTBufferQueue::~BLASTBufferQueue() { mergePendingTransactions(&t, std::numeric_limits::max() /* frameNumber */); // All transactions on our apply token are one-way. See comment on mAppliedLastTransaction t.setApplyToken(mApplyToken).apply(false, true); + + if (mTransactionReadyCallback) { + mTransactionReadyCallback(mSyncTransaction); + } } void BLASTBufferQueue::update(const sp& surface, uint32_t width, uint32_t height, @@ -702,14 +706,31 @@ void BLASTBufferQueue::syncNextTransaction( std::function callback, bool acquireSingleBuffer) { BBQ_TRACE(); - std::lock_guard _lock{mMutex}; - mTransactionReadyCallback = callback; - if (callback) { - mSyncTransaction = new SurfaceComposerClient::Transaction(); - } else { - mSyncTransaction = nullptr; + + std::function prevCallback = nullptr; + SurfaceComposerClient::Transaction* prevTransaction = nullptr; + + { + std::lock_guard _lock{mMutex}; + // We're about to overwrite the previous call so we should invoke that callback + // immediately. + if (mTransactionReadyCallback) { + prevCallback = mTransactionReadyCallback; + prevTransaction = mSyncTransaction; + } + + mTransactionReadyCallback = callback; + if (callback) { + mSyncTransaction = new SurfaceComposerClient::Transaction(); + } else { + mSyncTransaction = nullptr; + } + mAcquireSingleBuffer = mTransactionReadyCallback ? acquireSingleBuffer : true; + } + + if (prevCallback) { + prevCallback(prevTransaction); } - mAcquireSingleBuffer = mTransactionReadyCallback ? acquireSingleBuffer : true; } void BLASTBufferQueue::stopContinuousSyncTransaction() { -- cgit v1.2.3-59-g8ed1b