pendingSC = mSurfaceControlsWithPendingCallback.front();
std::optionalvoid BLASTBufferQueue::transactionCommittedCallback(nsecs_t /*latchTime*/,
const sp<Fence>& /*presentFence*/,
const std::vector<SurfaceControlStats>& stats) {
{
std::unique_lock _lock{mMutex};
ATRACE_CALL();
BQA_LOGV("transactionCommittedCallback");
if (!mSurfaceControlsWithPendingCallback.empty()) {
sp<SurfaceControl> pendingSC = mSurfaceControlsWithPendingCallback.front();
std::optional<SurfaceControlStats> stat = findMatchingStat(stats, pendingSC);
if (stat) {
uint64_t currFrameNumber = stat->frameEventStats.frameNumber;
// We need to check if we were waiting for a transaction callback in order to
// process any pending buffers and unblock. It's possible to get transaction
// callbacks for previous requests so we need to ensure the frame from this
// transaction callback matches the last acquired buffer. Since acquireNextBuffer
// will stop processing buffers when mWaitForTransactionCallback is set, we know
// that mLastAcquiredFrameNumber is the frame we're waiting on.
// We also want to check if mNextTransaction is null because it's possible another
// sync request came in while waiting, but it hasn't started processing yet. In that
// case, we don't actually want to flush the frames in between since they will get
// processed and merged with the sync transaction and released earlier than if they
// were sent to SF
if (mWaitForTransactionCallback && mNextTransaction == nullptr &&
currFrameNumber >= mLastAcquiredFrameNumber) {
mWaitForTransactionCallback = false;
flushShadowQueueLocked();
}
} else {
BQA_LOGE("Failed to find matching SurfaceControl in transactionCommittedCallback");
}
} else {
BQA_LOGE("No matching SurfaceControls found: mSurfaceControlsWithPendingCallback was "
"empty.");
}
decStrong((void*)transactionCommittedCallbackThunk);
}
}