From 0645a267d97767a82b8a9cb3ef7c5731444dc3cf Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Mon, 3 Feb 2025 14:32:58 -0800 Subject: [PATCH] PerformanceMetrics: Add clamping, resetting on resize, and setting Clamp overlays to the render window (with some padding), reset their positions when the render window changes sizes, and add a setting to enable moving the overlays (off by default, .ini only for now). --- Source/Core/Core/Config/GraphicsSettings.cpp | 2 + Source/Core/Core/Config/GraphicsSettings.h | 1 + .../Core/VideoCommon/PerformanceMetrics.cpp | 61 ++++++++++++++++--- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index f201ac7f95..56528a2399 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -45,6 +45,8 @@ const Info GFX_SHOW_VTIMES{{System::GFX, "Settings", "ShowVTimes"}, false} const Info GFX_SHOW_GRAPHS{{System::GFX, "Settings", "ShowGraphs"}, false}; const Info GFX_SHOW_SPEED{{System::GFX, "Settings", "ShowSpeed"}, false}; const Info GFX_SHOW_SPEED_COLORS{{System::GFX, "Settings", "ShowSpeedColors"}, true}; +const Info GFX_MOVABLE_PERFORMANCE_METRICS{ + {System::GFX, "Settings", "MovablePerformanceMetrics"}, false}; const Info GFX_PERF_SAMP_WINDOW{{System::GFX, "Settings", "PerfSampWindowMS"}, 1000}; const Info GFX_SHOW_NETPLAY_PING{{System::GFX, "Settings", "ShowNetPlayPing"}, false}; const Info GFX_SHOW_NETPLAY_MESSAGES{{System::GFX, "Settings", "ShowNetPlayMessages"}, false}; diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index bf4ef4f008..46b5fb847a 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -47,6 +47,7 @@ extern const Info GFX_SHOW_VTIMES; extern const Info GFX_SHOW_GRAPHS; extern const Info GFX_SHOW_SPEED; extern const Info GFX_SHOW_SPEED_COLORS; +extern const Info GFX_MOVABLE_PERFORMANCE_METRICS; extern const Info GFX_PERF_SAMP_WINDOW; extern const Info GFX_SHOW_NETPLAY_PING; extern const Info GFX_SHOW_NETPLAY_MESSAGES; diff --git a/Source/Core/VideoCommon/PerformanceMetrics.cpp b/Source/Core/VideoCommon/PerformanceMetrics.cpp index f1adb9c6be..773dc44383 100644 --- a/Source/Core/VideoCommon/PerformanceMetrics.cpp +++ b/Source/Core/VideoCommon/PerformanceMetrics.cpp @@ -3,11 +3,13 @@ #include "VideoCommon/PerformanceMetrics.h" +#include #include #include #include +#include "Core/Config/GraphicsSettings.h" #include "Core/CoreTiming.h" #include "Core/HW/VideoInterface.h" #include "Core/System.h" @@ -82,15 +84,21 @@ double PerformanceMetrics::GetLastSpeedDenominator() const void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) { + const int movable_flag = Config::Get(Config::GFX_MOVABLE_PERFORMANCE_METRICS) ? + ImGuiWindowFlags_None : + ImGuiWindowFlags_NoMove; + const float bg_alpha = 0.7f; const auto imgui_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | - ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav | movable_flag | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing; const double fps = GetFPS(); const double vps = GetVPS(); const double speed = GetSpeed(); + static ImVec2 last_display_size(-1.0f, -1.0f); + // Change Color based on % Speed float r = 0.0f, g = 1.0f, b = 1.0f; if (g_ActiveConfig.bShowSpeedColors) @@ -102,12 +110,41 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) const float window_padding = 8.f * backbuffer_scale; const float window_width = 93.f * backbuffer_scale; + + const ImVec2& display_size = ImGui::GetIO().DisplaySize; + const bool display_size_changed = + display_size.x != last_display_size.x || display_size.y != last_display_size.y; + last_display_size = display_size; + // There are too many edge cases to reasonably handle when the display size changes, so just reset + // the layout to default. Hopefully users aren't changing window sizes or resolutions too often. + const ImGuiCond set_next_position_condition = + display_size_changed ? ImGuiCond_Always : ImGuiCond_FirstUseEver; + float window_y = window_padding; - float window_x = ImGui::GetIO().DisplaySize.x - window_padding; + float window_x = display_size.x - window_padding; + + const auto clamp_window_position = [&]() { + const ImVec2 position = ImGui::GetWindowPos(); + const ImVec2 size = ImGui::GetWindowSize(); + const float window_min_x = window_padding; + const float window_max_x = display_size.x - window_padding - size.x; + const float window_min_y = window_padding; + const float window_max_y = display_size.y - window_padding - size.y; + + if (window_min_x > window_max_x || window_min_y > window_max_y) + return; + + const float window_x = std::clamp(position.x, window_min_x, window_max_x); + const float window_y = std::clamp(position.y, window_min_y, window_max_y); + const bool window_needs_clamping = (window_x != position.x) || (window_y != position.y); + + if (window_needs_clamping) + ImGui::SetWindowPos(ImVec2(window_x, window_y), ImGuiCond_Always); + }; const float graph_width = 50.f * backbuffer_scale + 3.f * window_width + 2.f * window_padding; const float graph_height = - std::min(200.f * backbuffer_scale, ImGui::GetIO().DisplaySize.y - 85.f * backbuffer_scale); + std::min(200.f * backbuffer_scale, display_size.y - 85.f * backbuffer_scale); const bool stack_vertically = !g_ActiveConfig.bShowGraphs; @@ -118,7 +155,9 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 4.f * backbuffer_scale)); // Position in the top-right corner of the screen. - ImGui::SetNextWindowPos(ImVec2(window_x, window_y), ImGuiCond_FirstUseEver, ImVec2(1.0f, 0.0f)); + + ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition, + ImVec2(1.0f, 0.0f)); ImGui::SetNextWindowSize(ImVec2(graph_width, graph_height)); ImGui::SetNextWindowBgAlpha(bg_alpha); window_y += graph_height + window_padding; @@ -144,6 +183,8 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) 1000.0, 2000.0}; + clamp_window_position(); + const DT vblank_time = m_vps_counter.GetDtAvg() + 2 * m_vps_counter.GetDtStd(); const DT frame_time = m_fps_counter.GetDtAvg() + 2 * m_fps_counter.GetDtStd(); const double target_max_time = DT_ms(vblank_time + frame_time).count(); @@ -192,7 +233,8 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) // Position in the top-right corner of the screen. float window_height = 47.f * backbuffer_scale; - ImGui::SetNextWindowPos(ImVec2(window_x, window_y), ImGuiCond_FirstUseEver, ImVec2(1.0f, 0.0f)); + ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition, + ImVec2(1.0f, 0.0f)); ImGui::SetNextWindowSize(ImVec2(window_width, window_height)); ImGui::SetNextWindowBgAlpha(bg_alpha); @@ -203,6 +245,7 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) if (ImGui::Begin("SpeedStats", nullptr, imgui_flags)) { + clamp_window_position(); ImGui::TextColored(ImVec4(r, g, b, 1.0f), "Speed:%4.0lf%%", 100.0 * speed); ImGui::TextColored(ImVec4(r, g, b, 1.0f), "Max:%6.0lf%%", 100.0 * GetMaxSpeed()); } @@ -215,7 +258,8 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) float window_height = (12.f + 17.f * count) * backbuffer_scale; // Position in the top-right corner of the screen. - ImGui::SetNextWindowPos(ImVec2(window_x, window_y), ImGuiCond_FirstUseEver, ImVec2(1.0f, 0.0f)); + ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition, + ImVec2(1.0f, 0.0f)); ImGui::SetNextWindowSize(ImVec2(window_width, window_height)); ImGui::SetNextWindowBgAlpha(bg_alpha); @@ -226,6 +270,7 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) if (ImGui::Begin("FPSStats", nullptr, imgui_flags)) { + clamp_window_position(); if (g_ActiveConfig.bShowFPS) ImGui::TextColored(ImVec4(r, g, b, 1.0f), "FPS:%7.2lf", fps); if (g_ActiveConfig.bShowFTimes) @@ -245,7 +290,8 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) float window_height = (12.f + 17.f * count) * backbuffer_scale; // Position in the top-right corner of the screen. - ImGui::SetNextWindowPos(ImVec2(window_x, window_y), ImGuiCond_FirstUseEver, ImVec2(1.0f, 0.0f)); + ImGui::SetNextWindowPos(ImVec2(window_x, window_y), set_next_position_condition, + ImVec2(1.0f, 0.0f)); ImGui::SetNextWindowSize(ImVec2(window_width, (12.f + 17.f * count) * backbuffer_scale)); ImGui::SetNextWindowBgAlpha(bg_alpha); @@ -256,6 +302,7 @@ void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale) if (ImGui::Begin("VPSStats", nullptr, imgui_flags)) { + clamp_window_position(); if (g_ActiveConfig.bShowVPS) ImGui::TextColored(ImVec4(r, g, b, 1.0f), "VPS:%7.2lf", vps); if (g_ActiveConfig.bShowVTimes)