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
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 982dd63..379b090 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -508,21 +508,7 @@
}
}
- 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());
-
+ mergePendingTransactions(t, bufferItem.mFrameNumber);
if (applyTransaction) {
t->setApplyToken(mApplyToken).apply();
}
@@ -726,6 +712,32 @@
}
}
+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<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());
+}
+
// Maintains a single worker thread per process that services a list of runnables.
class AsyncWorker : public Singleton<AsyncWorker> {
private:
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index be46180..86480e3 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -94,6 +94,7 @@
uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount);
void setNextTransaction(SurfaceComposerClient::Transaction *t);
void mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber);
+ void applyPendingTransactions(uint64_t frameNumber);
void setTransactionCompleteCallback(uint64_t frameNumber,
std::function<void(int64_t)>&& transactionCompleteCallback);
@@ -126,6 +127,8 @@
bool rejectBuffer(const BufferItem& item) REQUIRES(mMutex);
bool maxBuffersAcquired(bool includeExtraAcquire) const REQUIRES(mMutex);
static PixelFormat convertBufferFormat(PixelFormat& format);
+ void mergePendingTransactions(SurfaceComposerClient::Transaction* t, uint64_t frameNumber)
+ REQUIRES(mMutex);
std::string mName;
// Represents the queued buffer count from buffer queue,