From cd40bc8c612d4e483f661fc5cdc10ed0fddd166a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 24 Feb 2020 19:30:42 +0300 Subject: [PATCH] overlays: Avoid race condition between rendering and layout operations for system widgets - System widgets are callable from outside RSX code. - Responding to draw requests while setup is in progress can cause malformed cached output - Fixes glitched layouts for system message dialogs --- rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp | 8 ++++++++ rpcs3/Emu/RSX/Overlays/overlay_osk.cpp | 6 +++--- rpcs3/Emu/RSX/Overlays/overlay_perf_metrics.cpp | 3 +++ rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp | 8 ++++++++ .../RSX/Overlays/overlay_shader_compile_notification.cpp | 6 ++++++ rpcs3/Emu/RSX/Overlays/overlay_trophy_notification.cpp | 4 +++- rpcs3/Emu/RSX/Overlays/overlays.h | 2 +- 7 files changed, 32 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp b/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp index 8556cd544c..5fddbffc2b 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp @@ -75,6 +75,11 @@ namespace rsx compiled_resource message_dialog::get_compiled() { + if (!visible) + { + return {}; + } + compiled_resource result; if (background_image && background_image->data) @@ -158,6 +163,8 @@ namespace rsx error_code message_dialog::show(bool is_blocking, const std::string& text, const MsgDialogType& type, std::function on_close) { + visible = false; + num_progress_bars = type.progress_bar_count; if (num_progress_bars) { @@ -207,6 +214,7 @@ namespace rsx } this->on_close = std::move(on_close); + visible = true; if (is_blocking) { diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp index cd40bdc641..223ada7633 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp @@ -22,7 +22,7 @@ namespace rsx }); } - m_visible = false; + visible = false; close(); }; @@ -178,8 +178,8 @@ namespace rsx m_btn_cancel.set_image_resource(resource_config::standard_image_resource::circle); } - m_visible = true; m_update = true; + visible = true; exit = false; fade_animation.current = color4f(0.f); @@ -495,7 +495,7 @@ namespace rsx compiled_resource osk_dialog::get_compiled() { - if (!m_visible) + if (!visible) { return {}; } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_perf_metrics.cpp b/rpcs3/Emu/RSX/Overlays/overlay_perf_metrics.cpp index ba189f74a9..3d19b136e8 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_perf_metrics.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_perf_metrics.cpp @@ -205,6 +205,7 @@ namespace rsx update(); m_is_initialised = true; + visible = true; } void perf_metrics_overlay::set_framerate_graph_enabled(bool enabled) @@ -700,6 +701,8 @@ namespace rsx perf_overlay = manager->create(); } + std::scoped_lock lock(*manager); + perf_overlay->set_detail_level(perf_settings.level); perf_overlay->set_position(perf_settings.position); perf_overlay->set_update_interval(perf_settings.update_interval); diff --git a/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp b/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp index 639ee4a388..3af644aeec 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_save_dialog.cpp @@ -143,6 +143,11 @@ namespace rsx compiled_resource save_dialog::get_compiled() { + if (!visible) + { + return {}; + } + compiled_resource result; result.add(m_dim_background->get_compiled()); result.add(m_list->get_compiled()); @@ -157,6 +162,8 @@ namespace rsx s32 save_dialog::show(std::vector& save_entries, u32 focused, u32 op, vm::ptr listSet) { + visible = false; + std::vector icon; std::vector> entries; @@ -248,6 +255,7 @@ namespace rsx } static_cast(m_description.get())->auto_resize(); + visible = true; if (auto err = run_input_loop()) return err; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_shader_compile_notification.cpp b/rpcs3/Emu/RSX/Overlays/overlay_shader_compile_notification.cpp index 282c91bbdf..a78aaf7a37 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_shader_compile_notification.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_shader_compile_notification.cpp @@ -30,6 +30,7 @@ namespace rsx // Disable forced refresh unless fps dips below 4 min_refresh_duration_us = 250000; + visible = true; } void shader_compile_notification::update_animation(u64 t) @@ -81,6 +82,11 @@ namespace rsx compiled_resource shader_compile_notification::get_compiled() { + if (!visible) + { + return {}; + } + auto compiled = m_text.get_compiled(); compiled.add(dots[0].get_compiled()); compiled.add(dots[1].get_compiled()); diff --git a/rpcs3/Emu/RSX/Overlays/overlay_trophy_notification.cpp b/rpcs3/Emu/RSX/Overlays/overlay_trophy_notification.cpp index 60e4c0f0ac..3718b4e419 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_trophy_notification.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_trophy_notification.cpp @@ -93,7 +93,7 @@ namespace rsx compiled_resource trophy_notification::get_compiled() { - if (!creation_time) + if (!creation_time || !visible) { return {}; } @@ -110,6 +110,7 @@ namespace rsx { // Schedule to display this trophy display_sched_id = s_trophy_semaphore.enqueue(); + visible = false; if (!trophy_icon_buffer.empty()) { @@ -135,6 +136,7 @@ namespace rsx u16 margin_sz = text_view.x - image.w - image.x; frame.w = text_view.x + text_view.w + margin_sz; + visible = true; return CELL_OK; } } // namespace overlays diff --git a/rpcs3/Emu/RSX/Overlays/overlays.h b/rpcs3/Emu/RSX/Overlays/overlays.h index 6cedb34637..a5cc48cc09 100644 --- a/rpcs3/Emu/RSX/Overlays/overlays.h +++ b/rpcs3/Emu/RSX/Overlays/overlays.h @@ -34,6 +34,7 @@ namespace rsx u16 virtual_height = 720; u32 min_refresh_duration_us = 16600; + atomic_t visible = false; virtual ~overlay() = default; @@ -399,7 +400,6 @@ namespace rsx // Fade in/out animation_color_interpolate fade_animation; - bool m_visible = false; bool m_update = true; compiled_resource m_cached_resource;