1313#include " flutter/fml/platform/android/scoped_java_ref.h"
1414#include " flutter/fml/size.h"
1515#include " flutter/fml/trace_event.h"
16- #include " flutter/shell/platform/android/android_choreographer.h"
1716
1817namespace flutter {
1918
2019static fml::jni::ScopedJavaGlobalRef<jclass>* g_vsync_waiter_class = nullptr ;
2120static jmethodID g_async_wait_for_vsync_method_ = nullptr ;
22- static std::atomic_uint g_refresh_rate_ = 60 ;
2321
2422VsyncWaiterAndroid::VsyncWaiterAndroid (flutter::TaskRunners task_runners)
25- : VsyncWaiter(std::move(task_runners)),
26- use_ndk_choreographer_ (
27- AndroidChoreographer::ShouldUseNDKChoreographer ()) {}
23+ : VsyncWaiter(std::move(task_runners)) {}
2824
2925VsyncWaiterAndroid::~VsyncWaiterAndroid () = default ;
3026
3127// |VsyncWaiter|
3228void VsyncWaiterAndroid::AwaitVSync () {
33- if (use_ndk_choreographer_) {
34- auto * weak_this = new std::weak_ptr<VsyncWaiter>(shared_from_this ());
35- fml::TaskRunner::RunNowOrPostTask (
36- task_runners_.GetUITaskRunner (), [weak_this]() {
37- AndroidChoreographer::PostFrameCallback (&OnVsyncFromNDK, weak_this);
38- });
39- } else {
40- // TODO(99798): Remove it when we drop support for API level < 29.
41- auto * weak_this = new std::weak_ptr<VsyncWaiter>(shared_from_this ());
42- jlong java_baton = reinterpret_cast <jlong>(weak_this);
43- task_runners_.GetPlatformTaskRunner ()->PostTask ([java_baton]() {
44- JNIEnv* env = fml::jni::AttachCurrentThread ();
45- env->CallStaticVoidMethod (g_vsync_waiter_class->obj (), //
46- g_async_wait_for_vsync_method_, //
47- java_baton //
48- );
49- });
50- }
51- }
52-
53- // static
54- void VsyncWaiterAndroid::OnVsyncFromNDK (int64_t frame_nanos, void * data) {
55- TRACE_EVENT0 (" flutter" , " VSYNC" );
56-
57- auto frame_time = fml::TimePoint::FromEpochDelta (
58- fml::TimeDelta::FromNanoseconds (frame_nanos));
59- auto now = fml::TimePoint::Now ();
60- if (frame_time > now) {
61- frame_time = now;
62- }
63- auto target_time = frame_time + fml::TimeDelta::FromNanoseconds (
64- 1000000000.0 / g_refresh_rate_);
65- auto * weak_this = reinterpret_cast <std::weak_ptr<VsyncWaiter>*>(data);
66- ConsumePendingCallback (weak_this, frame_time, target_time);
29+ auto * weak_this = new std::weak_ptr<VsyncWaiter>(shared_from_this ());
30+ jlong java_baton = reinterpret_cast <jlong>(weak_this);
31+
32+ task_runners_.GetPlatformTaskRunner ()->PostTask ([java_baton]() {
33+ JNIEnv* env = fml::jni::AttachCurrentThread ();
34+ env->CallStaticVoidMethod (g_vsync_waiter_class->obj (), //
35+ g_async_wait_for_vsync_method_, //
36+ java_baton //
37+ );
38+ });
6739}
6840
6941// static
70- void VsyncWaiterAndroid::OnVsyncFromJava (JNIEnv* env,
71- jclass jcaller,
72- jlong frameDelayNanos,
73- jlong refreshPeriodNanos,
74- jlong java_baton) {
42+ void VsyncWaiterAndroid::OnNativeVsync (JNIEnv* env,
43+ jclass jcaller,
44+ jlong frameDelayNanos,
45+ jlong refreshPeriodNanos,
46+ jlong java_baton) {
7547 TRACE_EVENT0 (" flutter" , " VSYNC" );
7648
7749 auto frame_time =
7850 fml::TimePoint::Now () - fml::TimeDelta::FromNanoseconds (frameDelayNanos);
7951 auto target_time =
8052 frame_time + fml::TimeDelta::FromNanoseconds (refreshPeriodNanos);
8153
82- auto * weak_this = reinterpret_cast <std::weak_ptr<VsyncWaiter>*>(java_baton);
83- ConsumePendingCallback (weak_this, frame_time, target_time);
54+ ConsumePendingCallback (java_baton, frame_time, target_time);
8455}
8556
8657// static
8758void VsyncWaiterAndroid::ConsumePendingCallback (
88- std::weak_ptr<VsyncWaiter>* weak_this ,
59+ jlong java_baton ,
8960 fml::TimePoint frame_start_time,
9061 fml::TimePoint frame_target_time) {
62+ auto * weak_this = reinterpret_cast <std::weak_ptr<VsyncWaiter>*>(java_baton);
9163 auto shared_this = weak_this->lock ();
9264 delete weak_this;
9365
@@ -96,27 +68,13 @@ void VsyncWaiterAndroid::ConsumePendingCallback(
9668 }
9769}
9870
99- // static
100- void VsyncWaiterAndroid::OnUpdateRefreshRate (JNIEnv* env,
101- jclass jcaller,
102- jfloat refresh_rate) {
103- FML_DCHECK (refresh_rate > 0 );
104- g_refresh_rate_ = static_cast <uint>(refresh_rate);
105- }
106-
10771// static
10872bool VsyncWaiterAndroid::Register (JNIEnv* env) {
109- static const JNINativeMethod methods[] = {
110- {
111- .name = " nativeOnVsync" ,
112- .signature = " (JJJ)V" ,
113- .fnPtr = reinterpret_cast <void *>(&OnVsyncFromJava),
114- },
115- {
116- .name = " nativeUpdateRefreshRate" ,
117- .signature = " (F)V" ,
118- .fnPtr = reinterpret_cast <void *>(&OnUpdateRefreshRate),
119- }};
73+ static const JNINativeMethod methods[] = {{
74+ .name = " nativeOnVsync" ,
75+ .signature = " (JJJ)V" ,
76+ .fnPtr = reinterpret_cast <void *>(&OnNativeVsync),
77+ }};
12078
12179 jclass clazz = env->FindClass (" io/flutter/embedding/engine/FlutterJNI" );
12280
@@ -125,10 +83,12 @@ bool VsyncWaiterAndroid::Register(JNIEnv* env) {
12583 }
12684
12785 g_vsync_waiter_class = new fml::jni::ScopedJavaGlobalRef<jclass>(env, clazz);
86+
12887 FML_CHECK (!g_vsync_waiter_class->is_null ());
12988
13089 g_async_wait_for_vsync_method_ = env->GetStaticMethodID (
13190 g_vsync_waiter_class->obj (), " asyncWaitForVsync" , " (J)V" );
91+
13292 FML_CHECK (g_async_wait_for_vsync_method_ != nullptr );
13393
13494 return env->RegisterNatives (clazz, methods, fml::size (methods)) == 0 ;
0 commit comments