diff --git a/src/android/app/src/main/jni/emu_window/emu_window.cpp b/src/android/app/src/main/jni/emu_window/emu_window.cpp index 5a9e7ba53..5e53a9282 100644 --- a/src/android/app/src/main/jni/emu_window/emu_window.cpp +++ b/src/android/app/src/main/jni/emu_window/emu_window.cpp @@ -35,6 +35,7 @@ void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { window_info.render_surface = surface; StopPresenting(); + OnFramebufferSizeChanged(); } bool EmuWindow_Android::OnTouchEvent(int x, int y, bool pressed) { diff --git a/src/video_core/renderer_vulkan/vk_present_window.cpp b/src/video_core/renderer_vulkan/vk_present_window.cpp index 261dcdb4a..82111d0b0 100644 --- a/src/video_core/renderer_vulkan/vk_present_window.cpp +++ b/src/video_core/renderer_vulkan/vk_present_window.cpp @@ -100,8 +100,8 @@ PresentWindow::PresentWindow(Frontend::EmuWindow& emu_window_, const Instance& i Scheduler& scheduler_) : emu_window{emu_window_}, instance{instance_}, scheduler{scheduler_}, surface{CreateSurface(instance.GetInstance(), emu_window)}, - swapchain{instance, emu_window.GetFramebufferLayout().width, - emu_window.GetFramebufferLayout().height, surface}, + next_surface{surface}, swapchain{instance, emu_window.GetFramebufferLayout().width, + emu_window.GetFramebufferLayout().height, surface}, graphics_queue{instance.GetGraphicsQueue()}, present_renderpass{CreateRenderpass()}, vsync_enabled{Settings::values.use_vsync_new.GetValue()}, blit_supported{ @@ -328,32 +328,26 @@ void PresentWindow::PresentThread(std::stop_token token) { void PresentWindow::NotifySurfaceChanged() { #ifdef ANDROID std::scoped_lock lock{recreate_surface_mutex}; + next_surface = CreateSurface(instance.GetInstance(), emu_window); recreate_surface_cv.notify_one(); #endif } void PresentWindow::CopyToSwapchain(Frame* frame) { const auto recreate_swapchain = [&] { +#ifdef ANDROID + { + std::unique_lock lock{recreate_surface_mutex}; + recreate_surface_cv.wait(lock, [this]() { return surface != next_surface; }); + surface = next_surface; + } +#endif std::scoped_lock submit_lock{scheduler.submit_mutex}; graphics_queue.waitIdle(); swapchain.Create(frame->width, frame->height, surface); }; -#ifdef ANDROID - std::unique_lock lock{recreate_surface_mutex}; - - recreate_surface_cv.wait_for(lock, std::chrono::milliseconds(400), [&]() { - return last_render_surface == emu_window.GetWindowInfo().render_surface; - }); - - // If the frontend recreated the surface, recreate the renderer surface and swapchain. - void* const render_surface = emu_window.GetWindowInfo().render_surface; - if (last_render_surface != render_surface) { - last_render_surface = render_surface; - surface = CreateSurface(instance.GetInstance(), emu_window); - recreate_swapchain(); - } -#else +#ifndef ANDROID const bool use_vsync = Settings::values.use_vsync_new.GetValue(); const bool size_changed = swapchain.GetWidth() != frame->width || swapchain.GetHeight() != frame->height; diff --git a/src/video_core/renderer_vulkan/vk_present_window.h b/src/video_core/renderer_vulkan/vk_present_window.h index e55b0e757..f5e9844e7 100644 --- a/src/video_core/renderer_vulkan/vk_present_window.h +++ b/src/video_core/renderer_vulkan/vk_present_window.h @@ -75,6 +75,7 @@ private: const Instance& instance; Scheduler& scheduler; vk::SurfaceKHR surface; + vk::SurfaceKHR next_surface{}; Swapchain swapchain; vk::CommandPool command_pool; vk::Queue graphics_queue; diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 1e4f34fa5..285e98fc1 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -88,6 +88,7 @@ bool Swapchain::AcquireNextImage() { case vk::Result::eSuccess: break; case vk::Result::eSuboptimalKHR: + case vk::Result::eErrorSurfaceLostKHR: case vk::Result::eErrorOutOfDateKHR: needs_recreation = true; break;