Revert "Introduce SurfaceFlinger Queued Transaction"

This reverts commit 3e95285e5bc67a5e5a33ac72e3fff3f234b24de8.

Reason for revert: broken test b/169245126

Bug: 169245126

Change-Id: I9d4b01619433a31ad8d8b2698926599359322e83
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 78c0a0e..f1f67cc 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1896,18 +1896,19 @@
 
 bool SurfaceFlinger::handleMessageTransaction() {
     ATRACE_CALL();
-
-    if (getTransactionFlags(eTransactionFlushNeeded)) {
-        flushPendingTransactionQueues();
-        flushTransactionQueue();
-    }
-
     uint32_t transactionFlags = peekTransactionFlags();
+
+    bool flushedATransaction = flushTransactionQueues();
+
     bool runHandleTransaction =
-            (transactionFlags && (transactionFlags != eTransactionFlushNeeded)) || mForceTraversal;
+            (transactionFlags && (transactionFlags != eTransactionFlushNeeded)) ||
+            flushedATransaction ||
+            mForceTraversal;
 
     if (runHandleTransaction) {
         handleTransaction(eTransactionMask);
+    } else {
+        getTransactionFlags(eTransactionFlushNeeded);
     }
 
     if (transactionFlushNeeded()) {
@@ -2776,6 +2777,7 @@
         });
     }
 
+    commitInputWindowCommands();
     commitTransaction();
 }
 
@@ -2816,6 +2818,11 @@
                                                                      : nullptr);
 }
 
+void SurfaceFlinger::commitInputWindowCommands() {
+    mInputWindowCommands.merge(mPendingInputWindowCommands);
+    mPendingInputWindowCommands.clear();
+}
+
 void SurfaceFlinger::updateCursorAsync() {
     compositionengine::CompositionRefreshArgs refreshArgs;
     for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
@@ -3168,52 +3175,50 @@
     mForceTraversal = true;
 }
 
-void SurfaceFlinger::flushPendingTransactionQueues() {
+bool SurfaceFlinger::flushTransactionQueues() {
     // to prevent onHandleDestroyed from being called while the lock is held,
     // we must keep a copy of the transactions (specifically the composer
     // states) around outside the scope of the lock
     std::vector<const TransactionState> transactions;
+    bool flushedATransaction = false;
     {
-        Mutex::Autolock _l(mQueueLock);
+        Mutex::Autolock _l(mStateLock);
 
-        auto it = mPendingTransactionQueues.begin();
-        while (it != mPendingTransactionQueues.end()) {
+        auto it = mTransactionQueues.begin();
+        while (it != mTransactionQueues.end()) {
             auto& [applyToken, transactionQueue] = *it;
 
             while (!transactionQueue.empty()) {
                 const auto& transaction = transactionQueue.front();
                 if (!transactionIsReadyToBeApplied(transaction.desiredPresentTime,
                                                    transaction.states)) {
+                    setTransactionFlags(eTransactionFlushNeeded);
                     break;
                 }
                 transactions.push_back(transaction);
+                applyTransactionState(transaction.states, transaction.displays, transaction.flags,
+                                      mPendingInputWindowCommands, transaction.desiredPresentTime,
+                                      transaction.buffer, transaction.postTime,
+                                      transaction.privileged, transaction.hasListenerCallbacks,
+                                      transaction.listenerCallbacks, transaction.originPID,
+                                      transaction.originUID, /*isMainThread*/ true);
                 transactionQueue.pop();
+                flushedATransaction = true;
             }
 
             if (transactionQueue.empty()) {
-                it = mPendingTransactionQueues.erase(it);
+                it = mTransactionQueues.erase(it);
                 mTransactionCV.broadcast();
             } else {
                 it = std::next(it, 1);
             }
         }
     }
-
-    {
-        Mutex::Autolock _l(mStateLock);
-        for (const auto& transaction : transactions) {
-            applyTransactionState(transaction.states, transaction.displays, transaction.flags,
-                                  mInputWindowCommands, transaction.desiredPresentTime,
-                                  transaction.buffer, transaction.postTime, transaction.privileged,
-                                  transaction.hasListenerCallbacks, transaction.listenerCallbacks,
-                                  transaction.originPID, transaction.originUID);
-        }
-    }
+    return flushedATransaction;
 }
 
 bool SurfaceFlinger::transactionFlushNeeded() {
-    Mutex::Autolock _l(mQueueLock);
-    return !mPendingTransactionQueues.empty();
+    return !mTransactionQueues.empty();
 }
 
 
@@ -3248,125 +3253,51 @@
     ATRACE_CALL();
 
     const int64_t postTime = systemTime();
+
     bool privileged = callingThreadHasUnscopedSurfaceFlingerAccess();
-    {
-        Mutex::Autolock _l(mQueueLock);
-
-        // If its TransactionQueue already has a pending TransactionState or if it is pending
-        auto itr = mPendingTransactionQueues.find(applyToken);
-        // if this is an animation frame, wait until prior animation frame has
-        // been applied by SF
-        if (flags & eAnimation) {
-            while (itr != mPendingTransactionQueues.end()) {
-                status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
-                if (CC_UNLIKELY(err != NO_ERROR)) {
-                    ALOGW_IF(err == TIMED_OUT,
-                             "setTransactionState timed out "
-                             "waiting for animation frame to apply");
-                    break;
-                }
-                itr = mPendingTransactionQueues.find(applyToken);
-            }
-        }
-
-        // TODO(b/159125966): Remove eEarlyWakeup completly as no client should use this flag
-        if (flags & eEarlyWakeup) {
-            ALOGW("eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]");
-        }
-
-        if (!privileged && (flags & (eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd))) {
-            ALOGE("Only WindowManager is allowed to use eExplicitEarlyWakeup[Start|End] flags");
-            flags &= ~(eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd);
-        }
-
-        const bool pendingTransactions = itr != mPendingTransactionQueues.end();
-        // Expected present time is computed and cached on invalidate, so it may be stale.
-        if (!pendingTransactions) {
-            mExpectedPresentTime = calculateExpectedPresentTime(systemTime());
-        }
-
-        IPCThreadState* ipc = IPCThreadState::self();
-        const int originPID = ipc->getCallingPid();
-        const int originUID = ipc->getCallingUid();
-
-        if (pendingTransactions || !transactionIsReadyToBeApplied(desiredPresentTime, states)) {
-            mPendingTransactionQueues[applyToken].emplace(states, displays, flags,
-                                                          inputWindowCommands, desiredPresentTime,
-                                                          uncacheBuffer, postTime, privileged,
-                                                          hasListenerCallbacks, listenerCallbacks,
-                                                          originPID, originUID);
-            setTransactionFlags(eTransactionFlushNeeded);
-            return NO_ERROR;
-        }
-
-        mTransactionQueue.emplace_back(states, displays, flags, inputWindowCommands,
-                                       desiredPresentTime, uncacheBuffer, postTime, privileged,
-                                       hasListenerCallbacks, listenerCallbacks, originPID,
-                                       originUID);
-    }
-
-    {
-        Mutex::Autolock _l(mStateLock);
-
-        const auto schedule = [](uint32_t flags) {
-            if (flags & eEarlyWakeup) return TransactionSchedule::Early;
-            if (flags & eExplicitEarlyWakeupEnd) return TransactionSchedule::EarlyEnd;
-            if (flags & eExplicitEarlyWakeupStart) return TransactionSchedule::EarlyStart;
-            return TransactionSchedule::Late;
-        }(flags);
-
-        // if this is a synchronous transaction, wait for it to take effect
-        // before returning.
-        const bool synchronous = flags & eSynchronous;
-        const bool syncInput = inputWindowCommands.syncInputWindows;
-        if (!synchronous && !syncInput) {
-            setTransactionFlags(eTransactionFlushNeeded, schedule);
-            return NO_ERROR;
-        }
-
-        if (synchronous) {
-            mTransactionPending = true;
-        }
-        if (syncInput) {
-            mPendingSyncInputWindows = true;
-        }
-        setTransactionFlags(eTransactionFlushNeeded, schedule);
-
-        // applyTransactionState can be called by either the main SF thread or by
-        // another process through setTransactionState.  While a given process may wish
-        // to wait on synchronous transactions, the main SF thread should never
-        // be blocked.  Therefore, we only wait if isMainThread is false.
-        while (mTransactionPending || mPendingSyncInputWindows) {
-            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
-            if (CC_UNLIKELY(err != NO_ERROR)) {
-                // just in case something goes wrong in SF, return to the
-                // called after a few seconds.
-                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
-                mTransactionPending = false;
-                mPendingSyncInputWindows = false;
-                break;
-            }
-        }
-    }
-    return NO_ERROR;
-}
-
-void SurfaceFlinger::flushTransactionQueue() {
-    std::vector<TransactionState> transactionQueue;
-    {
-        Mutex::Autolock _l(mQueueLock);
-        if (!mTransactionQueue.empty()) {
-            transactionQueue.swap(mTransactionQueue);
-        }
-    }
 
     Mutex::Autolock _l(mStateLock);
-    for (const auto& t : transactionQueue) {
-        applyTransactionState(t.states, t.displays, t.flags, t.inputWindowCommands,
-                              t.desiredPresentTime, t.buffer, t.postTime, t.privileged,
-                              t.hasListenerCallbacks, t.listenerCallbacks, t.originPID,
-                              t.originUID);
+
+    // If its TransactionQueue already has a pending TransactionState or if it is pending
+    auto itr = mTransactionQueues.find(applyToken);
+    // if this is an animation frame, wait until prior animation frame has
+    // been applied by SF
+    if (flags & eAnimation) {
+        while (itr != mTransactionQueues.end()) {
+            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
+            if (CC_UNLIKELY(err != NO_ERROR)) {
+                ALOGW_IF(err == TIMED_OUT,
+                         "setTransactionState timed out "
+                         "waiting for animation frame to apply");
+                break;
+            }
+            itr = mTransactionQueues.find(applyToken);
+        }
     }
+
+    const bool pendingTransactions = itr != mTransactionQueues.end();
+    // Expected present time is computed and cached on invalidate, so it may be stale.
+    if (!pendingTransactions) {
+        mExpectedPresentTime = calculateExpectedPresentTime(systemTime());
+    }
+
+    IPCThreadState* ipc = IPCThreadState::self();
+    const int originPID = ipc->getCallingPid();
+    const int originUID = ipc->getCallingUid();
+
+    if (pendingTransactions || !transactionIsReadyToBeApplied(desiredPresentTime, states)) {
+        mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
+                                               uncacheBuffer, postTime, privileged,
+                                               hasListenerCallbacks, listenerCallbacks, originPID,
+                                               originUID);
+        setTransactionFlags(eTransactionFlushNeeded);
+        return NO_ERROR;
+    }
+
+    applyTransactionState(states, displays, flags, inputWindowCommands, desiredPresentTime,
+                          uncacheBuffer, postTime, privileged, hasListenerCallbacks,
+                          listenerCallbacks, originPID, originUID, /*isMainThread*/ false);
+    return NO_ERROR;
 }
 
 void SurfaceFlinger::applyTransactionState(
@@ -3374,9 +3305,25 @@
         const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime,
         const client_cache_t& uncacheBuffer, const int64_t postTime, bool privileged,
         bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
-        int32_t originPID, int32_t originUID) {
+        int originPID, int originUID, bool isMainThread) {
     uint32_t transactionFlags = 0;
 
+    if (flags & eAnimation) {
+        // For window updates that are part of an animation we must wait for
+        // previous animation "frames" to be handled.
+        while (!isMainThread && mAnimTransactionPending) {
+            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
+            if (CC_UNLIKELY(err != NO_ERROR)) {
+                // just in case something goes wrong in SF, return to the
+                // caller after a few seconds.
+                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
+                        "waiting for previous animation frame");
+                mAnimTransactionPending = false;
+                break;
+            }
+        }
+    }
+
     for (const DisplayState& display : displays) {
         transactionFlags |= setDisplayStateLocked(display);
     }
@@ -3432,25 +3379,80 @@
         transactionFlags = eTransactionNeeded;
     }
 
-    if (transactionFlags && mInterceptor->isEnabled()) {
-        mInterceptor->saveTransaction(states, mCurrentState.displays, displays, flags, originPID,
-                                      originUID);
-    }
-
-    // We are on the main thread, we are about to preform a traversal. Clear the traversal bit
-    // so we don't have to wake up again next frame to preform an unnecessary traversal.
-    if (transactionFlags & eTraversalNeeded) {
+    // If we are on the main thread, we are about to preform a traversal. Clear the traversal bit
+    // so we don't have to wake up again next frame to preform an uneeded traversal.
+    if (isMainThread && (transactionFlags & eTraversalNeeded)) {
         transactionFlags = transactionFlags & (~eTraversalNeeded);
         mForceTraversal = true;
     }
 
+    const auto schedule = [](uint32_t flags) {
+        if (flags & eEarlyWakeup) return TransactionSchedule::Early;
+        if (flags & eExplicitEarlyWakeupEnd) return TransactionSchedule::EarlyEnd;
+        if (flags & eExplicitEarlyWakeupStart) return TransactionSchedule::EarlyStart;
+        return TransactionSchedule::Late;
+    }(flags);
+
     if (transactionFlags) {
+        if (mInterceptor->isEnabled()) {
+            mInterceptor->saveTransaction(states, mCurrentState.displays, displays, flags,
+                                          originPID, originUID);
+        }
+
+        // TODO(b/159125966): Remove eEarlyWakeup completly as no client should use this flag
+        if (flags & eEarlyWakeup) {
+            ALOGW("eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]");
+        }
+
+        if (!privileged && (flags & (eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd))) {
+            ALOGE("Only WindowManager is allowed to use eExplicitEarlyWakeup[Start|End] flags");
+            flags &= ~(eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd);
+        }
+
         // this triggers the transaction
-        setTransactionFlags(transactionFlags);
+        setTransactionFlags(transactionFlags, schedule);
 
         if (flags & eAnimation) {
             mAnimTransactionPending = true;
         }
+
+        // if this is a synchronous transaction, wait for it to take effect
+        // before returning.
+        const bool synchronous = flags & eSynchronous;
+        const bool syncInput = inputWindowCommands.syncInputWindows;
+        if (!synchronous && !syncInput) {
+            return;
+        }
+
+        if (synchronous) {
+            mTransactionPending = true;
+        }
+        if (syncInput) {
+            mPendingSyncInputWindows = true;
+        }
+
+
+        // applyTransactionState can be called by either the main SF thread or by
+        // another process through setTransactionState.  While a given process may wish
+        // to wait on synchronous transactions, the main SF thread should never
+        // be blocked.  Therefore, we only wait if isMainThread is false.
+        while (!isMainThread && (mTransactionPending || mPendingSyncInputWindows)) {
+            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
+            if (CC_UNLIKELY(err != NO_ERROR)) {
+                // just in case something goes wrong in SF, return to the
+                // called after a few seconds.
+                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
+                mTransactionPending = false;
+                mPendingSyncInputWindows = false;
+                break;
+            }
+        }
+    } else {
+        // Update VsyncModulator state machine even if transaction is not needed.
+        if (schedule == TransactionSchedule::EarlyStart ||
+            schedule == TransactionSchedule::EarlyEnd) {
+            modulateVsync(&VsyncModulator::setTransactionSchedule, schedule);
+        }
     }
 }
 
@@ -3829,7 +3831,7 @@
 }
 
 uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
-    bool hasChanges = mInputWindowCommands.merge(inputWindowCommands);
+    bool hasChanges = mPendingInputWindowCommands.merge(inputWindowCommands);
     return hasChanges ? eTraversalNeeded : 0;
 }
 
@@ -4107,9 +4109,8 @@
     d.width = 0;
     d.height = 0;
     displays.add(d);
-    // This called on the main thread, apply it directly.
-    applyTransactionState(state, displays, 0, mInputWindowCommands, -1, {}, systemTime(), true,
-                          false, {}, getpid(), getuid());
+    setTransactionState(state, displays, 0, nullptr, mPendingInputWindowCommands, -1, {}, false,
+                        {});
 
     setPowerModeInternal(display, hal::PowerMode::ON);
     const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
@@ -5273,7 +5274,7 @@
 
 void SurfaceFlinger::repaintEverything() {
     mRepaintEverything = true;
-    setTransactionFlags(eTransactionNeeded);
+    signalTransaction();
 }
 
 void SurfaceFlinger::repaintEverythingForHWC() {