pendingSC = mSurfaceControlsWithPendingCallback.front(); std::optional 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 thi"> pendingSC = mSurfaceControlsWithPendingCallback.front(); std::optional 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 thi"> pendingSC = mSurfaceControlsWithPendingCallback.front(); std::optional 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 thi">
void 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);
    }
}