diff --git a/android/jni/AndroidGraphicsContext.h b/android/jni/AndroidGraphicsContext.h index 0c6f963086..f9191aadbd 100644 --- a/android/jni/AndroidGraphicsContext.h +++ b/android/jni/AndroidGraphicsContext.h @@ -20,9 +20,6 @@ class AndroidGraphicsContext : public GraphicsContext { public: // This is different than the base class function since on // Android (EGL, Vulkan) we do have all this info on the render thread. - virtual bool InitFromRenderThread(ANativeWindow *wnd) = 0; + virtual bool Init(ANativeWindow *wnd) { return true; } virtual void BeginAndroidShutdown() {} - -private: - using GraphicsContext::InitFromRenderThread; }; diff --git a/android/jni/AndroidJavaGLContext.cpp b/android/jni/AndroidJavaGLContext.cpp index 69298c7cf0..a23ed5c666 100644 --- a/android/jni/AndroidJavaGLContext.cpp +++ b/android/jni/AndroidJavaGLContext.cpp @@ -10,9 +10,10 @@ AndroidJavaEGLGraphicsContext::AndroidJavaEGLGraphicsContext() { SetGPUBackend(GPUBackend::OPENGL); } -bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd) { +bool AndroidJavaEGLGraphicsContext::InitFromRenderThread(std::string *errorMessage) { INFO_LOG(Log::G3D, "AndroidJavaEGLGraphicsContext::InitFromRenderThread"); if (!CheckGLExtensions()) { + *errorMessage = "CheckExtensions failed"; ERROR_LOG(Log::G3D, "CheckGLExtensions failed - not gonna attempt starting up."); return false; } diff --git a/android/jni/AndroidJavaGLContext.h b/android/jni/AndroidJavaGLContext.h index ad0e67eff2..b24ed480e0 100644 --- a/android/jni/AndroidJavaGLContext.h +++ b/android/jni/AndroidJavaGLContext.h @@ -12,8 +12,7 @@ public: bool NeedsRenderThread() const override { return true; } // This performs the actual initialization, - bool InitFromRenderThread(ANativeWindow *wnd) override; - + bool InitFromRenderThread(std::string *errorMessage) override; void ShutdownFromRenderThread() override; void Shutdown() override {} diff --git a/android/jni/AndroidVulkanContext.cpp b/android/jni/AndroidVulkanContext.cpp index 9036cc1a44..957c32d751 100644 --- a/android/jni/AndroidVulkanContext.cpp +++ b/android/jni/AndroidVulkanContext.cpp @@ -55,7 +55,7 @@ bool AndroidVulkanContext::InitAPI() { return true; } -bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd) { +bool AndroidVulkanContext::Init(ANativeWindow *wnd) { INFO_LOG(Log::G3D, "AndroidVulkanContext::InitFromRenderThread"); if (!g_Vulkan) { ERROR_LOG(Log::G3D, "AndroidVulkanContext::InitFromRenderThread: No Vulkan context"); @@ -101,7 +101,7 @@ bool AndroidVulkanContext::InitFromRenderThread(ANativeWindow *wnd) { } void AndroidVulkanContext::ShutdownFromRenderThread() { - INFO_LOG(Log::G3D, "AndroidVulkanContext::Shutdown"); + INFO_LOG(Log::G3D, "AndroidVulkanContext::ShutdownFromRenderThread"); draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, g_Vulkan->GetBackbufferWidth(), g_Vulkan->GetBackbufferHeight()); delete draw_; draw_ = nullptr; @@ -113,7 +113,7 @@ void AndroidVulkanContext::ShutdownFromRenderThread() { } void AndroidVulkanContext::Shutdown() { - INFO_LOG(Log::G3D, "Calling NativeShutdownGraphics"); + INFO_LOG(Log::G3D, "AndroidVulkanContext::Shutdown"); g_Vulkan->DestroyDevice(); g_Vulkan->DestroyInstance(); // We keep the g_Vulkan context around to avoid invalidating a ton of pointers around the app. @@ -128,6 +128,9 @@ void AndroidVulkanContext::Resize() { // TODO: We should only destroy the surface here if the window changed. We can track this inside g_Vulkan. g_Vulkan->DestroySurface(); + + // ========================================== + g_Vulkan->ReinitSurface(); VkPresentModeKHR presentMode = ConfigPresentModeToVulkan(draw_); diff --git a/android/jni/AndroidVulkanContext.h b/android/jni/AndroidVulkanContext.h index bcdf070fe2..f83daf9fa7 100644 --- a/android/jni/AndroidVulkanContext.h +++ b/android/jni/AndroidVulkanContext.h @@ -11,7 +11,7 @@ public: bool InitAPI(); - bool InitFromRenderThread(ANativeWindow *wnd) override; + bool Init(ANativeWindow *wnd) override; void ShutdownFromRenderThread() override; // Inverses InitFromRenderThread. void Shutdown() override; diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 8572866bc2..83489d4fac 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -1034,7 +1034,7 @@ extern "C" jboolean Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * e std::string errorMessage; if (!renderer_inited) { INFO_LOG(Log::G3D, "NativeApp.displayInit() first time"); - if (!graphicsContext->InitFromRenderThread((ANativeWindow *)nullptr)) { + if (!graphicsContext->InitFromRenderThread(&errorMessage)) { System_Toast("Graphics initialization failed. Quitting."); return false; } @@ -1068,8 +1068,9 @@ extern "C" jboolean Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * e INFO_LOG(Log::G3D, "Shut down both threads. Now let's bring it up again!"); - if (!graphicsContext->InitFromRenderThread((ANativeWindow *)nullptr)) { - System_Toast("Graphics initialization failed. Quitting."); + std::string errorMessage; + if (!graphicsContext->InitFromRenderThread(&errorMessage)) { + System_Toast(("Graphics initialization failed: Quitting: " + errorMessage).c_str()); return false; } @@ -1232,7 +1233,8 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_sendRequestResult(JNIEn } // This doesn't get called on the Vulkan path. -// We don't need a render thread "loop" as this gets called repeatedly by the system. +// We don't need a render thread "loop" as this gets called repeatedly by the system, by a system +// render thread. extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env, jobject obj) { static bool hasSetThreadName = false; if (!hasSetThreadName) { @@ -1240,15 +1242,21 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env, SetCurrentThreadName("AndroidRender"); } - if (IsVREnabled() && !StartVRRender()) + if (IsVREnabled() && !StartVRRender()) { return; + } // This is the "GPU thread". Call ThreadFrame. - if (!graphicsContext || !graphicsContext->ThreadFrame(true)) { + if (!graphicsContext) { return; } _assert_(graphicsContext->NeedsRenderThread()); + if (!graphicsContext->ThreadFrame(true)) { + INFO_LOG(Log::G3D, "ThreadFrame returned false"); + return; + } + if (IsVREnabled()) { UpdateVRInput(g_Config.bHapticFeedback, g_display.dpi_scale_x, g_display.dpi_scale_y); FinishVRRender(); @@ -1769,7 +1777,7 @@ static void VulkanEmuThread(ANativeWindow *wnd) { WARN_LOG(Log::G3D, "runVulkanRenderLoop. display_xres=%d display_yres=%d desiredBackbufferSizeX=%d desiredBackbufferSizeY=%d", display_xres, display_yres, desiredBackbufferSizeX, desiredBackbufferSizeY); - if (!graphicsContext->InitFromRenderThread(wnd)) { + if (!graphicsContext->Init(wnd)) { // 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. Hopefully we should have already failed in InitAPI anyway and reverted to GL back then.