From 6fde4c494487d26d92904e18cfb209108ffbbac9 Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Sun, 6 Mar 2022 19:36:41 +0800 Subject: [PATCH 1/3] Use AChoreographer methods to await vsync when available --- ci/licenses_golden/licenses_flutter | 2 + shell/platform/android/BUILD.gn | 2 + .../platform/android/android_choreographer.cc | 59 ++++++++++++ .../platform/android/android_choreographer.h | 24 +++++ .../flutter/embedding/engine/FlutterJNI.java | 10 ++ .../engine/loader/FlutterLoader.java | 1 + .../embedding/engine/FlutterJNITest.java | 10 ++ .../engine/loader/FlutterLoaderTest.java | 1 + .../platform/android/vsync_waiter_android.cc | 91 +++++++++++++------ shell/platform/android/vsync_waiter_android.h | 23 +++-- 10 files changed, 191 insertions(+), 32 deletions(-) create mode 100644 shell/platform/android/android_choreographer.cc create mode 100644 shell/platform/android/android_choreographer.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 16a564aa2ca35..c1c1f6a9b0621 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1093,6 +1093,8 @@ FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan.h FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan_delegate.cc FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan_delegate.h FILE: ../../../flutter/shell/platform/android/AndroidManifest.xml +FILE: ../../../flutter/shell/platform/android/android_choreographer.cc +FILE: ../../../flutter/shell/platform/android/android_choreographer.h FILE: ../../../flutter/shell/platform/android/android_context_gl.cc FILE: ../../../flutter/shell/platform/android/android_context_gl.h FILE: ../../../flutter/shell/platform/android/android_context_gl_unittests.cc diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index 41f9e3aed0ec7..295fe48c972d3 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -62,6 +62,8 @@ source_set("flutter_shell_native_src") { sources = [ "$root_build_dir/flutter_icu/icudtl.o", + "android_choreographer.cc", + "android_choreographer.h", "android_context_gl.cc", "android_context_gl.h", "android_display.cc", diff --git a/shell/platform/android/android_choreographer.cc b/shell/platform/android/android_choreographer.cc new file mode 100644 index 0000000000000..fe9a1aa89c7b2 --- /dev/null +++ b/shell/platform/android/android_choreographer.cc @@ -0,0 +1,59 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/android/android_choreographer.h" + +#include "flutter/fml/native_library.h" + +// Only avialalbe on API 24+ +typedef void AChoreographer; +typedef void (*AChoreographer_frameCallback)(int64_t frameTimeNanos, + void* data); +typedef AChoreographer* (*AChoreographer_getInstance_FPN)(); +typedef void (*AChoreographer_postFrameCallback_FPN)( + AChoreographer* choreographer, + AChoreographer_frameCallback callback, + void* data); +static AChoreographer_getInstance_FPN AChoreographer_getInstance; +static AChoreographer_postFrameCallback_FPN AChoreographer_postFrameCallback; + +namespace flutter { + +bool AndroidChoreographer::ShouldUseNDKChoreographer() { + static std::optional should_use_ndk_choreographer; + if (should_use_ndk_choreographer) { + return should_use_ndk_choreographer.value(); + } + auto libandroid = fml::NativeLibrary::Create("libandroid.so"); + FML_DCHECK(libandroid); + auto get_instance_fn = + libandroid->ResolveFunction( + "AChoreographer_getInstance"); + auto post_frame_callback_fn = + libandroid->ResolveFunction( + "AChoreographer_postFrameCallback64"); +#if FML_ARCH_CPU_64_BITS + if (!post_frame_callback_fn) { + post_frame_callback_fn = + libandroid->ResolveFunction( + "AChoreographer_postFrameCallback"); + } +#endif + if (get_instance_fn && post_frame_callback_fn) { + AChoreographer_getInstance = get_instance_fn.value(); + AChoreographer_postFrameCallback = post_frame_callback_fn.value(); + should_use_ndk_choreographer = true; + } else { + should_use_ndk_choreographer = false; + } + return should_use_ndk_choreographer.value(); +} + +void AndroidChoreographer::PostFrameCallback(OnFrameCallback callback, + void* data) { + AChoreographer* choreographer = AChoreographer_getInstance(); + AChoreographer_postFrameCallback(choreographer, callback, data); +} + +} // namespace flutter diff --git a/shell/platform/android/android_choreographer.h b/shell/platform/android/android_choreographer.h new file mode 100644 index 0000000000000..dbbfc56f1703e --- /dev/null +++ b/shell/platform/android/android_choreographer.h @@ -0,0 +1,24 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CHOREOGRAPHER_H_ +#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CHOREOGRAPHER_H_ + +#include "flutter/fml/macros.h" + +#include + +namespace flutter { +class AndroidChoreographer { + public: + typedef void (*OnFrameCallback)(int64_t frame_time_nanos, void* data); + static bool ShouldUseNDKChoreographer(); + static void PostFrameCallback(OnFrameCallback callback, void* data); + + FML_DISALLOW_COPY_AND_ASSIGN(AndroidChoreographer); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CHOREOGRAPHER_H_ diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index 128eb5c6a8e8d..9c6cc3b3ed06f 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -257,8 +257,18 @@ public void setRefreshRateFPS(float refreshRateFPS) { // on Android we will need to refactor this. Static lookup makes things a // bit easier on the C++ side. FlutterJNI.refreshRateFPS = refreshRateFPS; + updateRefreshRate(); } + public void updateRefreshRate() { + if (!FlutterJNI.loadLibraryCalled) { + return; + } + nativeUpdateRefreshRate(refreshRateFPS); + } + + private native void nativeUpdateRefreshRate(float refreshRateFPS); + /** * The Android vsync waiter implementation in C++ needs to know when a vsync signal arrives, which * is obtained via Java API. The delegate set here is called on the C++ side when the engine is diff --git a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java index 6720951c808a9..3eb6ba4781fb8 100644 --- a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java +++ b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java @@ -185,6 +185,7 @@ public InitResult call() { ResourceExtractor resourceExtractor = initResources(appContext); flutterJNI.loadLibrary(); + flutterJNI.updateRefreshRate(); // Prefetch the default font manager as soon as possible on a background thread. // It helps to reduce time cost of engine setup that blocks the platform thread. diff --git a/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java b/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java index 56c5ebc3b8e3b..cf6dca23f8deb 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java @@ -2,6 +2,7 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -245,4 +246,13 @@ public void invokePlatformMessageResponseCallback__wantsDirectBuffer() { ByteBuffer buffer = ByteBuffer.allocate(4); flutterJNI.invokePlatformMessageResponseCallback(0, buffer, buffer.position()); } + + @Test + public void setRefreshRateFPS__callsUpdateRefreshRate() { + FlutterJNI flutterJNI = spy(new FlutterJNI()); + // --- Execute Test --- + flutterJNI.setRefreshRateFPS(120.0f); + // --- Verify Results --- + verify(flutterJNI, times(1)).updateRefreshRate(); + } } diff --git a/shell/platform/android/test/io/flutter/embedding/engine/loader/FlutterLoaderTest.java b/shell/platform/android/test/io/flutter/embedding/engine/loader/FlutterLoaderTest.java index e585dd96717bf..4ec39d00ae58b 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/loader/FlutterLoaderTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/loader/FlutterLoaderTest.java @@ -55,6 +55,7 @@ public void itReportsInitializedAfterInitializing() { shadowOf(getMainLooper()).idle(); assertTrue(flutterLoader.initialized()); verify(mockFlutterJNI, times(1)).loadLibrary(); + verify(mockFlutterJNI, times(1)).updateRefreshRate(); } @Test diff --git a/shell/platform/android/vsync_waiter_android.cc b/shell/platform/android/vsync_waiter_android.cc index 1a69705f634d4..55bfe3ce25547 100644 --- a/shell/platform/android/vsync_waiter_android.cc +++ b/shell/platform/android/vsync_waiter_android.cc @@ -13,37 +13,64 @@ #include "flutter/fml/platform/android/scoped_java_ref.h" #include "flutter/fml/size.h" #include "flutter/fml/trace_event.h" +#include "flutter/shell/platform/android/android_choreographer.h" namespace flutter { static fml::jni::ScopedJavaGlobalRef* g_vsync_waiter_class = nullptr; static jmethodID g_async_wait_for_vsync_method_ = nullptr; +static std::atomic_uint g_refresh_rate_ = 60; VsyncWaiterAndroid::VsyncWaiterAndroid(flutter::TaskRunners task_runners) - : VsyncWaiter(std::move(task_runners)) {} + : VsyncWaiter(std::move(task_runners)), + should_use_ndk_choreographer_( + AndroidChoreographer::ShouldUseNDKChoreographer()) {} VsyncWaiterAndroid::~VsyncWaiterAndroid() = default; // |VsyncWaiter| void VsyncWaiterAndroid::AwaitVSync() { - auto* weak_this = new std::weak_ptr(shared_from_this()); - jlong java_baton = reinterpret_cast(weak_this); - - task_runners_.GetPlatformTaskRunner()->PostTask([java_baton]() { - JNIEnv* env = fml::jni::AttachCurrentThread(); - env->CallStaticVoidMethod(g_vsync_waiter_class->obj(), // - g_async_wait_for_vsync_method_, // - java_baton // - ); - }); + if (should_use_ndk_choreographer_) { + auto* weak_this = new std::weak_ptr(shared_from_this()); + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetUITaskRunner(), [weak_this]() { + AndroidChoreographer::PostFrameCallback(&OnVsyncFromNDK, weak_this); + }); + } else { + auto* weak_this = new std::weak_ptr(shared_from_this()); + jlong java_baton = reinterpret_cast(weak_this); + task_runners_.GetPlatformTaskRunner()->PostTask([java_baton]() { + JNIEnv* env = fml::jni::AttachCurrentThread(); + env->CallStaticVoidMethod(g_vsync_waiter_class->obj(), // + g_async_wait_for_vsync_method_, // + java_baton // + ); + }); + } +} + +// static +void VsyncWaiterAndroid::OnVsyncFromNDK(int64_t frame_nanos, void* data) { + TRACE_EVENT0("flutter", "VSYNC"); + + auto frame_time = fml::TimePoint::FromEpochDelta( + fml::TimeDelta::FromNanoseconds(frame_nanos)); + auto now = fml::TimePoint::Now(); + if (frame_time > now) { + frame_time = now; + } + auto target_time = frame_time + fml::TimeDelta::FromNanoseconds( + 1000000000.0 / g_refresh_rate_); + auto* weak_this = reinterpret_cast*>(data); + ConsumePendingCallback(weak_this, frame_time, target_time); } // static -void VsyncWaiterAndroid::OnNativeVsync(JNIEnv* env, - jclass jcaller, - jlong frameDelayNanos, - jlong refreshPeriodNanos, - jlong java_baton) { +void VsyncWaiterAndroid::OnVsyncFromJava(JNIEnv* env, + jclass jcaller, + jlong frameDelayNanos, + jlong refreshPeriodNanos, + jlong java_baton) { TRACE_EVENT0("flutter", "VSYNC"); auto frame_time = @@ -51,15 +78,15 @@ void VsyncWaiterAndroid::OnNativeVsync(JNIEnv* env, auto target_time = frame_time + fml::TimeDelta::FromNanoseconds(refreshPeriodNanos); - ConsumePendingCallback(java_baton, frame_time, target_time); + auto* weak_this = reinterpret_cast*>(java_baton); + ConsumePendingCallback(weak_this, frame_time, target_time); } // static void VsyncWaiterAndroid::ConsumePendingCallback( - jlong java_baton, + std::weak_ptr* weak_this, fml::TimePoint frame_start_time, fml::TimePoint frame_target_time) { - auto* weak_this = reinterpret_cast*>(java_baton); auto shared_this = weak_this->lock(); delete weak_this; @@ -68,13 +95,27 @@ void VsyncWaiterAndroid::ConsumePendingCallback( } } +// static +void VsyncWaiterAndroid::OnUpdateRefreshRate(JNIEnv* env, + jclass jcaller, + jfloat refresh_rate) { + FML_DCHECK(refresh_rate > 0); + g_refresh_rate_ = static_cast(refresh_rate); +} + // static bool VsyncWaiterAndroid::Register(JNIEnv* env) { - static const JNINativeMethod methods[] = {{ - .name = "nativeOnVsync", - .signature = "(JJJ)V", - .fnPtr = reinterpret_cast(&OnNativeVsync), - }}; + static const JNINativeMethod methods[] = { + { + .name = "nativeOnVsync", + .signature = "(JJJ)V", + .fnPtr = reinterpret_cast(&OnVsyncFromJava), + }, + { + .name = "nativeUpdateRefreshRate", + .signature = "(F)V", + .fnPtr = reinterpret_cast(&OnUpdateRefreshRate), + }}; jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI"); @@ -83,12 +124,10 @@ bool VsyncWaiterAndroid::Register(JNIEnv* env) { } g_vsync_waiter_class = new fml::jni::ScopedJavaGlobalRef(env, clazz); - FML_CHECK(!g_vsync_waiter_class->is_null()); g_async_wait_for_vsync_method_ = env->GetStaticMethodID( g_vsync_waiter_class->obj(), "asyncWaitForVsync", "(J)V"); - FML_CHECK(g_async_wait_for_vsync_method_ != nullptr); return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0; diff --git a/shell/platform/android/vsync_waiter_android.h b/shell/platform/android/vsync_waiter_android.h index 841832f503ee7..8b04ca9efddc6 100644 --- a/shell/platform/android/vsync_waiter_android.h +++ b/shell/platform/android/vsync_waiter_android.h @@ -14,6 +14,8 @@ namespace flutter { +class AndroidChoreographer; + class VsyncWaiterAndroid final : public VsyncWaiter { public: static bool Register(JNIEnv* env); @@ -26,16 +28,25 @@ class VsyncWaiterAndroid final : public VsyncWaiter { // |VsyncWaiter| void AwaitVSync() override; - static void OnNativeVsync(JNIEnv* env, - jclass jcaller, - jlong frameDelayNanos, - jlong refreshPeriodNanos, - jlong java_baton); + static void OnVsyncFromNDK(int64_t frame_nanos, void* data); + + static void OnVsyncFromJava(JNIEnv* env, + jclass jcaller, + jlong frameDelayNanos, + jlong refreshPeriodNanos, + jlong java_baton); - static void ConsumePendingCallback(jlong java_baton, + static void ConsumePendingCallback(std::weak_ptr* weak_this, fml::TimePoint frame_start_time, fml::TimePoint frame_target_time); + static void OnUpdateRefreshRate(JNIEnv* env, + jclass jcaller, + jfloat refresh_rate); + + bool should_use_ndk_choreographer_; + std::unique_ptr choreographer_; + FML_DISALLOW_COPY_AND_ASSIGN(VsyncWaiterAndroid); }; From 39705b6c4e49c78238f5e779f050948827762ddd Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Tue, 8 Mar 2022 16:35:44 +0800 Subject: [PATCH 2/3] Add some comments --- shell/platform/android/android_choreographer.cc | 2 ++ shell/platform/android/android_choreographer.h | 5 +++++ shell/platform/android/vsync_waiter_android.cc | 1 + shell/platform/android/vsync_waiter_android.h | 4 +--- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/shell/platform/android/android_choreographer.cc b/shell/platform/android/android_choreographer.cc index fe9a1aa89c7b2..43fc7297ca795 100644 --- a/shell/platform/android/android_choreographer.cc +++ b/shell/platform/android/android_choreographer.cc @@ -8,8 +8,10 @@ // Only avialalbe on API 24+ typedef void AChoreographer; +// Only avialalbe on API 29+ or API 24+ and architecture is 64-bit typedef void (*AChoreographer_frameCallback)(int64_t frameTimeNanos, void* data); +// Only avialalbe on API 24+ typedef AChoreographer* (*AChoreographer_getInstance_FPN)(); typedef void (*AChoreographer_postFrameCallback_FPN)( AChoreographer* choreographer, diff --git a/shell/platform/android/android_choreographer.h b/shell/platform/android/android_choreographer.h index dbbfc56f1703e..e2607cd7b4627 100644 --- a/shell/platform/android/android_choreographer.h +++ b/shell/platform/android/android_choreographer.h @@ -10,6 +10,11 @@ #include namespace flutter { + +//------------------------------------------------------------------------------ +/// The Android Choreographer is used by `VsyncWaiterAndroid` to await vsync +/// signal. It's only avialalbe on API 29+ or API 24+ and architecture is 64-bit +/// class AndroidChoreographer { public: typedef void (*OnFrameCallback)(int64_t frame_time_nanos, void* data); diff --git a/shell/platform/android/vsync_waiter_android.cc b/shell/platform/android/vsync_waiter_android.cc index 55bfe3ce25547..61140f640a764 100644 --- a/shell/platform/android/vsync_waiter_android.cc +++ b/shell/platform/android/vsync_waiter_android.cc @@ -37,6 +37,7 @@ void VsyncWaiterAndroid::AwaitVSync() { AndroidChoreographer::PostFrameCallback(&OnVsyncFromNDK, weak_this); }); } else { + // TODO: Remove the JNI fallback when we drop support for API level < 29. auto* weak_this = new std::weak_ptr(shared_from_this()); jlong java_baton = reinterpret_cast(weak_this); task_runners_.GetPlatformTaskRunner()->PostTask([java_baton]() { diff --git a/shell/platform/android/vsync_waiter_android.h b/shell/platform/android/vsync_waiter_android.h index 8b04ca9efddc6..7ef18c13bfb66 100644 --- a/shell/platform/android/vsync_waiter_android.h +++ b/shell/platform/android/vsync_waiter_android.h @@ -44,9 +44,7 @@ class VsyncWaiterAndroid final : public VsyncWaiter { jclass jcaller, jfloat refresh_rate); - bool should_use_ndk_choreographer_; - std::unique_ptr choreographer_; - + const bool should_use_ndk_choreographer_; FML_DISALLOW_COPY_AND_ASSIGN(VsyncWaiterAndroid); }; From 9bed5af4bf4a968c4e402bfa5b9993da46c63441 Mon Sep 17 00:00:00 2001 From: ColdPaleLight Date: Wed, 9 Mar 2022 11:43:10 +0800 Subject: [PATCH 3/3] tweak the code --- shell/platform/android/android_choreographer.cc | 14 +++++++------- shell/platform/android/android_choreographer.h | 3 ++- shell/platform/android/vsync_waiter_android.cc | 6 +++--- shell/platform/android/vsync_waiter_android.h | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/shell/platform/android/android_choreographer.cc b/shell/platform/android/android_choreographer.cc index 43fc7297ca795..f72787f423920 100644 --- a/shell/platform/android/android_choreographer.cc +++ b/shell/platform/android/android_choreographer.cc @@ -8,7 +8,7 @@ // Only avialalbe on API 24+ typedef void AChoreographer; -// Only avialalbe on API 29+ or API 24+ and architecture is 64-bit +// Only available on API 29+ or API 24+ if the architecture is 64-bit. typedef void (*AChoreographer_frameCallback)(int64_t frameTimeNanos, void* data); // Only avialalbe on API 24+ @@ -23,9 +23,9 @@ static AChoreographer_postFrameCallback_FPN AChoreographer_postFrameCallback; namespace flutter { bool AndroidChoreographer::ShouldUseNDKChoreographer() { - static std::optional should_use_ndk_choreographer; - if (should_use_ndk_choreographer) { - return should_use_ndk_choreographer.value(); + static std::optional use_ndk_choreographer; + if (use_ndk_choreographer) { + return use_ndk_choreographer.value(); } auto libandroid = fml::NativeLibrary::Create("libandroid.so"); FML_DCHECK(libandroid); @@ -45,11 +45,11 @@ bool AndroidChoreographer::ShouldUseNDKChoreographer() { if (get_instance_fn && post_frame_callback_fn) { AChoreographer_getInstance = get_instance_fn.value(); AChoreographer_postFrameCallback = post_frame_callback_fn.value(); - should_use_ndk_choreographer = true; + use_ndk_choreographer = true; } else { - should_use_ndk_choreographer = false; + use_ndk_choreographer = false; } - return should_use_ndk_choreographer.value(); + return use_ndk_choreographer.value(); } void AndroidChoreographer::PostFrameCallback(OnFrameCallback callback, diff --git a/shell/platform/android/android_choreographer.h b/shell/platform/android/android_choreographer.h index e2607cd7b4627..632bc77479e48 100644 --- a/shell/platform/android/android_choreographer.h +++ b/shell/platform/android/android_choreographer.h @@ -13,7 +13,8 @@ namespace flutter { //------------------------------------------------------------------------------ /// The Android Choreographer is used by `VsyncWaiterAndroid` to await vsync -/// signal. It's only avialalbe on API 29+ or API 24+ and architecture is 64-bit +/// signal. It's only available on API 29+ or API 24+ if the architecture is +/// 64-bit. /// class AndroidChoreographer { public: diff --git a/shell/platform/android/vsync_waiter_android.cc b/shell/platform/android/vsync_waiter_android.cc index 61140f640a764..e2601a16b7b17 100644 --- a/shell/platform/android/vsync_waiter_android.cc +++ b/shell/platform/android/vsync_waiter_android.cc @@ -23,21 +23,21 @@ static std::atomic_uint g_refresh_rate_ = 60; VsyncWaiterAndroid::VsyncWaiterAndroid(flutter::TaskRunners task_runners) : VsyncWaiter(std::move(task_runners)), - should_use_ndk_choreographer_( + use_ndk_choreographer_( AndroidChoreographer::ShouldUseNDKChoreographer()) {} VsyncWaiterAndroid::~VsyncWaiterAndroid() = default; // |VsyncWaiter| void VsyncWaiterAndroid::AwaitVSync() { - if (should_use_ndk_choreographer_) { + if (use_ndk_choreographer_) { auto* weak_this = new std::weak_ptr(shared_from_this()); fml::TaskRunner::RunNowOrPostTask( task_runners_.GetUITaskRunner(), [weak_this]() { AndroidChoreographer::PostFrameCallback(&OnVsyncFromNDK, weak_this); }); } else { - // TODO: Remove the JNI fallback when we drop support for API level < 29. + // TODO(99798): Remove it when we drop support for API level < 29. auto* weak_this = new std::weak_ptr(shared_from_this()); jlong java_baton = reinterpret_cast(weak_this); task_runners_.GetPlatformTaskRunner()->PostTask([java_baton]() { diff --git a/shell/platform/android/vsync_waiter_android.h b/shell/platform/android/vsync_waiter_android.h index 7ef18c13bfb66..3eef39f116ae3 100644 --- a/shell/platform/android/vsync_waiter_android.h +++ b/shell/platform/android/vsync_waiter_android.h @@ -44,7 +44,7 @@ class VsyncWaiterAndroid final : public VsyncWaiter { jclass jcaller, jfloat refresh_rate); - const bool should_use_ndk_choreographer_; + const bool use_ndk_choreographer_; FML_DISALLOW_COPY_AND_ASSIGN(VsyncWaiterAndroid); };