SurfaceFlinger: decouple EventThread from SF wakeup

Today we have two instances of EventThread:
1. 'app' - used to wake up Choreographer clients
2. 'sf' - used to wake up SF mian thead *and*
          Choreographer clients that uses sf instance

Now this creates an ambiguity when trying to reason about the expected
vsync time and deadline of 'sf' EventThread:
 - SF wakes up sfWorkDuration before a vsync and targets that vsync
 - Choreographer users wakes up with SF main thread but targets the
   vsync that happens after the next SF wakeup.

To resolve this ambiguity we are decoupling SF wakeup from 'sf'
EventThread. This means that Choreographer clients that uses 'sf'
instance will keep using the EventThread but SF will be waking up
directly by a callback with VSyncDispatch. This allows us to correct
the expected vsync and deadline for both.

Test: Interacting with the device and observe systraces
Test: new unit test added to SF suite
Bug: 166302754

Change-Id: I76d154029b4bc1902198074c33d38ff030c4601b
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 641a0a3..1343375 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -14,9 +14,7 @@
  * limitations under the License.
  */
 
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include <binder/IPCThreadState.h>
 
@@ -28,6 +26,7 @@
 #include <gui/IDisplayEventConnection.h>
 
 #include "EventThread.h"
+#include "FrameTimeline.h"
 #include "MessageQueue.h"
 #include "SurfaceFlinger.h"
 
@@ -68,15 +67,53 @@
     mHandler = new Handler(*this);
 }
 
+// TODO(b/169865816): refactor VSyncInjections to use MessageQueue directly
+// and remove the EventThread from MessageQueue
 void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
     if (mEventTube.getFd() >= 0) {
         mLooper->removeFd(mEventTube.getFd());
     }
 
     mEvents = connection;
-    mEvents->stealReceiveChannel(&mEventTube);
-    mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
-                   this);
+    if (mEvents) {
+        mEvents->stealReceiveChannel(&mEventTube);
+        mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
+                       this);
+    }
+}
+
+void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) {
+    ATRACE_CALL();
+    // Trace VSYNC-sf
+    mVsync.value = (mVsync.value + 1) % 2;
+
+    {
+        std::lock_guard lock(mVsync.mutex);
+        mVsync.lastCallbackTime = std::chrono::nanoseconds(vsyncTime);
+    }
+    mHandler->dispatchInvalidate(mVsync.tokenManager->generateTokenForPredictions(
+                                         {targetWakeupTime, readyTime, vsyncTime}),
+                                 vsyncTime);
+}
+
+void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch,
+                             frametimeline::TokenManager& tokenManager,
+                             std::chrono::nanoseconds workDuration) {
+    setDuration(workDuration);
+    mVsync.tokenManager = &tokenManager;
+    mVsync.registration = std::make_unique<
+            scheduler::VSyncCallbackRegistration>(dispatch,
+                                                  std::bind(&MessageQueue::vsyncCallback, this,
+                                                            std::placeholders::_1,
+                                                            std::placeholders::_2,
+                                                            std::placeholders::_3),
+                                                  "sf");
+}
+
+void MessageQueue::setDuration(std::chrono::nanoseconds workDuration) {
+    ATRACE_CALL();
+    std::lock_guard lock(mVsync.mutex);
+    mVsync.workDuration = workDuration;
 }
 
 void MessageQueue::waitMessage() {
@@ -106,7 +143,18 @@
 }
 
 void MessageQueue::invalidate() {
-    mEvents->requestNextVsync();
+    ATRACE_CALL();
+    if (mEvents) {
+        mEvents->requestNextVsync();
+    } else {
+        const auto [workDuration, lastVsyncCallback] = [&] {
+            std::lock_guard lock(mVsync.mutex);
+            std::chrono::nanoseconds mWorkDurationNanos = mVsync.workDuration;
+            return std::make_pair(mWorkDurationNanos.count(), mVsync.lastCallbackTime.count());
+        }();
+
+        mVsync.registration->schedule({workDuration, /*readyDuration=*/0, lastVsyncCallback});
+    }
 }
 
 void MessageQueue::refresh() {
@@ -135,5 +183,3 @@
 
 } // namespace android::impl
 
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"