From 3eb07e977269b6d2ddd126f78acd6d4b4a219e71 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 8 Aug 2021 16:22:52 +0200 Subject: [PATCH] Android: Don't rely on onPause for pausing before destroying surface Fixes a crash which was uncovered (or just made more likely?) by the previous commit. --- .../fragments/EmulationFragment.java | 1 + Source/Android/jni/MainAndroid.cpp | 20 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java index ce35f1e98e..d4780e9605 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java @@ -186,6 +186,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C { Log.debug("[EmulationFragment] Surface destroyed."); NativeLibrary.SurfaceDestroyed(); + mRunWhenSurfaceIsValid = true; } public void stopEmulation() diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 1b54cd592c..53a87da1bc 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -443,7 +443,25 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceChang JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestroyed(JNIEnv*, jclass) { - std::lock_guard guard(s_surface_lock); + { + // If emulation continues running without a valid surface, we will probably crash, + // so pause emulation until we get a valid surface again. EmulationFragment handles resuming. + + std::unique_lock host_identity_guard(s_host_identity_lock); + + while (s_is_booting.IsSet()) + { + // Need to wait for boot to finish before we can pause + host_identity_guard.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + host_identity_guard.lock(); + } + + if (Core::GetState() == Core::State::Running) + Core::SetState(Core::State::Paused); + } + + std::lock_guard surface_guard(s_surface_lock); if (g_renderer) g_renderer->ChangeSurface(nullptr);