Shared timeline plumbing

Add plumbing to get shared timeline data from Surface Flinger to HWUI
and back.

Bug: 162890382
Bug: 162888881
Bug: 162890407

Test: manual using ALOG messages in SF
Change-Id: I85c5eb56d2fa933889518854e7b79b1e65e29af3
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 987edf7..042808a4 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -660,8 +660,7 @@
         ThreadedRenderer.setFPSDivisor(divisor);
     }
 
-    @UnsupportedAppUsage
-    void doFrame(long frameTimeNanos, int frame) {
+    void doFrame(long frameTimeNanos, int frame, long frameTimelineVsyncId) {
         final long startNanos;
         synchronized (mLock) {
             if (!mFrameScheduled) {
@@ -711,7 +710,7 @@
                 }
             }
 
-            mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos);
+            mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, frameTimelineVsyncId);
             mFrameScheduled = false;
             mLastFrameTimeNanos = frameTimeNanos;
         }
@@ -897,7 +896,7 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_DO_FRAME:
-                    doFrame(System.nanoTime(), 0);
+                    doFrame(System.nanoTime(), 0, FrameInfo.INVALID_VSYNC_ID);
                     break;
                 case MSG_DO_SCHEDULE_VSYNC:
                     doScheduleVsync();
@@ -914,6 +913,7 @@
         private boolean mHavePendingVsync;
         private long mTimestampNanos;
         private int mFrame;
+        private long mFrameTimelineVsyncId;
 
         public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
             super(looper, vsyncSource, CONFIG_CHANGED_EVENT_SUPPRESS);
@@ -923,7 +923,8 @@
         // the internal display and DisplayEventReceiver#scheduleVsync only allows requesting VSYNC
         // for the internal display implicitly.
         @Override
-        public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
+        public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
+                long frameTimelineVsyncId) {
             // Post the vsync event to the Handler.
             // The idea is to prevent incoming vsync events from completely starving
             // the message queue.  If there are no messages in the queue with timestamps
@@ -946,6 +947,7 @@
 
             mTimestampNanos = timestampNanos;
             mFrame = frame;
+            mFrameTimelineVsyncId = frameTimelineVsyncId;
             Message msg = Message.obtain(mHandler, this);
             msg.setAsynchronous(true);
             mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
@@ -954,7 +956,7 @@
         @Override
         public void run() {
             mHavePendingVsync = false;
-            doFrame(mTimestampNanos, mFrame);
+            doFrame(mTimestampNanos, mFrame, mFrameTimelineVsyncId);
         }
     }
 
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
index eaf297c..51474d3 100644
--- a/core/java/android/view/DisplayEventReceiver.java
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -154,9 +154,11 @@
      * timebase.
      * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
      * @param frame The frame number.  Increases by one for each vertical sync interval.
+     * @param frameTimelineVsyncId The frame timeline vsync id, used to correlate a frame
+     * produced by HWUI with the timeline data stored in Surface Flinger.
      */
-    @UnsupportedAppUsage
-    public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
+    public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
+            long frameTimelineVsyncId) {
     }
 
     /**
@@ -198,9 +200,9 @@
 
     // Called from native code.
     @SuppressWarnings("unused")
-    @UnsupportedAppUsage
-    private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
-        onVsync(timestampNanos, physicalDisplayId, frame);
+    private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame,
+            long frameTimelineVsyncId) {
+        onVsync(timestampNanos, physicalDisplayId, frame, frameTimelineVsyncId);
     }
 
     // Called from native code.
diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java
index 32cc30be8..280a1c0 100644
--- a/core/java/android/view/FrameMetrics.java
+++ b/core/java/android/view/FrameMetrics.java
@@ -189,6 +189,7 @@
      */
     @IntDef ({
             Index.FLAGS,
+            Index.FRAME_TIMELINE_VSYNC_ID,
             Index.INTENDED_VSYNC,
             Index.VSYNC,
             Index.OLDEST_INPUT_EVENT,
@@ -206,21 +207,22 @@
     @Retention(RetentionPolicy.SOURCE)
     private @interface Index {
         int FLAGS = 0;
-        int INTENDED_VSYNC = 1;
-        int VSYNC = 2;
-        int OLDEST_INPUT_EVENT = 3;
-        int NEWEST_INPUT_EVENT = 4;
-        int HANDLE_INPUT_START = 5;
-        int ANIMATION_START = 6;
-        int PERFORM_TRAVERSALS_START = 7;
-        int DRAW_START = 8;
-        int SYNC_QUEUED = 9;
-        int SYNC_START = 10;
-        int ISSUE_DRAW_COMMANDS_START = 11;
-        int SWAP_BUFFERS = 12;
-        int FRAME_COMPLETED = 13;
+        int FRAME_TIMELINE_VSYNC_ID = 1;
+        int INTENDED_VSYNC = 2;
+        int VSYNC = 3;
+        int OLDEST_INPUT_EVENT = 4;
+        int NEWEST_INPUT_EVENT = 5;
+        int HANDLE_INPUT_START = 6;
+        int ANIMATION_START = 7;
+        int PERFORM_TRAVERSALS_START = 8;
+        int DRAW_START = 9;
+        int SYNC_QUEUED = 10;
+        int SYNC_START = 11;
+        int ISSUE_DRAW_COMMANDS_START = 12;
+        int SWAP_BUFFERS = 13;
+        int FRAME_COMPLETED = 14;
 
-        int FRAME_STATS_COUNT = 17; // must always be last
+        int FRAME_STATS_COUNT = 18; // must always be last
     }
 
     /*
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 50a557bb..3acd15a 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -59,7 +59,8 @@
     jobject mReceiverWeakGlobal;
     sp<MessageQueue> mMessageQueue;
 
-    void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
+    void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count,
+                       int64_t sharedTimelineFrameCount) override;
     void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
     void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
                                int32_t configId, nsecs_t vsyncPeriod) override;
@@ -90,14 +91,14 @@
 }
 
 void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
-                                               uint32_t count) {
+                                               uint32_t count, int64_t frameTimelineVsyncId) {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
 
     ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
     if (receiverObj.get()) {
         ALOGV("receiver %p ~ Invoking vsync handler.", this);
         env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,
-                            timestamp, displayId.value, count);
+                            timestamp, displayId.value, count, frameTimelineVsyncId);
         ALOGV("receiver %p ~ Returned from vsync handler.", this);
     }
 
@@ -196,8 +197,8 @@
     jclass clazz = FindClassOrDie(env, "android/view/DisplayEventReceiver");
     gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
 
-    gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env,
-            gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V");
+    gDisplayEventReceiverClassInfo.dispatchVsync =
+            GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJIJ)V");
     gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
             gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
     gDisplayEventReceiverClassInfo.dispatchConfigChanged = GetMethodIDOrDie(env,
diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java
index 42a5cc4..163823f 100644
--- a/graphics/java/android/graphics/FrameInfo.java
+++ b/graphics/java/android/graphics/FrameInfo.java
@@ -40,7 +40,7 @@
  */
 public final class FrameInfo {
 
-    public long[] frameInfo = new long[9];
+    public long[] frameInfo = new long[10];
 
     // Various flags set to provide extra metadata about the current frame
     private static final int FLAGS = 0;
@@ -51,38 +51,44 @@
     // A renderer associated with just a Surface, not with a ViewRootImpl instance.
     public static final long FLAG_SURFACE_CANVAS = 1 << 2;
 
+    // An invalid vsync id to be used when FRAME_TIMELINE_VSYNC_ID is unknown
+    public static final long INVALID_VSYNC_ID = -1;
+
     @LongDef(flag = true, value = {
             FLAG_WINDOW_LAYOUT_CHANGED, FLAG_SURFACE_CANVAS })
     @Retention(RetentionPolicy.SOURCE)
     public @interface FrameInfoFlags {}
 
+    private static final int FRAME_TIMELINE_VSYNC_ID = 1;
+
     // The intended vsync time, unadjusted by jitter
-    private static final int INTENDED_VSYNC = 1;
+    private static final int INTENDED_VSYNC = 2;
 
     // Jitter-adjusted vsync time, this is what was used as input into the
     // animation & drawing system
-    private static final int VSYNC = 2;
+    private static final int VSYNC = 3;
 
     // The time of the oldest input event
-    private static final int OLDEST_INPUT_EVENT = 3;
+    private static final int OLDEST_INPUT_EVENT = 4;
 
     // The time of the newest input event
-    private static final int NEWEST_INPUT_EVENT = 4;
+    private static final int NEWEST_INPUT_EVENT = 5;
 
     // When input event handling started
-    private static final int HANDLE_INPUT_START = 5;
+    private static final int HANDLE_INPUT_START = 6;
 
     // When animation evaluations started
-    private static final int ANIMATION_START = 6;
+    private static final int ANIMATION_START = 7;
 
     // When ViewRootImpl#performTraversals() started
-    private static final int PERFORM_TRAVERSALS_START = 7;
+    private static final int PERFORM_TRAVERSALS_START = 8;
 
     // When View:draw() started
-    private static final int DRAW_START = 8;
+    private static final int DRAW_START = 9;
 
     /** checkstyle */
-    public void setVsync(long intendedVsync, long usedVsync) {
+    public void setVsync(long intendedVsync, long usedVsync, long frameTimelineVsyncId) {
+        frameInfo[FRAME_TIMELINE_VSYNC_ID] = frameTimelineVsyncId;
         frameInfo[INTENDED_VSYNC] = intendedVsync;
         frameInfo[VSYNC] = usedVsync;
         frameInfo[OLDEST_INPUT_EVENT] = Long.MAX_VALUE;
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 0452933..fd5916c 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -354,7 +354,8 @@
          * @return this instance
          */
         public @NonNull FrameRenderRequest setVsyncTime(long vsyncTime) {
-            mFrameInfo.setVsync(vsyncTime, vsyncTime);
+            // TODO(b/168552873): populate vsync Id once available to Choreographer public API
+            mFrameInfo.setVsync(vsyncTime, vsyncTime, FrameInfo.INVALID_VSYNC_ID);
             mFrameInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS);
             return this;
         }
diff --git a/libs/hwui/FrameInfo.cpp b/libs/hwui/FrameInfo.cpp
index 0698775..30ce537 100644
--- a/libs/hwui/FrameInfo.cpp
+++ b/libs/hwui/FrameInfo.cpp
@@ -22,6 +22,7 @@
 
 const std::string FrameInfoNames[] = {
         "Flags",
+        "FrameTimelineVsyncId",
         "IntendedVsync",
         "Vsync",
         "OldestInputEvent",
@@ -44,7 +45,7 @@
                       static_cast<int>(FrameInfoIndex::NumIndexes),
               "size mismatch: FrameInfoNames doesn't match the enum!");
 
-static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 17,
+static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 18,
               "Must update value in FrameMetrics.java#FRAME_STATS_COUNT (and here)");
 
 void FrameInfo::importUiThreadInfo(int64_t* info) {
diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h
index dc30617..f5bfedd 100644
--- a/libs/hwui/FrameInfo.h
+++ b/libs/hwui/FrameInfo.h
@@ -27,10 +27,11 @@
 namespace android {
 namespace uirenderer {
 
-#define UI_THREAD_FRAME_INFO_SIZE 9
+#define UI_THREAD_FRAME_INFO_SIZE 10
 
 enum class FrameInfoIndex {
     Flags = 0,
+    FrameTimelineVsyncId,
     IntendedVsync,
     Vsync,
     OldestInputEvent,
@@ -71,11 +72,15 @@
 
 class UiFrameInfoBuilder {
 public:
+    static constexpr int64_t INVALID_VSYNC_ID = -1;
+
     explicit UiFrameInfoBuilder(int64_t* buffer) : mBuffer(buffer) {
         memset(mBuffer, 0, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t));
+        set(FrameInfoIndex::FrameTimelineVsyncId) = INVALID_VSYNC_ID;
     }
 
-    UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync) {
+    UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync, int64_t vsyncId) {
+        set(FrameInfoIndex::FrameTimelineVsyncId) = vsyncId;
         set(FrameInfoIndex::Vsync) = vsyncTime;
         set(FrameInfoIndex::IntendedVsync) = intendedVsync;
         // Pretend the other fields are all at vsync, too, so that naive
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index e817ca7..c89463b 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -514,7 +514,7 @@
         proxy.setLightGeometry((Vector3){0, 0, 0}, 0);
         nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
         UiFrameInfoBuilder(proxy.frameInfo())
-                .setVsync(vsync, vsync)
+                .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID)
                 .addFlag(FrameInfoFlags::SurfaceCanvas);
         proxy.syncAndDrawFrame();
     }
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 13d544c..c7560b2 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -484,6 +484,14 @@
 
     waitOnFences();
 
+    if (mNativeSurface) {
+        // TODO(b/165985262): measure performance impact
+        if (const auto vsyncId = mCurrentFrameInfo->get(FrameInfoIndex::FrameTimelineVsyncId);
+                vsyncId != UiFrameInfoBuilder::INVALID_VSYNC_ID) {
+            native_window_set_frame_timeline_vsync(mNativeSurface->getNativeWindow(), vsyncId);
+        }
+    }
+
     bool requireSwap = false;
     int error = OK;
     bool didSwap =
@@ -617,8 +625,11 @@
     ATRACE_CALL();
 
     nsecs_t vsync = mRenderThread.timeLord().computeFrameTimeNanos();
+    int64_t vsyncId = mRenderThread.timeLord().lastVsyncId();
     int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE];
-    UiFrameInfoBuilder(frameInfo).addFlag(FrameInfoFlags::RTAnimation).setVsync(vsync, vsync);
+    UiFrameInfoBuilder(frameInfo)
+        .addFlag(FrameInfoFlags::RTAnimation)
+        .setVsync(vsync, vsync, vsyncId);
 
     TreeInfo info(TreeInfo::MODE_RT_ONLY, *this);
     prepareTree(info, frameInfo, systemTime(SYSTEM_TIME_MONOTONIC), node);
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 1e59338..1ea595d 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -128,7 +128,9 @@
 bool DrawFrameTask::syncFrameState(TreeInfo& info) {
     ATRACE_CALL();
     int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)];
-    mRenderThread->timeLord().vsyncReceived(vsync);
+    int64_t intendedVsync = mFrameInfo[static_cast<int>(FrameInfoIndex::IntendedVsync)];
+    int64_t vsyncId = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameTimelineVsyncId)];
+    mRenderThread->timeLord().vsyncReceived(vsync, intendedVsync, vsyncId);
     bool canDraw = mContext->makeCurrent();
     mContext->unpinImages();
 
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 4dcbc44..9371656 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -51,8 +51,10 @@
 
 void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) {
     RenderThread* rt = reinterpret_cast<RenderThread*>(data);
+    int64_t vsyncId = AChoreographer_getVsyncId(rt->mChoreographer);
     rt->mVsyncRequested = false;
-    if (rt->timeLord().vsyncReceived(frameTimeNanos) && !rt->mFrameCallbackTaskPending) {
+    if (rt->timeLord().vsyncReceived(frameTimeNanos, frameTimeNanos, vsyncId) &&
+            !rt->mFrameCallbackTaskPending) {
         ATRACE_NAME("queue mFrameCallbackTask");
         rt->mFrameCallbackTaskPending = true;
         nsecs_t runAt = (frameTimeNanos + rt->mDispatchFrameDelay);
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index d7dc00b..4fbb0716 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -19,8 +19,8 @@
 
 #include <GrDirectContext.h>
 #include <SkBitmap.h>
-#include <apex/choreographer.h>
 #include <cutils/compiler.h>
+#include <private/android/choreographer.h>
 #include <thread/ThreadBase.h>
 #include <utils/Looper.h>
 #include <utils/Thread.h>
diff --git a/libs/hwui/renderthread/TimeLord.cpp b/libs/hwui/renderthread/TimeLord.cpp
index 784068f..7dc36c4 100644
--- a/libs/hwui/renderthread/TimeLord.cpp
+++ b/libs/hwui/renderthread/TimeLord.cpp
@@ -19,9 +19,17 @@
 namespace uirenderer {
 namespace renderthread {
 
-TimeLord::TimeLord() : mFrameIntervalNanos(milliseconds_to_nanoseconds(16)), mFrameTimeNanos(0) {}
+TimeLord::TimeLord() : mFrameIntervalNanos(milliseconds_to_nanoseconds(16)),
+                       mFrameTimeNanos(0),
+                       mFrameIntendedTimeNanos(0),
+                       mFrameVsyncId(-1) {}
 
-bool TimeLord::vsyncReceived(nsecs_t vsync) {
+bool TimeLord::vsyncReceived(nsecs_t vsync, nsecs_t intendedVsync, int64_t vsyncId) {
+    if (intendedVsync > mFrameIntendedTimeNanos) {
+        mFrameIntendedTimeNanos = intendedVsync;
+        mFrameVsyncId = vsyncId;
+    }
+
     if (vsync > mFrameTimeNanos) {
         mFrameTimeNanos = vsync;
         return true;
@@ -36,6 +44,8 @@
     if (jitterNanos >= mFrameIntervalNanos) {
         nsecs_t lastFrameOffset = jitterNanos % mFrameIntervalNanos;
         mFrameTimeNanos = now - lastFrameOffset;
+        // mFrameVsyncId is not adjusted here as we still want to send
+        // the vsync id that started this frame to the Surface Composer
     }
     return mFrameTimeNanos;
 }
diff --git a/libs/hwui/renderthread/TimeLord.h b/libs/hwui/renderthread/TimeLord.h
index 68a0f7f..23c1e51 100644
--- a/libs/hwui/renderthread/TimeLord.h
+++ b/libs/hwui/renderthread/TimeLord.h
@@ -32,9 +32,10 @@
     nsecs_t frameIntervalNanos() const { return mFrameIntervalNanos; }
 
     // returns true if the vsync is newer, false if it was rejected for staleness
-    bool vsyncReceived(nsecs_t vsync);
+    bool vsyncReceived(nsecs_t vsync, nsecs_t indendedVsync, int64_t vsyncId);
     nsecs_t latestVsync() { return mFrameTimeNanos; }
     nsecs_t computeFrameTimeNanos();
+    int64_t lastVsyncId() const { return mFrameVsyncId; }
 
 private:
     friend class RenderThread;
@@ -44,6 +45,8 @@
 
     nsecs_t mFrameIntervalNanos;
     nsecs_t mFrameTimeNanos;
+    nsecs_t mFrameIntendedTimeNanos;
+    int64_t mFrameVsyncId;
 };
 
 } /* namespace renderthread */
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 801cb7d..ed89c59 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -145,7 +145,8 @@
     for (int i = 0; i < warmupFrameCount; i++) {
         testContext.waitForVsync();
         nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
-        UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
+        UiFrameInfoBuilder(proxy->frameInfo())
+            .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID);
         proxy->syncAndDrawFrame();
     }
 
@@ -165,7 +166,8 @@
         nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
         {
             ATRACE_NAME("UI-Draw Frame");
-            UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
+            UiFrameInfoBuilder(proxy->frameInfo())
+                .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID);
             scene->doFrame(i);
             proxy->syncAndDrawFrame();
         }