From ba15a76d7bbd9b0e39565b36a59e9182baeabce8 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 2 Jan 2025 21:33:53 +1000 Subject: [PATCH] ImGuiManager: Pack state in struct --- src/util/imgui_manager.cpp | 433 +++++++++++++++++++------------------ 1 file changed, 224 insertions(+), 209 deletions(-) diff --git a/src/util/imgui_manager.cpp b/src/util/imgui_manager.cpp index ce62d2c0a3..ab4224b651 100644 --- a/src/util/imgui_manager.cpp +++ b/src/util/imgui_manager.cpp @@ -89,61 +89,71 @@ static void UpdateSoftwareCursorTexture(u32 index); static void DestroySoftwareCursorTextures(); static void DrawSoftwareCursor(const SoftwareCursor& sc, const std::pair& pos); -static float s_global_prescale = 0.0f; // before window scale -static float s_global_scale = 0.0f; -static float s_screen_margin = 0.0f; +static constexpr float OSD_FADE_IN_TIME = 0.1f; +static constexpr float OSD_FADE_OUT_TIME = 0.4f; static constexpr std::array s_ascii_font_range = {{0x20, 0x7F, 0x00, 0x00}}; -static std::string s_font_path; -static std::vector s_font_range; -static std::vector s_emoji_range; +namespace { -static ImGuiContext* s_imgui_context; -static ImFont* s_debug_font; -static ImFont* s_osd_font; -static ImFont* s_fixed_font; -static ImFont* s_medium_font; -static ImFont* s_large_font; +struct ALIGN_TO_CACHE_LINE State +{ + float global_prescale = 0.0f; // before window scale + float global_scale = 0.0f; + float screen_margin = 0.0f; -static DynamicHeapArray s_standard_font_data; -static DynamicHeapArray s_fixed_font_data; -static DynamicHeapArray s_icon_fa_font_data; -static DynamicHeapArray s_icon_pf_font_data; -static DynamicHeapArray s_emoji_font_data; + std::string font_path; + std::vector font_range; + std::vector emoji_range; -static float s_window_width; -static float s_window_height; -static Timer s_last_render_time; + ImGuiContext* imgui_context; + ImFont* debug_font; + ImFont* osd_font; + ImFont* fixed_font; + ImFont* medium_font; + ImFont* large_font; -// cached copies of WantCaptureKeyboard/Mouse, used to know when to dispatch events -static std::atomic_bool s_imgui_wants_keyboard{false}; -static std::atomic_bool s_imgui_wants_mouse{false}; -static std::atomic_bool s_imgui_wants_text{false}; + DynamicHeapArray standard_font_data; + DynamicHeapArray fixed_font_data; + DynamicHeapArray icon_fa_font_data; + DynamicHeapArray icon_pf_font_data; + DynamicHeapArray emoji_font_data; -// mapping of host key -> imgui key -static std::unordered_map s_imgui_key_map; + float window_width; + float window_height; + Timer::Value last_render_time; -static constexpr float OSD_FADE_IN_TIME = 0.1f; -static constexpr float OSD_FADE_OUT_TIME = 0.4f; + // cached copies of WantCaptureKeyboard/Mouse, used to know when to dispatch events + std::atomic_bool imgui_wants_keyboard{false}; + std::atomic_bool imgui_wants_mouse{false}; + std::atomic_bool imgui_wants_text{false}; + + // mapping of host key -> imgui key + std::unordered_map imgui_key_map; + + std::deque osd_active_messages; + std::deque osd_posted_messages; + std::mutex osd_messages_lock; + bool show_osd_messages = true; + bool scale_changed = false; + + std::array software_cursors = {}; +}; + +} // namespace -static std::deque s_osd_active_messages; -static std::deque s_osd_posted_messages; -static std::mutex s_osd_messages_lock; -static bool s_show_osd_messages = true; -static bool s_scale_changed = false; +static State s_state; -static std::array s_software_cursors = {}; } // namespace ImGuiManager void ImGuiManager::SetFontPathAndRange(std::string path, std::vector range) { - if (s_font_path == path && s_font_range == range) + if (s_state.font_path == path && s_state.font_range == range) return; - s_font_path = std::move(path); - s_font_range = std::move(range); - s_standard_font_data = {}; + s_state.font_path = std::move(path); + s_state.font_range = std::move(range); + s_state.standard_font_data = {}; ReloadFontDataIfActive(); } @@ -154,23 +164,23 @@ void ImGuiManager::SetEmojiFontRange(std::vector range) if (runtime_size == 0) { - if (s_emoji_range.empty()) + if (s_state.emoji_range.empty()) return; - s_emoji_range = {}; + s_state.emoji_range = {}; } else { - if (!s_emoji_range.empty() && (s_emoji_range.size() - builtin_size) == range.size() && - std::memcmp(s_emoji_range.data(), range.data(), range.size() * sizeof(ImWchar)) == 0) + if (!s_state.emoji_range.empty() && (s_state.emoji_range.size() - builtin_size) == range.size() && + std::memcmp(s_state.emoji_range.data(), range.data(), range.size() * sizeof(ImWchar)) == 0) { // no change return; } - s_emoji_range = std::move(range); - s_emoji_range.resize(s_emoji_range.size() + builtin_size); - std::memcpy(&s_emoji_range[runtime_size], EMOJI_ICON_RANGE, sizeof(EMOJI_ICON_RANGE)); + s_state.emoji_range = std::move(range); + s_state.emoji_range.resize(s_state.emoji_range.size() + builtin_size); + std::memcpy(&s_state.emoji_range[runtime_size], EMOJI_ICON_RANGE, sizeof(EMOJI_ICON_RANGE)); } ReloadFontDataIfActive(); @@ -210,24 +220,24 @@ std::vector ImGuiManager::CompactFontRange(std::spanHasMainSwapChain() ? g_gpu_device->GetMainSwapChain()->GetScale() : 1.0f) * global_scale, 1.0f); - s_screen_margin = std::max(screen_margin, 0.0f); - s_scale_changed = false; + s_state.screen_margin = std::max(screen_margin, 0.0f); + s_state.scale_changed = false; - s_imgui_context = ImGui::CreateContext(); + s_state.imgui_context = ImGui::CreateContext(); - ImGuiIO& io = s_imgui_context->IO; + ImGuiIO& io = s_state.imgui_context->IO; io.IniFilename = nullptr; io.BackendFlags |= ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_RendererHasVtxOffset; #ifndef __ANDROID__ @@ -260,15 +270,16 @@ bool ImGuiManager::Initialize(float global_scale, float screen_margin, Error* er #endif SetCommonIOOptions(io); - s_window_width = + s_state.last_render_time = Timer::GetCurrentValue(); + s_state.window_width = g_gpu_device->HasMainSwapChain() ? static_cast(g_gpu_device->GetMainSwapChain()->GetWidth()) : 0.0f; - s_window_height = + s_state.window_height = g_gpu_device->HasMainSwapChain() ? static_cast(g_gpu_device->GetMainSwapChain()->GetHeight()) : 0.0f; io.DisplayFramebufferScale = ImVec2(1, 1); // We already scale things ourselves, this would double-apply scaling - io.DisplaySize = ImVec2(s_window_width, s_window_height); + io.DisplaySize = ImVec2(s_state.window_width, s_state.window_height); SetKeyMap(); - SetStyle(s_imgui_context->Style, s_global_scale); + SetStyle(s_state.imgui_context->Style, s_state.global_scale); if (!AddImGuiFonts(false, false) || !g_gpu_device->UpdateImGuiFontTexture()) { @@ -290,43 +301,43 @@ void ImGuiManager::Shutdown() { DestroySoftwareCursorTextures(); - if (s_imgui_context) + if (s_state.imgui_context) { - ImGui::DestroyContext(s_imgui_context); - s_imgui_context = nullptr; + ImGui::DestroyContext(s_state.imgui_context); + s_state.imgui_context = nullptr; } - s_debug_font = nullptr; - s_fixed_font = nullptr; - s_medium_font = nullptr; - s_large_font = nullptr; + s_state.debug_font = nullptr; + s_state.fixed_font = nullptr; + s_state.medium_font = nullptr; + s_state.large_font = nullptr; ImGuiFullscreen::SetFonts(nullptr, nullptr); } ImGuiContext* ImGuiManager::GetMainContext() { - return s_imgui_context; + return s_state.imgui_context; } void ImGuiManager::SetScreenMargin(float margin) { - s_screen_margin = std::max(margin, 0.0f); + s_state.screen_margin = std::max(margin, 0.0f); } float ImGuiManager::GetWindowWidth() { - return s_window_width; + return s_state.window_width; } float ImGuiManager::GetWindowHeight() { - return s_window_height; + return s_state.window_height; } void ImGuiManager::WindowResized(float width, float height) { - s_window_width = width; - s_window_height = height; + s_state.window_width = width; + s_state.window_height = height; ImGui::GetIO().DisplaySize = ImVec2(width, height); // Scale might have changed as a result of window resize. @@ -336,20 +347,20 @@ void ImGuiManager::WindowResized(float width, float height) void ImGuiManager::RequestScaleUpdate() { // Might need to update the scale. - s_scale_changed = true; + s_state.scale_changed = true; } void ImGuiManager::UpdateScale() { const float window_scale = (g_gpu_device && g_gpu_device->HasMainSwapChain()) ? g_gpu_device->GetMainSwapChain()->GetScale() : 1.0f; - const float scale = std::max(window_scale * s_global_prescale, 1.0f); + const float scale = std::max(window_scale * s_state.global_prescale, 1.0f); - if ((!HasFullscreenFonts() || !ImGuiFullscreen::UpdateLayoutScale()) && scale == s_global_scale) + if ((!HasFullscreenFonts() || !ImGuiFullscreen::UpdateLayoutScale()) && scale == s_state.global_scale) return; - s_global_scale = scale; - SetStyle(s_imgui_context->Style, s_global_scale); + s_state.global_scale = scale; + SetStyle(s_state.imgui_context->Style, s_state.global_scale); if (!AddImGuiFonts(HasDebugFont(), HasFullscreenFonts())) Panic("Failed to create ImGui font text"); @@ -360,12 +371,15 @@ void ImGuiManager::UpdateScale() void ImGuiManager::NewFrame() { + const Timer::Value current_time = Timer::GetCurrentValue(); + ImGuiIO& io = ImGui::GetIO(); - io.DeltaTime = static_cast(s_last_render_time.GetTimeSecondsAndReset()); + io.DeltaTime = static_cast(Timer::ConvertValueToSeconds(current_time - s_state.last_render_time)); + s_state.last_render_time = current_time; - if (s_scale_changed) + if (s_state.scale_changed) { - s_scale_changed = false; + s_state.scale_changed = false; UpdateScale(); } @@ -374,13 +388,13 @@ void ImGuiManager::NewFrame() // Disable nav input on the implicit (Debug##Default) window. Otherwise we end up requesting keyboard // focus when there's nothing there. We use GetCurrentWindowRead() because otherwise it'll make it visible. ImGui::GetCurrentWindowRead()->Flags |= ImGuiWindowFlags_NoNavInputs; - s_imgui_wants_keyboard.store(io.WantCaptureKeyboard, std::memory_order_relaxed); - s_imgui_wants_mouse.store(io.WantCaptureMouse, std::memory_order_release); + s_state.imgui_wants_keyboard.store(io.WantCaptureKeyboard, std::memory_order_relaxed); + s_state.imgui_wants_mouse.store(io.WantCaptureMouse, std::memory_order_release); const bool wants_text_input = io.WantTextInput; - if (s_imgui_wants_text.load(std::memory_order_relaxed) != wants_text_input) + if (s_state.imgui_wants_text.load(std::memory_order_relaxed) != wants_text_input) { - s_imgui_wants_text.store(wants_text_input, std::memory_order_release); + s_state.imgui_wants_text.store(wants_text_input, std::memory_order_release); if (wants_text_input) Host::BeginTextInput(); else @@ -560,65 +574,65 @@ void ImGuiManager::SetKeyMap() {ImGuiKey_KeypadEnter, "KeypadReturn", nullptr}, {ImGuiKey_KeypadEqual, "KeypadEqual", nullptr}}; - s_imgui_key_map.clear(); + s_state.imgui_key_map.clear(); for (const KeyMapping& km : mapping) { std::optional map(InputManager::ConvertHostKeyboardStringToCode(km.name)); if (!map.has_value() && km.alt_name) map = InputManager::ConvertHostKeyboardStringToCode(km.alt_name); if (map.has_value()) - s_imgui_key_map[map.value()] = km.index; + s_state.imgui_key_map[map.value()] = km.index; } } bool ImGuiManager::LoadFontData(Error* error) { - if (s_standard_font_data.empty()) + if (s_state.standard_font_data.empty()) { - std::optional> font_data = s_font_path.empty() ? + std::optional> font_data = s_state.font_path.empty() ? Host::ReadResourceFile("fonts/Roboto-Regular.ttf", true, error) : - FileSystem::ReadBinaryFile(s_font_path.c_str(), error); + FileSystem::ReadBinaryFile(s_state.font_path.c_str(), error); if (!font_data.has_value()) return false; - s_standard_font_data = std::move(font_data.value()); + s_state.standard_font_data = std::move(font_data.value()); } - if (s_fixed_font_data.empty()) + if (s_state.fixed_font_data.empty()) { std::optional> font_data = Host::ReadResourceFile("fonts/RobotoMono-Medium.ttf", true, error); if (!font_data.has_value()) return false; - s_fixed_font_data = std::move(font_data.value()); + s_state.fixed_font_data = std::move(font_data.value()); } - if (s_icon_fa_font_data.empty()) + if (s_state.icon_fa_font_data.empty()) { std::optional> font_data = Host::ReadResourceFile("fonts/fa-solid-900.ttf", true, error); if (!font_data.has_value()) return false; - s_icon_fa_font_data = std::move(font_data.value()); + s_state.icon_fa_font_data = std::move(font_data.value()); } - if (s_icon_pf_font_data.empty()) + if (s_state.icon_pf_font_data.empty()) { std::optional> font_data = Host::ReadResourceFile("fonts/promptfont.otf", true, error); if (!font_data.has_value()) return false; - s_icon_pf_font_data = std::move(font_data.value()); + s_state.icon_pf_font_data = std::move(font_data.value()); } - if (s_emoji_font_data.empty()) + if (s_state.emoji_font_data.empty()) { std::optional> font_data = Host::ReadCompressedResourceFile("fonts/TwitterColorEmoji-SVGinOT.ttf.zst", true, error); if (!font_data.has_value()) return false; - s_emoji_font_data = std::move(font_data.value()); + s_state.emoji_font_data = std::move(font_data.value()); } return true; @@ -628,17 +642,18 @@ ImFont* ImGuiManager::AddTextFont(float size, bool full_glyph_range) { ImFontConfig cfg; cfg.FontDataOwnedByAtlas = false; - return ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_standard_font_data.data(), - static_cast(s_standard_font_data.size()), size, &cfg, - full_glyph_range ? s_font_range.data() : s_ascii_font_range.data()); + return ImGui::GetIO().Fonts->AddFontFromMemoryTTF( + s_state.standard_font_data.data(), static_cast(s_state.standard_font_data.size()), size, &cfg, + full_glyph_range ? s_state.font_range.data() : s_ascii_font_range.data()); } ImFont* ImGuiManager::AddFixedFont(float size) { ImFontConfig cfg; cfg.FontDataOwnedByAtlas = false; - return ImGui::GetIO().Fonts->AddFontFromMemoryTTF( - s_fixed_font_data.data(), static_cast(s_fixed_font_data.size()), size, &cfg, s_ascii_font_range.data()); + return ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_state.fixed_font_data.data(), + static_cast(s_state.fixed_font_data.size()), size, &cfg, + s_ascii_font_range.data()); } bool ImGuiManager::AddIconFonts(float size) @@ -651,9 +666,9 @@ bool ImGuiManager::AddIconFonts(float size) cfg.GlyphMaxAdvanceX = size; cfg.FontDataOwnedByAtlas = false; - if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF( - s_icon_fa_font_data.data(), static_cast(s_icon_fa_font_data.size()), size * 0.75f, &cfg, FA_ICON_RANGE)) - [[unlikely]] + if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_state.icon_fa_font_data.data(), + static_cast(s_state.icon_fa_font_data.size()), size * 0.75f, + &cfg, FA_ICON_RANGE)) [[unlikely]] { return false; } @@ -667,9 +682,9 @@ bool ImGuiManager::AddIconFonts(float size) cfg.GlyphMaxAdvanceX = size; cfg.FontDataOwnedByAtlas = false; - if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF( - s_icon_pf_font_data.data(), static_cast(s_icon_pf_font_data.size()), size * 1.2f, &cfg, PF_ICON_RANGE)) - [[unlikely]] + if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF(s_state.icon_pf_font_data.data(), + static_cast(s_state.icon_pf_font_data.size()), size * 1.2f, + &cfg, PF_ICON_RANGE)) [[unlikely]] { return false; } @@ -685,8 +700,8 @@ bool ImGuiManager::AddIconFonts(float size) cfg.FontBuilderFlags = ImGuiFreeTypeBuilderFlags_LoadColor | ImGuiFreeTypeBuilderFlags_Bitmap; if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF( - s_emoji_font_data.data(), static_cast(s_emoji_font_data.size()), size * 0.9f, &cfg, - s_emoji_range.empty() ? EMOJI_ICON_RANGE : s_emoji_range.data())) [[unlikely]] + s_state.emoji_font_data.data(), static_cast(s_state.emoji_font_data.size()), size * 0.9f, &cfg, + s_state.emoji_range.empty() ? EMOJI_ICON_RANGE : s_state.emoji_range.data())) [[unlikely]] { return false; } @@ -700,10 +715,10 @@ bool ImGuiManager::AddImGuiFonts(bool debug_font, bool fullscreen_fonts) const float window_scale = (g_gpu_device && g_gpu_device->HasMainSwapChain()) ? g_gpu_device->GetMainSwapChain()->GetScale() : 1.0f; const float debug_font_size = std::ceil(15.0f * window_scale); - const float standard_font_size = std::ceil(15.0f * s_global_scale); - const float osd_font_size = std::ceil(17.0f * s_global_scale); + const float standard_font_size = std::ceil(15.0f * s_state.global_scale); + const float osd_font_size = std::ceil(17.0f * s_state.global_scale); - INFO_LOG("Allocating fonts winscale={} globalscale={} debug={} fullscreen={}", window_scale, s_global_scale, + INFO_LOG("Allocating fonts winscale={} globalscale={} debug={} fullscreen={}", window_scale, s_state.global_scale, debug_font, fullscreen_fonts); ImGuiIO& io = ImGui::GetIO(); @@ -711,47 +726,47 @@ bool ImGuiManager::AddImGuiFonts(bool debug_font, bool fullscreen_fonts) if (debug_font) { - s_debug_font = AddTextFont(debug_font_size, false); - if (!s_debug_font) + s_state.debug_font = AddTextFont(debug_font_size, false); + if (!s_state.debug_font) return false; } - s_fixed_font = AddFixedFont(standard_font_size); - if (!s_fixed_font) + s_state.fixed_font = AddFixedFont(standard_font_size); + if (!s_state.fixed_font) return false; - s_osd_font = AddTextFont(osd_font_size, true); - if (!s_osd_font || !AddIconFonts(osd_font_size)) + s_state.osd_font = AddTextFont(osd_font_size, true); + if (!s_state.osd_font || !AddIconFonts(osd_font_size)) return false; if (!debug_font) - s_debug_font = s_osd_font; + s_state.debug_font = s_state.osd_font; if (fullscreen_fonts) { const float medium_font_size = ImGuiFullscreen::LayoutScale(ImGuiFullscreen::LAYOUT_MEDIUM_FONT_SIZE); - s_medium_font = AddTextFont(medium_font_size, true); - if (!s_medium_font || !AddIconFonts(medium_font_size)) + s_state.medium_font = AddTextFont(medium_font_size, true); + if (!s_state.medium_font || !AddIconFonts(medium_font_size)) return false; const float large_font_size = ImGuiFullscreen::LayoutScale(ImGuiFullscreen::LAYOUT_LARGE_FONT_SIZE); - s_large_font = AddTextFont(large_font_size, true); - if (!s_large_font || !AddIconFonts(large_font_size)) + s_state.large_font = AddTextFont(large_font_size, true); + if (!s_state.large_font || !AddIconFonts(large_font_size)) return false; } else { - s_medium_font = nullptr; - s_large_font = nullptr; + s_state.medium_font = nullptr; + s_state.large_font = nullptr; } - ImGuiFullscreen::SetFonts(s_medium_font, s_large_font); + ImGuiFullscreen::SetFonts(s_state.medium_font, s_state.large_font); return io.Fonts->Build(); } void ImGuiManager::ReloadFontDataIfActive() { - if (!s_imgui_context) + if (!s_state.imgui_context) return; ImGui::EndFrame(); @@ -791,7 +806,7 @@ bool ImGuiManager::AddFullscreenFontsIfMissing() bool ImGuiManager::HasDebugFont() { - return (s_debug_font != s_osd_font); + return (s_state.debug_font != s_state.osd_font); } bool ImGuiManager::AddDebugFontIfMissing() @@ -817,7 +832,7 @@ bool ImGuiManager::AddDebugFontIfMissing() bool ImGuiManager::HasFullscreenFonts() { - return (s_medium_font && s_large_font); + return (s_state.medium_font && s_state.large_font); } void ImGuiManager::AddOSDMessage(std::string key, std::string message, float duration, bool is_warning) @@ -827,7 +842,7 @@ void ImGuiManager::AddOSDMessage(std::string key, std::string message, float dur else INFO_LOG("OSD: {}", message); - if (!s_show_osd_messages && !is_warning) + if (!s_state.show_osd_messages && !is_warning) return; const Timer::Value current_time = Timer::GetCurrentValue(); @@ -842,13 +857,13 @@ void ImGuiManager::AddOSDMessage(std::string key, std::string message, float dur msg.last_y = -1.0f; msg.is_warning = is_warning; - std::unique_lock lock(s_osd_messages_lock); - s_osd_posted_messages.push_back(std::move(msg)); + std::unique_lock lock(s_state.osd_messages_lock); + s_state.osd_posted_messages.push_back(std::move(msg)); } void ImGuiManager::RemoveKeyedOSDMessage(std::string key, bool is_warning) { - if (!s_show_osd_messages && !is_warning) + if (!s_state.show_osd_messages && !is_warning) return; ImGuiManager::OSDMessage msg = {}; @@ -856,24 +871,24 @@ void ImGuiManager::RemoveKeyedOSDMessage(std::string key, bool is_warning) msg.duration = 0.0f; msg.is_warning = is_warning; - std::unique_lock lock(s_osd_messages_lock); - s_osd_posted_messages.push_back(std::move(msg)); + std::unique_lock lock(s_state.osd_messages_lock); + s_state.osd_posted_messages.push_back(std::move(msg)); } void ImGuiManager::ClearOSDMessages(bool clear_warnings) { { - std::unique_lock lock(s_osd_messages_lock); + std::unique_lock lock(s_state.osd_messages_lock); if (clear_warnings) { - s_osd_posted_messages.clear(); + s_state.osd_posted_messages.clear(); } else { - for (auto iter = s_osd_posted_messages.begin(); iter != s_osd_posted_messages.end();) + for (auto iter = s_state.osd_posted_messages.begin(); iter != s_state.osd_posted_messages.end();) { if (!iter->is_warning) - iter = s_osd_posted_messages.erase(iter); + iter = s_state.osd_posted_messages.erase(iter); else ++iter; } @@ -882,14 +897,14 @@ void ImGuiManager::ClearOSDMessages(bool clear_warnings) if (clear_warnings) { - s_osd_active_messages.clear(); + s_state.osd_active_messages.clear(); } else { - for (auto iter = s_osd_active_messages.begin(); iter != s_osd_active_messages.end();) + for (auto iter = s_state.osd_active_messages.begin(); iter != s_state.osd_active_messages.end();) { if (!iter->is_warning) - s_osd_active_messages.erase(iter); + s_state.osd_active_messages.erase(iter); else ++iter; } @@ -899,21 +914,21 @@ void ImGuiManager::ClearOSDMessages(bool clear_warnings) void ImGuiManager::AcquirePendingOSDMessages(Timer::Value current_time) { std::atomic_thread_fence(std::memory_order_consume); - if (s_osd_posted_messages.empty()) + if (s_state.osd_posted_messages.empty()) return; - std::unique_lock lock(s_osd_messages_lock); + std::unique_lock lock(s_state.osd_messages_lock); for (;;) { - if (s_osd_posted_messages.empty()) + if (s_state.osd_posted_messages.empty()) break; - OSDMessage& new_msg = s_osd_posted_messages.front(); + OSDMessage& new_msg = s_state.osd_posted_messages.front(); std::deque::iterator iter; - if (!new_msg.key.empty() && (iter = std::find_if(s_osd_active_messages.begin(), s_osd_active_messages.end(), - [&new_msg](const OSDMessage& other) { - return new_msg.key == other.key; - })) != s_osd_active_messages.end()) + if (!new_msg.key.empty() && + (iter = std::find_if(s_state.osd_active_messages.begin(), s_state.osd_active_messages.end(), + [&new_msg](const OSDMessage& other) { return new_msg.key == other.key; })) != + s_state.osd_active_messages.end()) { iter->text = std::move(new_msg.text); iter->duration = new_msg.duration; @@ -924,14 +939,14 @@ void ImGuiManager::AcquirePendingOSDMessages(Timer::Value current_time) } else { - s_osd_active_messages.push_back(std::move(new_msg)); + s_state.osd_active_messages.push_back(std::move(new_msg)); } - s_osd_posted_messages.pop_front(); + s_state.osd_posted_messages.pop_front(); static constexpr size_t MAX_ACTIVE_OSD_MESSAGES = 512; - if (s_osd_active_messages.size() > MAX_ACTIVE_OSD_MESSAGES) - s_osd_active_messages.pop_front(); + if (s_state.osd_active_messages.size() > MAX_ACTIVE_OSD_MESSAGES) + s_state.osd_active_messages.pop_front(); } } @@ -939,24 +954,24 @@ void ImGuiManager::DrawOSDMessages(Timer::Value current_time) { static constexpr float MOVE_DURATION = 0.5f; - ImFont* const font = s_osd_font; - const float scale = s_global_scale; + ImFont* const font = s_state.osd_font; + const float scale = s_state.global_scale; const float spacing = std::ceil(6.0f * scale); - const float margin = std::ceil(s_screen_margin * scale); + const float margin = std::ceil(s_state.screen_margin * scale); const float padding = std::ceil(9.0f * scale); const float rounding = std::ceil(6.0f * scale); - const float max_width = s_window_width - (margin + padding) * 2.0f; + const float max_width = s_state.window_width - (margin + padding) * 2.0f; float position_x = margin; float position_y = margin; - auto iter = s_osd_active_messages.begin(); - while (iter != s_osd_active_messages.end()) + auto iter = s_state.osd_active_messages.begin(); + while (iter != s_state.osd_active_messages.end()) { OSDMessage& msg = *iter; const float time_passed = static_cast(Timer::ConvertValueToSeconds(current_time - msg.start_time)); if (time_passed >= msg.duration) { - iter = s_osd_active_messages.erase(iter); + iter = s_state.osd_active_messages.erase(iter); continue; } @@ -1074,68 +1089,68 @@ void Host::ClearOSDMessages(bool clear_warnings) float ImGuiManager::GetGlobalScale() { - return s_global_scale; + return s_state.global_scale; } float ImGuiManager::GetScreenMargin() { - return s_screen_margin; + return s_state.screen_margin; } ImFont* ImGuiManager::GetDebugFont() { - return s_debug_font; + return s_state.debug_font; } ImFont* ImGuiManager::GetOSDFont() { - return s_osd_font; + return s_state.osd_font; } ImFont* ImGuiManager::GetFixedFont() { - return s_fixed_font; + return s_state.fixed_font; } ImFont* ImGuiManager::GetMediumFont() { AddFullscreenFontsIfMissing(); - return s_medium_font; + return s_state.medium_font; } ImFont* ImGuiManager::GetLargeFont() { AddFullscreenFontsIfMissing(); - return s_large_font; + return s_state.large_font; } bool ImGuiManager::WantsTextInput() { - return s_imgui_wants_keyboard.load(std::memory_order_acquire); + return s_state.imgui_wants_keyboard.load(std::memory_order_acquire); } bool ImGuiManager::WantsMouseInput() { - return s_imgui_wants_mouse.load(std::memory_order_acquire); + return s_state.imgui_wants_mouse.load(std::memory_order_acquire); } void ImGuiManager::AddTextInput(std::string str) { - if (!s_imgui_context) + if (!s_state.imgui_context) return; - if (!s_imgui_wants_keyboard.load(std::memory_order_acquire)) + if (!s_state.imgui_wants_keyboard.load(std::memory_order_acquire)) return; - s_imgui_context->IO.AddInputCharactersUTF8(str.c_str()); + s_state.imgui_context->IO.AddInputCharactersUTF8(str.c_str()); } void ImGuiManager::UpdateMousePosition(float x, float y) { - if (!s_imgui_context) + if (!s_state.imgui_context) return; - s_imgui_context->IO.MousePos = ImVec2(x, y); + s_state.imgui_context->IO.MousePos = ImVec2(x, y); std::atomic_thread_fence(std::memory_order_release); } @@ -1150,53 +1165,53 @@ void ImGuiManager::SetCommonIOOptions(ImGuiIO& io) bool ImGuiManager::ProcessPointerButtonEvent(InputBindingKey key, float value) { - if (!s_imgui_context || key.data >= std::size(ImGui::GetIO().MouseDown)) + if (!s_state.imgui_context || key.data >= std::size(ImGui::GetIO().MouseDown)) return false; // still update state anyway - s_imgui_context->IO.AddMouseButtonEvent(key.data, value != 0.0f); + s_state.imgui_context->IO.AddMouseButtonEvent(key.data, value != 0.0f); - return s_imgui_wants_mouse.load(std::memory_order_acquire); + return s_state.imgui_wants_mouse.load(std::memory_order_acquire); } bool ImGuiManager::ProcessPointerAxisEvent(InputBindingKey key, float value) { - if (!s_imgui_context || key.data < static_cast(InputPointerAxis::WheelX)) + if (!s_state.imgui_context || key.data < static_cast(InputPointerAxis::WheelX)) return false; // still update state anyway const bool horizontal = (key.data == static_cast(InputPointerAxis::WheelX)); - s_imgui_context->IO.AddMouseWheelEvent(horizontal ? value : 0.0f, horizontal ? 0.0f : value); + s_state.imgui_context->IO.AddMouseWheelEvent(horizontal ? value : 0.0f, horizontal ? 0.0f : value); - return s_imgui_wants_mouse.load(std::memory_order_acquire); + return s_state.imgui_wants_mouse.load(std::memory_order_acquire); } bool ImGuiManager::ProcessHostKeyEvent(InputBindingKey key, float value) { - if (!s_imgui_context) + if (!s_state.imgui_context) return false; // still update state anyway - SetImKeyState(s_imgui_context->IO, key.data, (value != 0.0f)); + SetImKeyState(s_state.imgui_context->IO, key.data, (value != 0.0f)); - return s_imgui_wants_keyboard.load(std::memory_order_acquire); + return s_state.imgui_wants_keyboard.load(std::memory_order_acquire); } void ImGuiManager::SetImKeyState(ImGuiIO& io, u32 key, bool pressed) { - const auto iter = s_imgui_key_map.find(key); - if (iter == s_imgui_key_map.end()) + const auto iter = s_state.imgui_key_map.find(key); + if (iter == s_state.imgui_key_map.end()) return; const ImGuiKey imkey = iter->second; - s_imgui_context->IO.AddKeyEvent(imkey, pressed); + s_state.imgui_context->IO.AddKeyEvent(imkey, pressed); // modifier keys need to be handled separately if ((imkey >= ImGuiKey_LeftCtrl && imkey <= ImGuiKey_LeftSuper) || (imkey >= ImGuiKey_RightCtrl && imkey <= ImGuiKey_RightSuper)) { const u32 idx = imkey - ((imkey >= ImGuiKey_RightCtrl) ? ImGuiKey_RightCtrl : ImGuiKey_LeftCtrl); - s_imgui_context->IO.AddKeyEvent(static_cast(static_cast(ImGuiMod_Ctrl) << idx), pressed); + s_state.imgui_context->IO.AddKeyEvent(static_cast(static_cast(ImGuiMod_Ctrl) << idx), pressed); } } @@ -1231,14 +1246,14 @@ bool ImGuiManager::ProcessGenericInputEvent(GenericInputBinding key, float value ImGuiKey_GamepadL2, // R2 }; - if (!s_imgui_context) + if (!s_state.imgui_context) return false; if (static_cast(key) >= std::size(key_map) || key_map[static_cast(key)] == ImGuiKey_None) return false; - s_imgui_context->IO.AddKeyAnalogEvent(key_map[static_cast(key)], (value > 0.0f), value); - return s_imgui_wants_keyboard.load(std::memory_order_acquire); + s_state.imgui_context->IO.AddKeyAnalogEvent(key_map[static_cast(key)], (value > 0.0f), value); + return s_state.imgui_wants_keyboard.load(std::memory_order_acquire); } const char* ImGuiManager::GetClipboardTextImpl(void* userdata) @@ -1265,22 +1280,22 @@ void ImGuiManager::SetClipboardTextImpl(void* userdata, const char* text) void ImGuiManager::CreateSoftwareCursorTextures() { - for (u32 i = 0; i < static_cast(s_software_cursors.size()); i++) + for (u32 i = 0; i < static_cast(s_state.software_cursors.size()); i++) { - if (!s_software_cursors[i].image_path.empty()) + if (!s_state.software_cursors[i].image_path.empty()) UpdateSoftwareCursorTexture(i); } } void ImGuiManager::DestroySoftwareCursorTextures() { - for (SoftwareCursor& sc : s_software_cursors) + for (SoftwareCursor& sc : s_state.software_cursors) sc.texture.reset(); } void ImGuiManager::UpdateSoftwareCursorTexture(u32 index) { - SoftwareCursor& sc = s_software_cursors[index]; + SoftwareCursor& sc = s_state.software_cursors[index]; if (sc.image_path.empty()) { sc.texture.reset(); @@ -1305,8 +1320,8 @@ void ImGuiManager::UpdateSoftwareCursorTexture(u32 index) return; } - sc.extent_x = std::ceil(static_cast(image.GetWidth()) * sc.scale * s_global_scale) / 2.0f; - sc.extent_y = std::ceil(static_cast(image.GetHeight()) * sc.scale * s_global_scale) / 2.0f; + sc.extent_x = std::ceil(static_cast(image.GetWidth()) * sc.scale * s_state.global_scale) / 2.0f; + sc.extent_y = std::ceil(static_cast(image.GetHeight()) * sc.scale * s_state.global_scale) / 2.0f; } void ImGuiManager::DrawSoftwareCursor(const SoftwareCursor& sc, const std::pair& pos) @@ -1328,16 +1343,16 @@ void ImGuiManager::RenderSoftwareCursors() // This one's okay to race, worst that happens is we render the wrong number of cursors for a frame. const u32 pointer_count = InputManager::GetPointerCount(); for (u32 i = 0; i < pointer_count; i++) - DrawSoftwareCursor(s_software_cursors[i], InputManager::GetPointerAbsolutePosition(i)); + DrawSoftwareCursor(s_state.software_cursors[i], InputManager::GetPointerAbsolutePosition(i)); for (u32 i = InputManager::MAX_POINTER_DEVICES; i < InputManager::MAX_SOFTWARE_CURSORS; i++) - DrawSoftwareCursor(s_software_cursors[i], s_software_cursors[i].pos); + DrawSoftwareCursor(s_state.software_cursors[i], s_state.software_cursors[i].pos); } void ImGuiManager::SetSoftwareCursor(u32 index, std::string image_path, float image_scale, u32 multiply_color) { - DebugAssert(index < std::size(s_software_cursors)); - SoftwareCursor& sc = s_software_cursors[index]; + DebugAssert(index < std::size(s_state.software_cursors)); + SoftwareCursor& sc = s_state.software_cursors[index]; sc.color = multiply_color | 0xFF000000; if (sc.image_path == image_path && sc.scale == image_scale) return; @@ -1355,7 +1370,7 @@ void ImGuiManager::SetSoftwareCursor(u32 index, std::string image_path, float im bool ImGuiManager::HasSoftwareCursor(u32 index) { - return (index < s_software_cursors.size() && !s_software_cursors[index].image_path.empty()); + return (index < s_state.software_cursors.size() && !s_state.software_cursors[index].image_path.empty()); } void ImGuiManager::ClearSoftwareCursor(u32 index) @@ -1366,7 +1381,7 @@ void ImGuiManager::ClearSoftwareCursor(u32 index) void ImGuiManager::SetSoftwareCursorPosition(u32 index, float pos_x, float pos_y) { DebugAssert(index >= InputManager::MAX_POINTER_DEVICES); - SoftwareCursor& sc = s_software_cursors[index]; + SoftwareCursor& sc = s_state.software_cursors[index]; sc.pos.first = pos_x; sc.pos.second = pos_y; } @@ -1436,7 +1451,7 @@ bool ImGuiManager::CreateAuxiliaryRenderWindow(AuxiliaryRenderWindowState* state AddDebugFontIfMissing(); - state->imgui_context = ImGui::CreateContext(s_imgui_context->IO.Fonts); + state->imgui_context = ImGui::CreateContext(s_state.imgui_context->IO.Fonts); state->imgui_context->IO.DisplaySize = ImVec2(static_cast(state->swap_chain->GetWidth()), static_cast(state->swap_chain->GetHeight())); state->imgui_context->IO.IniFilename = nullptr; @@ -1505,7 +1520,7 @@ bool ImGuiManager::RenderAuxiliaryRenderWindow(AuxiliaryRenderWindowState* state ImGui::SetCurrentContext(state->imgui_context); ImGui::NewFrame(); - ImGui::PushFont(s_debug_font); + ImGui::PushFont(s_state.debug_font); ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f), ImGuiCond_Always); ImGui::SetNextWindowSize(state->imgui_context->IO.DisplaySize, ImGuiCond_Always); if (ImGui::Begin("AuxRenderWindowMain", nullptr,