diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/android/app/src/main/jni/native.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_base.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_present_manager.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_present_manager.h | 5 |
5 files changed, 36 insertions, 1 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index d503ef61d..b87e04b3d 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
| @@ -148,6 +148,7 @@ public: | |||
| 148 | return; | 148 | return; |
| 149 | } | 149 | } |
| 150 | m_window->OnSurfaceChanged(m_native_window); | 150 | m_window->OnSurfaceChanged(m_native_window); |
| 151 | m_system.Renderer().NotifySurfaceChanged(); | ||
| 151 | } | 152 | } |
| 152 | 153 | ||
| 153 | Core::SystemResultStatus InitializeEmulation(const std::string& filepath) { | 154 | Core::SystemResultStatus InitializeEmulation(const std::string& filepath) { |
diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 78ea5208b..3e12a8813 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h | |||
| @@ -89,6 +89,9 @@ public: | |||
| 89 | void RequestScreenshot(void* data, std::function<void(bool)> callback, | 89 | void RequestScreenshot(void* data, std::function<void(bool)> callback, |
| 90 | const Layout::FramebufferLayout& layout); | 90 | const Layout::FramebufferLayout& layout); |
| 91 | 91 | ||
| 92 | /// This is called to notify the rendering backend of a surface change | ||
| 93 | virtual void NotifySurfaceChanged() {} | ||
| 94 | |||
| 92 | protected: | 95 | protected: |
| 93 | Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle. | 96 | Core::Frontend::EmuWindow& render_window; ///< Reference to the render window handle. |
| 94 | std::unique_ptr<Core::Frontend::GraphicsContext> context; | 97 | std::unique_ptr<Core::Frontend::GraphicsContext> context; |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 3c63a2004..b2e8cbd1b 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -54,6 +54,10 @@ public: | |||
| 54 | return device.GetDriverName(); | 54 | return device.GetDriverName(); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | void NotifySurfaceChanged() override { | ||
| 58 | present_manager.NotifySurfaceChanged(); | ||
| 59 | } | ||
| 60 | |||
| 57 | private: | 61 | private: |
| 58 | void Report() const; | 62 | void Report() const; |
| 59 | 63 | ||
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index 77832720d..dc42982e9 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp | |||
| @@ -291,6 +291,13 @@ void PresentManager::PresentThread(std::stop_token token) { | |||
| 291 | } | 291 | } |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | void PresentManager::NotifySurfaceChanged() { | ||
| 295 | #ifdef ANDROID | ||
| 296 | std::scoped_lock lock{recreate_surface_mutex}; | ||
| 297 | recreate_surface_cv.notify_one(); | ||
| 298 | #endif | ||
| 299 | } | ||
| 300 | |||
| 294 | void PresentManager::CopyToSwapchain(Frame* frame) { | 301 | void PresentManager::CopyToSwapchain(Frame* frame) { |
| 295 | MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain); | 302 | MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain); |
| 296 | 303 | ||
| @@ -299,7 +306,22 @@ void PresentManager::CopyToSwapchain(Frame* frame) { | |||
| 299 | image_count = swapchain.GetImageCount(); | 306 | image_count = swapchain.GetImageCount(); |
| 300 | }; | 307 | }; |
| 301 | 308 | ||
| 309 | const auto needs_recreation = [&] { | ||
| 310 | if (last_render_surface != render_window.GetWindowInfo().render_surface) { | ||
| 311 | return true; | ||
| 312 | } | ||
| 313 | if (swapchain.NeedsRecreation(frame->is_srgb)) { | ||
| 314 | return true; | ||
| 315 | } | ||
| 316 | return false; | ||
| 317 | }; | ||
| 318 | |||
| 302 | #ifdef ANDROID | 319 | #ifdef ANDROID |
| 320 | std::unique_lock lock{recreate_surface_mutex}; | ||
| 321 | |||
| 322 | recreate_surface_cv.wait_for(lock, std::chrono::milliseconds(400), | ||
| 323 | [&]() { return !needs_recreation(); }); | ||
| 324 | |||
| 303 | // If the frontend recreated the surface, recreate the renderer surface and swapchain. | 325 | // If the frontend recreated the surface, recreate the renderer surface and swapchain. |
| 304 | if (last_render_surface != render_window.GetWindowInfo().render_surface) { | 326 | if (last_render_surface != render_window.GetWindowInfo().render_surface) { |
| 305 | last_render_surface = render_window.GetWindowInfo().render_surface; | 327 | last_render_surface = render_window.GetWindowInfo().render_surface; |
| @@ -450,7 +472,7 @@ void PresentManager::CopyToSwapchain(Frame* frame) { | |||
| 450 | 472 | ||
| 451 | // Submit the image copy/blit to the swapchain | 473 | // Submit the image copy/blit to the swapchain |
| 452 | { | 474 | { |
| 453 | std::scoped_lock lock{scheduler.submit_mutex}; | 475 | std::scoped_lock submit_lock{scheduler.submit_mutex}; |
| 454 | switch (const VkResult result = | 476 | switch (const VkResult result = |
| 455 | device.GetGraphicsQueue().Submit(submit_info, *frame->present_done)) { | 477 | device.GetGraphicsQueue().Submit(submit_info, *frame->present_done)) { |
| 456 | case VK_SUCCESS: | 478 | case VK_SUCCESS: |
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.h b/src/video_core/renderer_vulkan/vk_present_manager.h index 3cbfce4ed..4ac2e2395 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.h +++ b/src/video_core/renderer_vulkan/vk_present_manager.h | |||
| @@ -55,6 +55,9 @@ public: | |||
| 55 | /// Waits for the present thread to finish presenting all queued frames. | 55 | /// Waits for the present thread to finish presenting all queued frames. |
| 56 | void WaitPresent(); | 56 | void WaitPresent(); |
| 57 | 57 | ||
| 58 | /// This is called to notify the rendering backend of a surface change | ||
| 59 | void NotifySurfaceChanged(); | ||
| 60 | |||
| 58 | private: | 61 | private: |
| 59 | void PresentThread(std::stop_token token); | 62 | void PresentThread(std::stop_token token); |
| 60 | 63 | ||
| @@ -74,7 +77,9 @@ private: | |||
| 74 | std::queue<Frame*> free_queue; | 77 | std::queue<Frame*> free_queue; |
| 75 | std::condition_variable_any frame_cv; | 78 | std::condition_variable_any frame_cv; |
| 76 | std::condition_variable free_cv; | 79 | std::condition_variable free_cv; |
| 80 | std::condition_variable recreate_surface_cv; | ||
| 77 | std::mutex swapchain_mutex; | 81 | std::mutex swapchain_mutex; |
| 82 | std::mutex recreate_surface_mutex; | ||
| 78 | std::mutex queue_mutex; | 83 | std::mutex queue_mutex; |
| 79 | std::mutex free_mutex; | 84 | std::mutex free_mutex; |
| 80 | std::jthread present_thread; | 85 | std::jthread present_thread; |