-
Notifications
You must be signed in to change notification settings - Fork 6k
Reland "Listen for Vsync callback on the UI thread directly" #31494
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,31 @@ namespace fml { | |
|
|
||
| static constexpr int kClockType = CLOCK_MONOTONIC; | ||
|
|
||
| static fml::jni::ScopedJavaGlobalRef<jclass>* g_looper_class = nullptr; | ||
| static jmethodID g_looper_prepare_method_ = nullptr; | ||
| static jmethodID g_looper_loop_method_ = nullptr; | ||
| static jmethodID g_looper_my_looper_method_ = nullptr; | ||
| static jmethodID g_looper_quit_method_ = nullptr; | ||
|
|
||
| static void LooperPrepare() { | ||
| JNIEnv* env = fml::jni::AttachCurrentThread(); | ||
| env->CallStaticVoidMethod(g_looper_class->obj(), g_looper_prepare_method_); | ||
| } | ||
|
|
||
| static void LooperLoop() { | ||
| JNIEnv* env = fml::jni::AttachCurrentThread(); | ||
| env->CallStaticVoidMethod(g_looper_class->obj(), g_looper_loop_method_); | ||
| } | ||
|
|
||
| static void LooperQuit() { | ||
| JNIEnv* env = fml::jni::AttachCurrentThread(); | ||
| auto my_looper = env->CallStaticObjectMethod(g_looper_class->obj(), | ||
| g_looper_my_looper_method_); | ||
| if (my_looper != nullptr) { | ||
| env->CallVoidMethod(my_looper, g_looper_quit_method_); | ||
| } | ||
| } | ||
|
|
||
| static ALooper* AcquireLooperForThread() { | ||
| ALooper* looper = ALooper_forThread(); | ||
|
|
||
|
|
@@ -63,23 +88,15 @@ void MessageLoopAndroid::Run() { | |
| FML_DCHECK(looper_.get() == ALooper_forThread()); | ||
|
|
||
| running_ = true; | ||
|
|
||
| while (running_) { | ||
| int result = ::ALooper_pollOnce(-1, // infinite timeout | ||
| nullptr, // out fd, | ||
| nullptr, // out events, | ||
| nullptr // out data | ||
| ); | ||
| if (result == ALOOPER_POLL_TIMEOUT || result == ALOOPER_POLL_ERROR) { | ||
| // This handles the case where the loop is terminated using ALooper APIs. | ||
| running_ = false; | ||
| } | ||
| } | ||
| // Initialize the current thread as a looper. | ||
| LooperPrepare(); | ||
| // Run the message queue in this thread. | ||
| LooperLoop(); | ||
| } | ||
|
|
||
| void MessageLoopAndroid::Terminate() { | ||
| running_ = false; | ||
| ALooper_wake(looper_.get()); | ||
| LooperQuit(); | ||
| } | ||
|
|
||
| void MessageLoopAndroid::WakeUp(fml::TimePoint time_point) { | ||
|
|
@@ -93,4 +110,30 @@ void MessageLoopAndroid::OnEventFired() { | |
| } | ||
| } | ||
|
|
||
| bool MessageLoopAndroid::Register(JNIEnv* env) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it possible to add a comment to indicate that this could just use There's not concrete plan, but worth mentioning for future maintainers that using the NDK simplifies this quite a bit.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a related issue here: flutter/flutter#62166. |
||
| jclass clazz = env->FindClass("android/os/Looper"); | ||
| FML_CHECK(clazz != nullptr); | ||
|
|
||
| g_looper_class = new fml::jni::ScopedJavaGlobalRef<jclass>(env, clazz); | ||
| FML_CHECK(!g_looper_class->is_null()); | ||
|
|
||
| g_looper_prepare_method_ = | ||
| env->GetStaticMethodID(g_looper_class->obj(), "prepare", "()V"); | ||
| FML_CHECK(g_looper_prepare_method_ != nullptr); | ||
|
|
||
| g_looper_loop_method_ = | ||
| env->GetStaticMethodID(g_looper_class->obj(), "loop", "()V"); | ||
| FML_CHECK(g_looper_loop_method_ != nullptr); | ||
|
|
||
| g_looper_my_looper_method_ = env->GetStaticMethodID( | ||
| g_looper_class->obj(), "myLooper", "()Landroid/os/Looper;"); | ||
| FML_CHECK(g_looper_my_looper_method_ != nullptr); | ||
|
|
||
| g_looper_quit_method_ = | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no check for
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's missed before, added now |
||
| env->GetMethodID(g_looper_class->obj(), "quit", "()V"); | ||
| FML_CHECK(g_looper_quit_method_ != nullptr); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| } // namespace fml | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this means that
ALooper_forThread()returnsnull? or are we calling prepare unnecessarily?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nvm, this is initializing the state in the JVM, right? could we add comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.