From 628cf20360e62ab654fc33c93f9e6f7d60182223 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Fri, 8 Oct 2021 17:44:39 -0700 Subject: [PATCH] Map the Android VsyncWaiter frame start time to the clock used by fml::TimePoint The Android Choreographer.doFrame callback provides a timestamp in the clock used by System.nanoTime. The VsyncWaiter needs to translate this to a frame start time based on the fml::TimePoint clock (similar to how VsyncWaiterIOS calculates the frame start time) --- .../io/flutter/embedding/engine/FlutterJNI.java | 2 +- .../android/io/flutter/view/VsyncWaiter.java | 10 +++++++--- shell/platform/android/vsync_waiter_android.cc | 12 ++++++------ shell/platform/android/vsync_waiter_android.h | 4 ++-- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index b06487d61434f..4ac8740641541 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -238,7 +238,7 @@ private static void asyncWaitForVsync(final long cookie) { // TODO(mattcarroll): add javadocs public static native void nativeOnVsync( - long frameTimeNanos, long frameTargetTimeNanos, long cookie); + long frameDelayNanos, long refreshPeriodNanos, long cookie); // TODO(mattcarroll): add javadocs @NonNull diff --git a/shell/platform/android/io/flutter/view/VsyncWaiter.java b/shell/platform/android/io/flutter/view/VsyncWaiter.java index 89ff20dbee951..714511f5bb3fa 100644 --- a/shell/platform/android/io/flutter/view/VsyncWaiter.java +++ b/shell/platform/android/io/flutter/view/VsyncWaiter.java @@ -21,6 +21,7 @@ public static VsyncWaiter getInstance(float fps) { } private final float fps; + private final long refreshPeriodNanos; private final FlutterJNI.AsyncWaitForVsyncDelegate asyncWaitForVsyncDelegate = new FlutterJNI.AsyncWaitForVsyncDelegate() { @@ -31,9 +32,11 @@ public void asyncWaitForVsync(long cookie) { new Choreographer.FrameCallback() { @Override public void doFrame(long frameTimeNanos) { - long refreshPeriodNanos = (long) (1000000000.0 / fps); - FlutterJNI.nativeOnVsync( - frameTimeNanos, frameTimeNanos + refreshPeriodNanos, cookie); + long delay = System.nanoTime() - frameTimeNanos; + if (delay < 0) { + delay = 0; + } + FlutterJNI.nativeOnVsync(delay, refreshPeriodNanos, cookie); } }); } @@ -41,6 +44,7 @@ public void doFrame(long frameTimeNanos) { private VsyncWaiter(float fps) { this.fps = fps; + refreshPeriodNanos = (long) (1000000000.0 / fps); } public void init() { diff --git a/shell/platform/android/vsync_waiter_android.cc b/shell/platform/android/vsync_waiter_android.cc index 2851eec5f58e5..1a69705f634d4 100644 --- a/shell/platform/android/vsync_waiter_android.cc +++ b/shell/platform/android/vsync_waiter_android.cc @@ -41,15 +41,15 @@ void VsyncWaiterAndroid::AwaitVSync() { // static void VsyncWaiterAndroid::OnNativeVsync(JNIEnv* env, jclass jcaller, - jlong frameTimeNanos, - jlong frameTargetTimeNanos, + jlong frameDelayNanos, + jlong refreshPeriodNanos, jlong java_baton) { TRACE_EVENT0("flutter", "VSYNC"); - auto frame_time = fml::TimePoint::FromEpochDelta( - fml::TimeDelta::FromNanoseconds(frameTimeNanos)); - auto target_time = fml::TimePoint::FromEpochDelta( - fml::TimeDelta::FromNanoseconds(frameTargetTimeNanos)); + auto frame_time = + fml::TimePoint::Now() - fml::TimeDelta::FromNanoseconds(frameDelayNanos); + auto target_time = + frame_time + fml::TimeDelta::FromNanoseconds(refreshPeriodNanos); ConsumePendingCallback(java_baton, frame_time, target_time); } diff --git a/shell/platform/android/vsync_waiter_android.h b/shell/platform/android/vsync_waiter_android.h index 96fcc8c0e16ec..03bc415e3ae99 100644 --- a/shell/platform/android/vsync_waiter_android.h +++ b/shell/platform/android/vsync_waiter_android.h @@ -28,8 +28,8 @@ class VsyncWaiterAndroid final : public VsyncWaiter { static void OnNativeVsync(JNIEnv* env, jclass jcaller, - jlong frameTimeNanos, - jlong frameTargetTimeNanos, + jlong frameDelayNanos, + jlong refreshPeriodNanos, jlong java_baton); static void ConsumePendingCallback(jlong java_baton,