diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 7e3da54b25..5e12fffa57 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -747,35 +747,21 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceChang if (surf == nullptr) __android_log_print(ANDROID_LOG_ERROR, DOLPHIN_TAG, "Error: Surface is null."); - // If GLInterface isn't a thing yet then we don't need to let it know that the - // surface has changed - if (GLInterface) - { - GLInterface->UpdateHandle(surf); - Renderer::s_ChangedSurface.Reset(); - Renderer::s_SurfaceNeedsChanged.Set(); - Renderer::s_ChangedSurface.Wait(); - } + if (g_renderer) + g_renderer->ChangeSurface(surf); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestroyed(JNIEnv* env, jobject obj) { + if (g_renderer) + g_renderer->ChangeSurface(nullptr); + if (surf) { ANativeWindow_release(surf); surf = nullptr; } - - // If GLInterface isn't a thing yet then we don't need to let it know that the - // surface has changed - if (GLInterface) - { - GLInterface->UpdateHandle(nullptr); - Renderer::s_ChangedSurface.Reset(); - Renderer::s_SurfaceNeedsChanged.Set(); - Renderer::s_ChangedSurface.Wait(); - } } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_RefreshWiimotes(JNIEnv* env, jobject obj) diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index 55e31075d6..2b690c0e5a 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -77,6 +77,7 @@ #include "InputCommon/ControllerInterface/ControllerInterface.h" +#include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoBackendBase.h" #include "VideoCommon/VideoConfig.h" @@ -907,6 +908,12 @@ void CFrame::OnRenderParentResize(wxSizeEvent& event) } m_LogWindow->Refresh(); m_LogWindow->Update(); + + // We call Renderer::ChangeSurface here to indicate the size has changed, + // but pass the same window handle. This is needed for the Vulkan backend, + // otherwise it cannot tell that the window has been resized on some drivers. + if (g_renderer) + g_renderer->ChangeSurface(GetRenderHandle()); } event.Skip(); } diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 3fb9ebb755..c1e8165b9b 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1620,12 +1620,16 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, OSD::DoCallbacks(OSD::CallbackType::OnFrame); OSD::DrawMessages(); - if (s_SurfaceNeedsChanged.IsSet()) +#ifdef ANDROID + if (s_surface_needs_change.IsSet()) { + GLInterface->UpdateHandle(s_new_surface_handle); GLInterface->UpdateSurface(); - s_SurfaceNeedsChanged.Clear(); - s_ChangedSurface.Set(); + s_new_surface_handle = nullptr; + s_surface_needs_change.Clear(); + s_surface_changed.Set(); } +#endif // Copy the rendered frame to the real window GLInterface->Swap(); @@ -1814,4 +1818,16 @@ int Renderer::GetMaxTextureSize() glGetIntegerv(GL_MAX_TEXTURE_SIZE, &s_max_texture_size); return s_max_texture_size; } + +void Renderer::ChangeSurface(void* new_surface_handle) +{ +// Win32 polls the window size when redrawing, X11 runs an event loop in another thread. +// This is only necessary for Android at this point, although handling resizes here +// would be more efficient than polling. +#ifdef ANDROID + s_new_surface_handle = new_surface_handle; + s_surface_needs_change.Set(); + s_surface_changed.Wait(); +#endif +} } diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index c240a936d3..57611f6856 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -105,6 +105,8 @@ public: int GetMaxTextureSize() override; + void ChangeSurface(void* new_surface_handle) override; + private: void UpdateEFBCache(EFBAccessType type, u32 cacheRectIdx, const EFBRectangle& efbPixelRc, const TargetRectangle& targetPixelRc, const void* data); diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 3b50cd2313..8fb77a341f 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -60,10 +60,6 @@ Common::Event Renderer::s_screenshotCompleted; volatile bool Renderer::s_bScreenshot; -// Final surface changing -Common::Flag Renderer::s_SurfaceNeedsChanged; -Common::Event Renderer::s_ChangedSurface; - // The framebuffer size int Renderer::s_target_width; int Renderer::s_target_height; @@ -74,6 +70,11 @@ int Renderer::s_backbuffer_height; std::unique_ptr Renderer::m_post_processor; +// Final surface changing +Common::Flag Renderer::s_surface_needs_change; +Common::Event Renderer::s_surface_changed; +void* Renderer::s_new_surface_handle; + TargetRectangle Renderer::target_rc; int Renderer::s_last_efb_scale; diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 1ae3121637..44a0b982b7 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -138,9 +138,8 @@ public: static Common::Event s_screenshotCompleted; // Final surface changing - static Common::Flag s_SurfaceNeedsChanged; - static Common::Event s_ChangedSurface; - + // This is called when the surface is resized (WX) or the window changes (Android). + virtual void ChangeSurface(void* new_surface_handle) {} protected: static void CalculateTargetScale(int x, int y, int* scaledX, int* scaledY); bool CalculateTargetSize(unsigned int framebuffer_width, unsigned int framebuffer_height); @@ -178,6 +177,10 @@ protected: static const float GX_MAX_DEPTH; + static Common::Flag s_surface_needs_change; + static Common::Event s_surface_changed; + static void* s_new_surface_handle; + private: static PEControl::PixelFormat prev_efb_format; static unsigned int efb_scale_numeratorX;