From f17f2f5bb5cbc44b51562a59bcc3e786b161c9dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 22 Dec 2022 10:03:28 +0100 Subject: [PATCH 1/6] Remove more dead code in app-android.cpp --- android/jni/app-android.cpp | 54 ++++++++++++------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 03bc0e6d73..eea417e12b 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -172,20 +172,19 @@ static jmethodID postCommand; static jmethodID getDebugString; static jobject nativeActivity; + static volatile bool exitRenderLoop; static bool renderLoopRunning; +static bool renderer_inited = false; +static std::mutex renderLock; + static int inputBoxSequence = 1; std::map> inputBoxCallbacks; static float dp_xscale = 1.0f; static float dp_yscale = 1.0f; -static bool renderer_inited = false; static bool sustainedPerfSupported = false; -static std::mutex renderLock; - -// See NativeQueryConfig("androidJavaGL") to change this value. -static bool javaGL = true; static std::string library_path; static std::map permissions; @@ -737,14 +736,12 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init retry: switch (g_Config.iGPUBackend) { case (int)GPUBackend::OPENGL: - javaGL = true; useCPUThread = true; INFO_LOG(SYSTEM, "NativeApp.init() -- creating OpenGL context (JavaGL)"); graphicsContext = new AndroidJavaEGLGraphicsContext(); break; case (int)GPUBackend::VULKAN: { - javaGL = false; INFO_LOG(SYSTEM, "NativeApp.init() -- creating Vulkan context"); useCPUThread = false; // The Vulkan render manager manages its own thread. // We create and destroy the Vulkan graphics context in the "EGL" thread. @@ -1353,7 +1350,7 @@ std::vector __cameraGetDeviceList() { jint arrayListObjectLen = getEnv()->CallIntMethod(deviceListObject, arrayListSize); std::vector deviceListVector; - for (int i=0; i < arrayListObjectLen; i++) { + for (int i = 0; i < arrayListObjectLen; i++) { jstring dev = static_cast(getEnv()->CallObjectMethod(deviceListObject, arrayListGet, i)); const char* cdev = getEnv()->GetStringUTFChars(dev, nullptr); deviceListVector.push_back(cdev); @@ -1407,14 +1404,15 @@ static void ProcessFrameCommands(JNIEnv *env) { } } +// This runs in Vulkan mode only. extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(JNIEnv *env, jobject obj, jobject _surf) { + _assert_(!useCPUThread); + if (!graphicsContext) { ERROR_LOG(G3D, "runEGLRenderLoop: Tried to enter without a created graphics context."); return false; } - // Needed for Vulkan, even if we're not using the old EGL path. - exitRenderLoop = false; // This is up here to prevent race conditions, in case we pause during init. renderLoopRunning = true; @@ -1459,11 +1457,9 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J } if (!exitRenderLoop) { - if (!useCPUThread) { - if (!NativeInitGraphics(graphicsContext)) { - ERROR_LOG(G3D, "Failed to initialize graphics."); - // Gonna be in a weird state here.. - } + if (!NativeInitGraphics(graphicsContext)) { + ERROR_LOG(G3D, "Failed to initialize graphics."); + // Gonna be in a weird state here.. } graphicsContext->ThreadStart(); renderer_inited = true; @@ -1477,33 +1473,17 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J } } - if (useCPUThread) { - ERROR_LOG(SYSTEM, "Running graphics loop"); - while (!exitRenderLoop) { - // This is the "GPU thread". - graphicsContext->ThreadFrame(); - graphicsContext->SwapBuffers(); - } - } else { - while (!exitRenderLoop) { - LockedNativeUpdateRender(); - graphicsContext->SwapBuffers(); + while (!exitRenderLoop) { + LockedNativeUpdateRender(); + graphicsContext->SwapBuffers(); - ProcessFrameCommands(env); - } + ProcessFrameCommands(env); } INFO_LOG(G3D, "Leaving EGL/Vulkan render loop."); - if (useCPUThread) { - EmuThreadStop("exitrenderloop"); - while (graphicsContext->ThreadFrame()) { - continue; - } - EmuThreadJoin(); - } else { - NativeShutdownGraphics(); - } + NativeShutdownGraphics(); + renderer_inited = false; graphicsContext->ThreadEnd(); From f0c651072771be64ba46318feddb1d9a82881786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 22 Dec 2022 10:05:21 +0100 Subject: [PATCH 2/6] Remove redundant variables --- android/jni/app-android.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index eea417e12b..46960c6f3b 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -181,9 +181,6 @@ static std::mutex renderLock; static int inputBoxSequence = 1; std::map> inputBoxCallbacks; -static float dp_xscale = 1.0f; -static float dp_yscale = 1.0f; - static bool sustainedPerfSupported = false; static std::string library_path; @@ -967,17 +964,11 @@ static void recalculateDpi() { dp_xres = display_xres * g_dpi_scale_x; dp_yres = display_yres * g_dpi_scale_y; - // Touch scaling is from display pixels to dp pixels. - // Wait, doesn't even make sense... this is equal to g_dpi_scale_x. TODO: Figure out what's going on! - dp_xscale = (float)dp_xres / (float)display_xres; - dp_yscale = (float)dp_yres / (float)display_yres; - pixel_in_dps_x = (float)pixel_xres / dp_xres; pixel_in_dps_y = (float)pixel_yres / dp_yres; INFO_LOG(G3D, "RecalcDPI: display_xres=%d display_yres=%d", display_xres, display_yres); INFO_LOG(G3D, "RecalcDPI: g_dpi=%f g_dpi_scale_x=%f g_dpi_scale_y=%f", g_dpi, g_dpi_scale_x, g_dpi_scale_y); - INFO_LOG(G3D, "RecalcDPI: dp_xscale=%f dp_yscale=%f", dp_xscale, dp_yscale); INFO_LOG(G3D, "RecalcDPI: dp_xres=%d dp_yres=%d", dp_xres, dp_yres); INFO_LOG(G3D, "RecalcDPI: pixel_xres=%d pixel_yres=%d", pixel_xres, pixel_yres); } @@ -1080,7 +1071,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env, } if (IsVREnabled()) { - UpdateVRInput(g_Config.bHapticFeedback, dp_xscale, dp_yscale); + UpdateVRInput(g_Config.bHapticFeedback, g_dpi_scale_x, g_dpi_scale_y); FinishVRRender(); } } @@ -1104,8 +1095,8 @@ PermissionStatus System_GetPermissionStatus(SystemPermission permission) { extern "C" jboolean JNICALL Java_org_ppsspp_ppsspp_NativeApp_touch (JNIEnv *, jclass, float x, float y, int code, int pointerId) { - float scaledX = x * dp_xscale; - float scaledY = y * dp_yscale; + float scaledX = x * g_dpi_scale_x; + float scaledY = y * g_dpi_scale_y; TouchInput touch; touch.id = pointerId; From afbf732d7eda69113184706641795abec624c9a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 22 Dec 2022 10:17:52 +0100 Subject: [PATCH 3/6] Delete even more dead code in app-android.cpp --- android/jni/app-android.cpp | 42 ++----------------- .../src/org/ppsspp/ppsspp/NativeActivity.java | 4 +- android/src/org/ppsspp/ppsspp/NativeApp.java | 2 +- 3 files changed, 5 insertions(+), 43 deletions(-) diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 46960c6f3b..a3668df455 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -132,13 +132,6 @@ std::string g_extFilesDir; // App private external dir. std::vector g_additionalStorageDirs; -static float left_joystick_x_async; -static float left_joystick_y_async; -static float right_joystick_x_async; -static float right_joystick_y_async; -static float hat_joystick_x_async; -static float hat_joystick_y_async; - static int optimalFramesPerBuffer = 0; static int optimalSampleRate = 0; static int sampleRate = 0; @@ -173,7 +166,7 @@ static jmethodID getDebugString; static jobject nativeActivity; -static volatile bool exitRenderLoop; +static std::atomic exitRenderLoop; static bool renderLoopRunning; static bool renderer_inited = false; static std::mutex renderLock; @@ -183,7 +176,6 @@ std::map> inputBoxCallbacks; static bool sustainedPerfSupported = false; -static std::string library_path; static std::map permissions; AndroidGraphicsContext *graphicsContext; @@ -287,7 +279,7 @@ static void EmuThreadFunc() { sleep_ms(20); } } else { - INFO_LOG(SYSTEM, "Runloop: Graphics context available! %p", graphicsContext); + INFO_LOG(SYSTEM, "Runloop: Graphics context available!"); } if (!NativeInitGraphics(graphicsContext)) { @@ -644,7 +636,7 @@ static void parse_args(std::vector &args, const std::string value) extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init (JNIEnv *env, jclass, jstring jmodel, jint jdeviceType, jstring jlangRegion, jstring japkpath, - jstring jdataDir, jstring jexternalStorageDir, jstring jexternalFilesDir, jstring jadditionalStorageDirs, jstring jlibraryDir, jstring jcacheDir, jstring jshortcutParam, + jstring jdataDir, jstring jexternalStorageDir, jstring jexternalFilesDir, jstring jadditionalStorageDirs, jstring jcacheDir, jstring jshortcutParam, jint jAndroidVersion, jstring jboard) { SetCurrentThreadName("androidInit"); @@ -659,13 +651,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init androidVersion = jAndroidVersion; deviceType = jdeviceType; - left_joystick_x_async = 0; - left_joystick_y_async = 0; - right_joystick_x_async = 0; - right_joystick_y_async = 0; - hat_joystick_x_async = 0; - hat_joystick_y_async = 0; - std::string apkPath = GetJavaString(env, japkpath); VFSRegister("", new ZipAssetReader(apkPath.c_str(), "assets/")); @@ -691,7 +676,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init std::string user_data_path = GetJavaString(env, jdataDir); if (user_data_path.size() > 0) user_data_path += "/"; - library_path = GetJavaString(env, jlibraryDir) + "/"; std::string shortcut_param = GetJavaString(env, jshortcutParam); std::string cacheDir = GetJavaString(env, jcacheDir); std::string buildBoard = GetJavaString(env, jboard); @@ -1136,26 +1120,6 @@ extern "C" jboolean Java_org_ppsspp_ppsspp_NativeApp_joystickAxis( JNIEnv *env, jclass, jint deviceId, jint axisId, jfloat value) { if (!renderer_inited) return false; - switch (axisId) { - case JOYSTICK_AXIS_X: - left_joystick_x_async = value; - break; - case JOYSTICK_AXIS_Y: - left_joystick_y_async = -value; - break; - case JOYSTICK_AXIS_Z: - right_joystick_x_async = value; - break; - case JOYSTICK_AXIS_RZ: - right_joystick_y_async = -value; - break; - case JOYSTICK_AXIS_HAT_X: - hat_joystick_x_async = value; - break; - case JOYSTICK_AXIS_HAT_Y: - hat_joystick_y_async = -value; - break; - } AxisInput axis; axis.axisId = axisId; diff --git a/android/src/org/ppsspp/ppsspp/NativeActivity.java b/android/src/org/ppsspp/ppsspp/NativeActivity.java index 07a80dae19..02dc8c32a7 100644 --- a/android/src/org/ppsspp/ppsspp/NativeActivity.java +++ b/android/src/org/ppsspp/ppsspp/NativeActivity.java @@ -399,8 +399,6 @@ public abstract class NativeActivity extends Activity { isXperiaPlay = IsXperiaPlay(); - String libraryDir = getApplicationLibraryDir(appInfo); - String extStorageState = Environment.getExternalStorageState(); String extStorageDir = Environment.getExternalStorageDirectory().getAbsolutePath(); File externalFiles = this.getExternalFilesDir(null); @@ -446,7 +444,7 @@ public abstract class NativeActivity extends Activity { overrideShortcutParam = null; NativeApp.audioConfig(optimalFramesPerBuffer, optimalSampleRate); - NativeApp.init(model, deviceType, languageRegion, apkFilePath, dataDir, extStorageDir, externalFilesDir, additionalStorageDirs, libraryDir, cacheDir, shortcut, Build.VERSION.SDK_INT, Build.BOARD); + NativeApp.init(model, deviceType, languageRegion, apkFilePath, dataDir, extStorageDir, externalFilesDir, additionalStorageDirs, cacheDir, shortcut, Build.VERSION.SDK_INT, Build.BOARD); // Allow C++ to tell us to use JavaGL or not. javaGL = "true".equalsIgnoreCase(NativeApp.queryConfig("androidJavaGL")); diff --git a/android/src/org/ppsspp/ppsspp/NativeApp.java b/android/src/org/ppsspp/ppsspp/NativeApp.java index 24a43f5b8e..8b3f709130 100644 --- a/android/src/org/ppsspp/ppsspp/NativeApp.java +++ b/android/src/org/ppsspp/ppsspp/NativeApp.java @@ -13,7 +13,7 @@ public class NativeApp { public static final int DEVICE_TYPE_DESKTOP = 2; public static final int DEVICE_TYPE_VR = 3; - public static native void init(String model, int deviceType, String languageRegion, String apkPath, String dataDir, String externalStorageDir, String extFilesDir, String additionalStorageDirs, String libraryDir, String cacheDir, String shortcutParam, int androidVersion, String board); + public static native void init(String model, int deviceType, String languageRegion, String apkPath, String dataDir, String externalStorageDir, String extFilesDir, String additionalStorageDirs, String cacheDir, String shortcutParam, int androidVersion, String board); public static native void audioInit(); public static native void audioShutdown(); public static native void audioConfig(int optimalFramesPerBuffer, int optimalSampleRate); From a3bbaeb31d7e20a812c1f66811df717242891b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 22 Dec 2022 10:35:18 +0100 Subject: [PATCH 4/6] Simplify some more code in app-android.cpp --- android/jni/app-android.cpp | 60 ++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index a3668df455..2bd7f8c236 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -860,15 +860,17 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) { VFSShutdown(); } - std::lock_guard guard(frameCommandLock); - while (frameCommands.size()) - frameCommands.pop(); + { + std::lock_guard guard(frameCommandLock); + while (frameCommands.size()) + frameCommands.pop(); + } INFO_LOG(SYSTEM, "NativeApp.shutdown() -- end"); } -// JavaEGL +// JavaEGL. This doesn't get called on the Vulkan path. extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { - + INFO_LOG(G3D, "NativeApp.displayInit()"); bool firstStart = !renderer_inited; // We should be running on the render thread here. @@ -929,6 +931,7 @@ extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, graphicsContext->ThreadStart(); renderer_inited = true; } + NativeMessageReceived("recreateviews", ""); if (IsVREnabled()) { @@ -1047,9 +1050,10 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env, return; if (useCPUThread) { - // This is the "GPU thread". - if (!graphicsContext || !graphicsContext->ThreadFrame()) + // This is the "GPU thread". Call ThreadFrame. + if (!graphicsContext || !graphicsContext->ThreadFrame()) { return; + } } else { UpdateRunLoopAndroid(env); } @@ -1374,41 +1378,26 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J ANativeWindow *wnd = _surf ? ANativeWindow_fromSurface(env, _surf) : nullptr; - WARN_LOG(G3D, "runEGLRenderLoop. display_xres=%d display_yres=%d", display_xres, display_yres); + WARN_LOG(G3D, "runEGLRenderLoop. display_xres=%d display_yres=%d desiredBackbufferSizeX=%d desiredBackbufferSizeY=%d", + display_xres, display_yres, desiredBackbufferSizeX, desiredBackbufferSizeY); - if (wnd == nullptr) { + if (!wnd) { ERROR_LOG(G3D, "Error: Surface is null."); renderLoopRunning = false; return false; } - auto tryInit = [&]() { - if (graphicsContext->InitFromRenderThread(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format, androidVersion)) { - return true; - } else { - ERROR_LOG(G3D, "Failed to initialize graphics context."); - System_Toast("Failed to initialize graphics context."); - return false; - } - }; + if (!graphicsContext->InitFromRenderThread(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format, androidVersion)) { + // On Android, if we get here, really no point in continuing. + // The UI is supposed to render on any device both on OpenGL and Vulkan. If either of those don't work + // on a device, we blacklist it. + ERROR_LOG(G3D, "Failed to initialize graphics context."); + System_Toast("Failed to initialize graphics context."); - bool initSuccess = tryInit(); - if (!initSuccess) { - if (!exitRenderLoop && g_Config.iGPUBackend == (int)GPUBackend::VULKAN) { - INFO_LOG(G3D, "Trying again, this time with OpenGL."); - SetGPUBackend(GPUBackend::OPENGL); - g_Config.iGPUBackend = (int)GetGPUBackend(); - - // If we were still supporting EGL for GL, we'd retry here: - //initSuccess = tryInit(); - } - - if (!initSuccess) { - delete graphicsContext; - graphicsContext = nullptr; - renderLoopRunning = false; - return false; - } + delete graphicsContext; + graphicsContext = nullptr; + renderLoopRunning = false; + return false; } if (!exitRenderLoop) { @@ -1446,6 +1435,7 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J INFO_LOG(G3D, "Shutting down graphics context from render thread..."); graphicsContext->ShutdownFromRenderThread(); renderLoopRunning = false; + WARN_LOG(G3D, "Render loop function exited."); return true; } From fe0f19fa31b88ae618d0301e1ea2b60f1820db4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 22 Dec 2022 10:35:34 +0100 Subject: [PATCH 5/6] Fix JNI leak in Android_GetInputDeviceDebugString, affecting TouchScreenTest --- android/jni/app-android.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 2bd7f8c236..61d9567157 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -506,16 +506,19 @@ std::string Android_GetInputDeviceDebugString() { return "(N/A)"; } auto env = getEnv(); - jstring param = env->NewStringUTF("InputDevice"); - jstring str = (jstring)env->CallObjectMethod(nativeActivity, getDebugString, param); - if (!str) { + jstring jparam = env->NewStringUTF("InputDevice"); + jstring jstr = (jstring)env->CallObjectMethod(nativeActivity, getDebugString, jparam); + if (!jstr) { + env->DeleteLocalRef(jparam); return "(N/A)"; } - const char *charArray = env->GetStringUTFChars(str, 0); + const char *charArray = env->GetStringUTFChars(jstr, 0); std::string retVal = charArray; - env->DeleteLocalRef(str); + env->ReleaseStringUTFChars(jstr, charArray); + env->DeleteLocalRef(jstr); + env->DeleteLocalRef(jparam); return retVal; } From db98ed9b7a3fe2d0c56ad5205d4276dffeb2e055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 22 Dec 2022 10:46:09 +0100 Subject: [PATCH 6/6] More simplification. --- android/jni/app-android.cpp | 49 +++++++++++++++---------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 61d9567157..c0ddad6ff9 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -265,6 +265,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *pjvm, void *reserved) { return JNI_VERSION_1_6; } +// Only used in OpenGL mode. static void EmuThreadFunc() { JNIEnv *env; gJvm->AttachCurrentThread(&env, nullptr); @@ -723,12 +724,15 @@ retry: useCPUThread = true; INFO_LOG(SYSTEM, "NativeApp.init() -- creating OpenGL context (JavaGL)"); graphicsContext = new AndroidJavaEGLGraphicsContext(); + INFO_LOG(SYSTEM, "NativeApp.init() - launching emu thread"); + EmuThreadStart(); break; case (int)GPUBackend::VULKAN: { INFO_LOG(SYSTEM, "NativeApp.init() -- creating Vulkan context"); - useCPUThread = false; // The Vulkan render manager manages its own thread. - // We create and destroy the Vulkan graphics context in the "EGL" thread. + useCPUThread = false; + // The Vulkan render manager manages its own thread. + // We create and destroy the Vulkan graphics context in the app main thread though. AndroidVulkanContext *ctx = new AndroidVulkanContext(); if (!ctx->InitAPI()) { INFO_LOG(SYSTEM, "Failed to initialize Vulkan, switching to OpenGL"); @@ -746,11 +750,6 @@ retry: goto retry; } - if (useCPUThread) { - INFO_LOG(SYSTEM, "NativeApp.init() - launching emu thread"); - EmuThreadStart(); - } - if (IsVREnabled()) { Version gitVer(PPSSPP_GIT_VERSION); InitVROnAndroid(gJvm, nativeActivity, systemName.c_str(), gitVer.ToInteger(), "PPSSPP"); @@ -873,6 +872,8 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) { // JavaEGL. This doesn't get called on the Vulkan path. extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, jobject obj) { + _assert_(useCPUThread); + INFO_LOG(G3D, "NativeApp.displayInit()"); bool firstStart = !renderer_inited; @@ -881,19 +882,16 @@ extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, if (renderer_inited) { // Would be really nice if we could get something on the GL thread immediately when shutting down. INFO_LOG(G3D, "NativeApp.displayInit() restoring"); - if (useCPUThread) { - EmuThreadStop("displayInit"); - graphicsContext->BeginAndroidShutdown(); - INFO_LOG(G3D, "BeginAndroidShutdown. Looping until emu thread done..."); - // Skipping GL calls here because the old context is lost. - while (graphicsContext->ThreadFrame()) { - continue; - } - INFO_LOG(G3D, "Joining emu thread"); - EmuThreadJoin(); - } else { - NativeShutdownGraphics(); + EmuThreadStop("displayInit"); + graphicsContext->BeginAndroidShutdown(); + INFO_LOG(G3D, "BeginAndroidShutdown. Looping until emu thread done..."); + // Skipping GL calls here because the old context is lost. + while (graphicsContext->ThreadFrame()) { + continue; } + INFO_LOG(G3D, "Joining emu thread"); + EmuThreadJoin(); + graphicsContext->ThreadEnd(); graphicsContext->ShutdownFromRenderThread(); @@ -908,17 +906,10 @@ extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, host->NotifyUserMessage(details, 5.0, 0xFFFFFFFF, "error_callback"); }, nullptr); - if (useCPUThread) { - EmuThreadStart(); - } else { - if (!NativeInitGraphics(graphicsContext)) { - // Gonna be in a weird state here, not good. - System_Toast("Failed to initialize graphics."); - return false; - } - } + EmuThreadStart(); graphicsContext->ThreadStart(); + INFO_LOG(G3D, "Restored."); } else { INFO_LOG(G3D, "NativeApp.displayInit() first time"); @@ -940,7 +931,6 @@ extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, if (IsVREnabled()) { EnterVR(firstStart, graphicsContext->GetAPIContext()); } - return true; } @@ -1034,6 +1024,7 @@ void UpdateRunLoopAndroid(JNIEnv *env) { std::lock_guard guard(frameCommandLock); if (!nativeActivity) { + ERROR_LOG(SYSTEM, "No activity, clearing commands"); while (!frameCommands.empty()) frameCommands.pop(); return;