summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/app/src/main/jni/native.cpp1
-rw-r--r--src/video_core/renderer_base.h3
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_present_manager.cpp24
-rw-r--r--src/video_core/renderer_vulkan/vk_present_manager.h5
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
92protected: 95protected:
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
57private: 61private:
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
294void PresentManager::NotifySurfaceChanged() {
295#ifdef ANDROID
296 std::scoped_lock lock{recreate_surface_mutex};
297 recreate_surface_cv.notify_one();
298#endif
299}
300
294void PresentManager::CopyToSwapchain(Frame* frame) { 301void 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
58private: 61private:
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;