diff options
| author | JosJuice <josjuice@gmail.com> | 2024-08-21 20:36:46 +0200 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2024-08-21 20:36:46 +0200 |
| commit | dcf8ab01898eb71bcf4aca1fa527e6cd196367da (patch) | |
| tree | 3e51a6fa4cf59f33d0e2d52654b17d0f9257031b /Source/Android/jni/MainAndroid.cpp | |
| parent | 93617e96c3c208e032f31053e1b02f6c9ddc35e9 (diff) | |
Android: Wait for surface in Run
When we boot the core, it needs to have a valid surface to draw graphics
to. Our Kotlin code does wait for a valid surface to exist before it
calls NativeLibrary.Run, but there's a chance for the surface to be
deleted before Run locks s_surface_lock. If that happens, the core boots
without a valid surface, which presumably would cause a crash. (I
haven't been able to reproduce the problem myself.)
Diffstat (limited to 'Source/Android/jni/MainAndroid.cpp')
| -rw-r--r-- | Source/Android/jni/MainAndroid.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 811b28c32b..d73cd904dc 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -1,13 +1,9 @@ // Copyright 2003 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include <EGL/egl.h> -#include <android/log.h> -#include <android/native_window_jni.h> +#include <condition_variable> #include <cstdio> #include <cstdlib> -#include <fmt/format.h> -#include <jni.h> #include <memory> #include <mutex> #include <optional> @@ -15,6 +11,12 @@ #include <thread> #include <utility> +#include <EGL/egl.h> +#include <android/log.h> +#include <android/native_window_jni.h> +#include <fmt/format.h> +#include <jni.h> + #include "Common/AndroidAnalytics.h" #include "Common/Assert.h" #include "Common/CPUDetect.h" @@ -77,6 +79,8 @@ Common::Event s_update_main_frame_event; // This exists to prevent surfaces from being destroyed during the boot process, // as that can lead to the boot process dereferencing nullptr. std::mutex s_surface_lock; +std::condition_variable s_surface_cv; + bool s_need_nonblocking_alert_msg; Common::Flag s_is_booting; @@ -454,6 +458,8 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceChang if (g_presenter) g_presenter->ChangeSurface(s_surf); + + s_surface_cv.notify_all(); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestroyed(JNIEnv*, @@ -487,6 +493,8 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestr ANativeWindow_release(s_surf); s_surf = nullptr; } + + s_surface_cv.notify_all(); } JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_HasSurface(JNIEnv*, jclass) @@ -578,12 +586,14 @@ static void Run(JNIEnv* env, std::unique_ptr<BootParameters>&& boot, bool riivol volume.GetDiscNumber())); } - WindowSystemInfo wsi(WindowSystemType::Android, nullptr, s_surf, s_surf); - wsi.render_surface_scale = GetRenderSurfaceScale(env); - s_need_nonblocking_alert_msg = true; std::unique_lock<std::mutex> surface_guard(s_surface_lock); + s_surface_cv.wait(surface_guard, []() { return s_surf != nullptr; }); + + WindowSystemInfo wsi(WindowSystemType::Android, nullptr, s_surf, s_surf); + wsi.render_surface_scale = GetRenderSurfaceScale(env); + if (BootManager::BootCore(Core::System::GetInstance(), std::move(boot), wsi)) { static constexpr int WAIT_STEP = 25; |
