Add TransactionCompleteCallback
Allow users of BlastBufferQueue to register for transaction complete for
a particular frame number. This will allow VRI to know when a
transaction was applied so it can continue rendering after a relayout.
Test: Split screen with blast sync
Bug: 167202096
Change-Id: If0bb5b496a462ba486b05b0ddc35bff66eb29e1a
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 8328322..e17f319 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -184,49 +184,64 @@
void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/,
const std::vector<SurfaceControlStats>& stats) {
- std::unique_lock _lock{mMutex};
- ATRACE_CALL();
- BQA_LOGV("transactionCallback");
- mInitialCallbackReceived = true;
+ std::function<void(int64_t)> transactionCompleteCallback = nullptr;
+ uint64_t currFrameNumber = 0;
- if (!stats.empty()) {
- mTransformHint = stats[0].transformHint;
- mBufferItemConsumer->setTransformHint(mTransformHint);
- mBufferItemConsumer->updateFrameTimestamps(stats[0].frameEventStats.frameNumber,
- stats[0].frameEventStats.refreshStartTime,
- stats[0].frameEventStats.gpuCompositionDoneFence,
- stats[0].presentFence,
- stats[0].previousReleaseFence,
- stats[0].frameEventStats.compositorTiming,
- stats[0].latchTime,
- stats[0].frameEventStats.dequeueReadyTime);
- }
- if (mPendingReleaseItem.item.mGraphicBuffer != nullptr) {
+ {
+ std::unique_lock _lock{mMutex};
+ ATRACE_CALL();
+ BQA_LOGV("transactionCallback");
+ mInitialCallbackReceived = true;
+
if (!stats.empty()) {
- mPendingReleaseItem.releaseFence = stats[0].previousReleaseFence;
- } else {
- BQA_LOGE("Warning: no SurfaceControlStats returned in BLASTBufferQueue callback");
+ mTransformHint = stats[0].transformHint;
+ mBufferItemConsumer->setTransformHint(mTransformHint);
+ mBufferItemConsumer
+ ->updateFrameTimestamps(stats[0].frameEventStats.frameNumber,
+ stats[0].frameEventStats.refreshStartTime,
+ stats[0].frameEventStats.gpuCompositionDoneFence,
+ stats[0].presentFence, stats[0].previousReleaseFence,
+ stats[0].frameEventStats.compositorTiming,
+ stats[0].latchTime,
+ stats[0].frameEventStats.dequeueReadyTime);
+ }
+ if (mPendingReleaseItem.item.mGraphicBuffer != nullptr) {
+ if (!stats.empty()) {
+ mPendingReleaseItem.releaseFence = stats[0].previousReleaseFence;
+ } else {
+ BQA_LOGE("Warning: no SurfaceControlStats returned in BLASTBufferQueue callback");
+ mPendingReleaseItem.releaseFence = nullptr;
+ }
+ mBufferItemConsumer->releaseBuffer(mPendingReleaseItem.item,
+ mPendingReleaseItem.releaseFence
+ ? mPendingReleaseItem.releaseFence
+ : Fence::NO_FENCE);
+ mNumAcquired--;
+ mPendingReleaseItem.item = BufferItem();
mPendingReleaseItem.releaseFence = nullptr;
}
- mBufferItemConsumer->releaseBuffer(mPendingReleaseItem.item,
- mPendingReleaseItem.releaseFence
- ? mPendingReleaseItem.releaseFence
- : Fence::NO_FENCE);
- mNumAcquired--;
- mPendingReleaseItem.item = BufferItem();
- mPendingReleaseItem.releaseFence = nullptr;
+
+ if (mSubmitted.empty()) {
+ BQA_LOGE("ERROR: callback with no corresponding submitted buffer item");
+ }
+ mPendingReleaseItem.item = std::move(mSubmitted.front());
+ mSubmitted.pop();
+
+ processNextBufferLocked(false);
+
+ currFrameNumber = mPendingReleaseItem.item.mFrameNumber;
+ if (mTransactionCompleteCallback && mTransactionCompleteFrameNumber == currFrameNumber) {
+ transactionCompleteCallback = std::move(mTransactionCompleteCallback);
+ mTransactionCompleteFrameNumber = 0;
+ }
+
+ mCallbackCV.notify_all();
+ decStrong((void*)transactionCallbackThunk);
}
- if (mSubmitted.empty()) {
- BQA_LOGE("ERROR: callback with no corresponding submitted buffer item");
+ if (transactionCompleteCallback) {
+ transactionCompleteCallback(currFrameNumber);
}
- mPendingReleaseItem.item = std::move(mSubmitted.front());
- mSubmitted.pop();
-
- processNextBufferLocked(false);
-
- mCallbackCV.notify_all();
- decStrong((void*)transactionCallbackThunk);
}
void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {
@@ -394,6 +409,17 @@
return mSize != bufferSize;
}
+void BLASTBufferQueue::setTransactionCompleteCallback(
+ uint64_t frameNumber, std::function<void(int64_t)>&& transactionCompleteCallback) {
+ std::lock_guard _lock{mMutex};
+ if (transactionCompleteCallback == nullptr) {
+ mTransactionCompleteCallback = nullptr;
+ } else {
+ mTransactionCompleteCallback = std::move(transactionCompleteCallback);
+ mTransactionCompleteFrameNumber = frameNumber;
+ }
+}
+
// Check if we have acquired the maximum number of buffers.
// As a special case, we wait for the first callback before acquiring the second buffer so we
// can ensure the first buffer is presented if multiple buffers are queued in succession.