From f9c3f06f0a03cbff599bb9a601454fc1ae440a69 Mon Sep 17 00:00:00 2001 From: Mihai Brodschi Date: Sat, 14 Mar 2026 15:36:11 +0200 Subject: [PATCH] Move PerformanceMetrics from global variable to System This avoids the static initialization order fiasco between Core and VideoCommon Co-authored-by: Jordan Woyak --- Source/Core/Core/Core.cpp | 7 ++++--- Source/Core/Core/CoreTiming.cpp | 8 ++++---- Source/Core/Core/HW/SystemTimers.cpp | 2 +- Source/Core/Core/HW/VideoInterface.cpp | 2 +- Source/Core/Core/System.cpp | 6 ++++++ Source/Core/Core/System.h | 2 ++ Source/Core/VideoCommon/OnScreenUI.cpp | 3 ++- Source/Core/VideoCommon/PerformanceMetrics.cpp | 2 -- Source/Core/VideoCommon/PerformanceMetrics.h | 2 -- 9 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 8ee7c44c2b..cebcc748ec 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -332,7 +332,7 @@ static void CpuThread(Core::System& system, const std::optional& sa DolphinAnalytics::Instance().ReportGameStart(); // Clear performance data collected from previous threads. - g_perf_metrics.Reset(); + system.GetPerfMetrics().Reset(); // The JIT need to be able to intercept faults, both for fastmem and for the BLR optimization. const bool exception_handler = EMM::IsExceptionHandlerSupported(); @@ -856,11 +856,12 @@ void RunOnCPUThread(Core::System& system, Common::MoveOnlyFunction funct // Called from Renderer::Swap (GPU thread) when a frame is presented to the host screen. void Callback_FramePresented(const PresentInfo& present_info) { - g_perf_metrics.CountFrame(); + auto& perf_metrics = Core::System::GetInstance().GetPerfMetrics(); + perf_metrics.CountFrame(); const auto presentation_offset = present_info.actual_present_time - present_info.intended_present_time; - g_perf_metrics.SetLatestFramePresentationOffset(presentation_offset); + perf_metrics.SetLatestFramePresentationOffset(presentation_offset); if (present_info.reason == PresentInfo::PresentReason::VideoInterfaceDuplicate) return; diff --git a/Source/Core/Core/CoreTiming.cpp b/Source/Core/Core/CoreTiming.cpp index a692e8db6f..9e45a7c387 100644 --- a/Source/Core/Core/CoreTiming.cpp +++ b/Source/Core/Core/CoreTiming.cpp @@ -422,7 +422,7 @@ void CoreTimingManager::SleepUntil(TimePoint time_point) // Count amount of time sleeping for analytics const TimePoint time_after_sleep = Clock::now(); - g_perf_metrics.CountThrottleSleep(time_after_sleep - time); + m_system.GetPerfMetrics().CountThrottleSleep(time_after_sleep - time); } else { @@ -452,8 +452,8 @@ void CoreTimingManager::Throttle(const s64 target_cycle) // Measure current performance after throttling. Common::ScopeGuard perf_marker{[&] { - g_perf_metrics.CountPerformanceMarker(target_cycle, - m_system.GetSystemTimers().GetTicksPerSecond()); + m_system.GetPerfMetrics().CountPerformanceMarker( + target_cycle, m_system.GetSystemTimers().GetTicksPerSecond()); }}; if (IsSpeedUnlimited()) @@ -562,7 +562,7 @@ void CoreTimingManager::AdjustEventQueueTimes(u32 new_ppc_clock, u32 old_ppc_clo UpdateSpeedLimit(ticks, m_emulation_speed); - g_perf_metrics.AdjustClockSpeed(ticks, new_ppc_clock, old_ppc_clock); + m_system.GetPerfMetrics().AdjustClockSpeed(ticks, new_ppc_clock, old_ppc_clock); for (Event& ev : m_event_queue) { diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index 2b89d22d16..1790a97f05 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -214,7 +214,7 @@ s64 SystemTimersManager::GetLocalTimeRTCOffset() const double SystemTimersManager::GetEstimatedEmulationPerformance() const { - return g_perf_metrics.GetMaxSpeed(); + return m_system.GetPerfMetrics().GetMaxSpeed(); } // split from Init to break a circular dependency between VideoInterface::Init and diff --git a/Source/Core/Core/HW/VideoInterface.cpp b/Source/Core/Core/HW/VideoInterface.cpp index 3d46a345ee..42e0f350ba 100644 --- a/Source/Core/Core/HW/VideoInterface.cpp +++ b/Source/Core/Core/HW/VideoInterface.cpp @@ -895,7 +895,7 @@ void VideoInterfaceManager::EndField(FieldType field, u64 ticks) if (is_vblank_data_wanted) m_system.GetCoreTiming().Throttle(ticks); - g_perf_metrics.CountVBlank(); + m_system.GetPerfMetrics().CountVBlank(); m_system.GetVideoEvents().vi_end_field_event.Trigger(); Core::OnFrameEnd(m_system); } diff --git a/Source/Core/Core/System.cpp b/Source/Core/Core/System.cpp index d22c058258..2c64c7f2b6 100644 --- a/Source/Core/Core/System.cpp +++ b/Source/Core/Core/System.cpp @@ -85,6 +85,7 @@ struct System::Impl IOS::WiiIPC m_wii_ipc; Memory::MemoryManager m_memory; MemoryInterface::MemoryInterfaceManager m_memory_interface; + PerformanceMetrics m_perf_metrics; PixelEngine::PixelEngineManager m_pixel_engine; PixelShaderManager m_pixel_shader_manager; PowerPC::PowerPCManager m_power_pc; @@ -273,6 +274,11 @@ Movie::MovieManager& System::GetMovie() const return m_impl->m_movie; } +PerformanceMetrics& System::GetPerfMetrics() const +{ + return m_impl->m_perf_metrics; +} + PixelEngine::PixelEngineManager& System::GetPixelEngine() const { return m_impl->m_pixel_engine; diff --git a/Source/Core/Core/System.h b/Source/Core/Core/System.h index e9fdec092d..8b8e8e4a87 100644 --- a/Source/Core/Core/System.h +++ b/Source/Core/Core/System.h @@ -5,6 +5,7 @@ #include +#include "VideoCommon/PerformanceMetrics.h" #include "VideoCommon/VideoEvents.h" class GeometryShaderManager; @@ -186,6 +187,7 @@ public: MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const; PowerPC::MMU& GetMMU() const; Movie::MovieManager& GetMovie() const; + PerformanceMetrics& GetPerfMetrics() const; PixelEngine::PixelEngineManager& GetPixelEngine() const; PixelShaderManager& GetPixelShaderManager() const; PowerPC::PowerPCManager& GetPowerPC() const; diff --git a/Source/Core/VideoCommon/OnScreenUI.cpp b/Source/Core/VideoCommon/OnScreenUI.cpp index 0bf669ab96..209e96c9b2 100644 --- a/Source/Core/VideoCommon/OnScreenUI.cpp +++ b/Source/Core/VideoCommon/OnScreenUI.cpp @@ -417,7 +417,8 @@ void OnScreenUI::Finalize() { auto lock = GetImGuiLock(); - g_perf_metrics.DrawImGuiStats(m_backbuffer_scale); + auto& perf_metrics = Core::System::GetInstance().GetPerfMetrics(); + perf_metrics.DrawImGuiStats(m_backbuffer_scale); DrawDebugText(); OSD::DrawMessages(); DrawChallengesAndLeaderboards(); diff --git a/Source/Core/VideoCommon/PerformanceMetrics.cpp b/Source/Core/VideoCommon/PerformanceMetrics.cpp index cba4beb8c6..9676eb3b33 100644 --- a/Source/Core/VideoCommon/PerformanceMetrics.cpp +++ b/Source/Core/VideoCommon/PerformanceMetrics.cpp @@ -13,8 +13,6 @@ #include "Core/Core.h" #include "VideoCommon/VideoConfig.h" -PerformanceMetrics g_perf_metrics; - PerformanceMetrics::PerformanceMetrics() { const auto invalidate_counters_last_time = [this](Core::State) { diff --git a/Source/Core/VideoCommon/PerformanceMetrics.h b/Source/Core/VideoCommon/PerformanceMetrics.h index 71fd339c07..6a6260a611 100644 --- a/Source/Core/VideoCommon/PerformanceMetrics.h +++ b/Source/Core/VideoCommon/PerformanceMetrics.h @@ -71,5 +71,3 @@ private: Common::EventHook m_state_change_hook; }; - -extern PerformanceMetrics g_perf_metrics;