From cac66317aa715a3d9fcfe39ccbe5d224ca489637 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 31 Jan 2024 13:12:06 -0500 Subject: [PATCH 1/2] VideoCommon/Statistics: Remove global system accessor from s_after_frame_event Instead, we make the event take a reference to the system and then pass it in when the event is triggered. This does introduce two other accessors, but these are much easier to refactor out over time, and without modification to the existing event interface. --- Source/Core/Core/FifoPlayer/FifoRecorder.cpp | 4 ++-- Source/Core/VideoCommon/BPStructs.cpp | 2 +- Source/Core/VideoCommon/FrameDumper.cpp | 3 ++- Source/Core/VideoCommon/FramebufferManager.cpp | 3 ++- .../GraphicsModSystem/Runtime/CustomShaderCache.cpp | 4 ++-- .../Runtime/GraphicsModManager.cpp | 3 ++- Source/Core/VideoCommon/Present.cpp | 2 +- Source/Core/VideoCommon/ShaderCache.cpp | 4 ++-- Source/Core/VideoCommon/Statistics.cpp | 13 ++++++------- Source/Core/VideoCommon/TextureCacheBase.h | 2 +- Source/Core/VideoCommon/VertexManagerBase.cpp | 6 ++++-- Source/Core/VideoCommon/VideoConfig.cpp | 4 ++-- Source/Core/VideoCommon/VideoEvents.h | 7 ++++++- Source/Core/VideoCommon/Widescreen.cpp | 4 ++-- 14 files changed, 35 insertions(+), 26 deletions(-) diff --git a/Source/Core/Core/FifoPlayer/FifoRecorder.cpp b/Source/Core/Core/FifoPlayer/FifoRecorder.cpp index bfcb8c3dc7..bea5b94519 100644 --- a/Source/Core/Core/FifoPlayer/FifoRecorder.cpp +++ b/Source/Core/Core/FifoPlayer/FifoRecorder.cpp @@ -256,7 +256,7 @@ void FifoRecorder::StartRecording(s32 numFrames, CallbackFunc finishedCb) m_FinishedCb = finishedCb; m_end_of_frame_event = AfterFrameEvent::Register( - [this] { + [this](const Core::System& system) { const bool was_recording = OpcodeDecoder::g_record_fifo_data; OpcodeDecoder::g_record_fifo_data = IsRecording(); @@ -272,7 +272,7 @@ void FifoRecorder::StartRecording(s32 numFrames, CallbackFunc finishedCb) RecordInitialVideoMemory(); } - const auto& fifo = m_system.GetCommandProcessor().GetFifo(); + const auto& fifo = system.GetCommandProcessor().GetFifo(); EndFrame(fifo.CPBase.load(std::memory_order_relaxed), fifo.CPEnd.load(std::memory_order_relaxed)); }, diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 3da4a1f69a..0b8540bd44 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -346,7 +346,7 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager, XFStateManager& // render multiple sub-frames and arrange the XFB copies in next to each-other in main memory // so they form a single completed XFB. // See https://dolphin-emu.org/blog/2017/11/19/hybridxfb/ for examples and more detail. - AfterFrameEvent::Trigger(); + AfterFrameEvent::Trigger(Core::System::GetInstance()); // Note: Theoretically, in the future we could track the VI configuration and try to detect // when an XFB is the last XFB copy of a frame. Not only would we get a clean "end of diff --git a/Source/Core/VideoCommon/FrameDumper.cpp b/Source/Core/VideoCommon/FrameDumper.cpp index d45d9933be..db4ef5205e 100644 --- a/Source/Core/VideoCommon/FrameDumper.cpp +++ b/Source/Core/VideoCommon/FrameDumper.cpp @@ -27,7 +27,8 @@ static bool DumpFrameToPNG(const FrameData& frame, const std::string& file_name) FrameDumper::FrameDumper() { - m_frame_end_handle = AfterFrameEvent::Register([this] { FlushFrameDump(); }, "FrameDumper"); + m_frame_end_handle = + AfterFrameEvent::Register([this](Core::System&) { FlushFrameDump(); }, "FrameDumper"); } FrameDumper::~FrameDumper() diff --git a/Source/Core/VideoCommon/FramebufferManager.cpp b/Source/Core/VideoCommon/FramebufferManager.cpp index 9790551afb..bae9b1d15c 100644 --- a/Source/Core/VideoCommon/FramebufferManager.cpp +++ b/Source/Core/VideoCommon/FramebufferManager.cpp @@ -84,7 +84,8 @@ bool FramebufferManager::Initialize() return false; } - m_end_of_frame_event = AfterFrameEvent::Register([this] { EndOfFrame(); }, "FramebufferManager"); + m_end_of_frame_event = + AfterFrameEvent::Register([this](Core::System&) { EndOfFrame(); }, "FramebufferManager"); return true; } diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomShaderCache.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomShaderCache.cpp index cd871b5833..de68bffa63 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomShaderCache.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/CustomShaderCache.cpp @@ -16,8 +16,8 @@ CustomShaderCache::CustomShaderCache() m_async_uber_shader_compiler = g_gfx->CreateAsyncShaderCompiler(); m_async_uber_shader_compiler->StartWorkerThreads(1); // TODO - m_frame_end_handler = - AfterFrameEvent::Register([this] { RetrieveAsyncShaders(); }, "RetreiveAsyncShaders"); + m_frame_end_handler = AfterFrameEvent::Register([this](Core::System&) { RetrieveAsyncShaders(); }, + "RetrieveAsyncShaders"); } CustomShaderCache::~CustomShaderCache() diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.cpp b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.cpp index 01e7a07033..4ddd2d1d72 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.cpp +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.cpp @@ -95,7 +95,8 @@ bool GraphicsModManager::Initialize() g_ActiveConfig.graphics_mod_config->SetChangeCount(old_game_mod_changes); g_graphics_mod_manager->Load(*g_ActiveConfig.graphics_mod_config); - m_end_of_frame_event = AfterFrameEvent::Register([this] { EndOfFrame(); }, "ModManager"); + m_end_of_frame_event = + AfterFrameEvent::Register([this](Core::System&) { EndOfFrame(); }, "ModManager"); } return true; diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp index bf4b6af33b..8f773ae630 100644 --- a/Source/Core/VideoCommon/Present.cpp +++ b/Source/Core/VideoCommon/Present.cpp @@ -784,7 +784,7 @@ void Presenter::DoState(PointerWrap& p) if (p.IsReadMode() && m_last_xfb_stride != 0) { // This technically counts as the end of the frame - AfterFrameEvent::Trigger(); + AfterFrameEvent::Trigger(Core::System::GetInstance()); ImmediateSwap(m_last_xfb_addr, m_last_xfb_width, m_last_xfb_stride, m_last_xfb_height, m_last_xfb_ticks); diff --git a/Source/Core/VideoCommon/ShaderCache.cpp b/Source/Core/VideoCommon/ShaderCache.cpp index 7d11645949..ca409777ce 100644 --- a/Source/Core/VideoCommon/ShaderCache.cpp +++ b/Source/Core/VideoCommon/ShaderCache.cpp @@ -46,8 +46,8 @@ bool ShaderCache::Initialize() return false; m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler(); - m_frame_end_handler = - AfterFrameEvent::Register([this] { RetrieveAsyncShaders(); }, "RetreiveAsyncShaders"); + m_frame_end_handler = AfterFrameEvent::Register([this](Core::System&) { RetrieveAsyncShaders(); }, + "RetrieveAsyncShaders"); return true; } diff --git a/Source/Core/VideoCommon/Statistics.cpp b/Source/Core/VideoCommon/Statistics.cpp index 4103dbda3d..aea3b0e957 100644 --- a/Source/Core/VideoCommon/Statistics.cpp +++ b/Source/Core/VideoCommon/Statistics.cpp @@ -23,13 +23,12 @@ static Common::EventHook s_before_frame_event = BeforeFrameEvent::Register([] { g_stats.ResetFrame(); }, "Statistics::ResetFrame"); static Common::EventHook s_after_frame_event = AfterFrameEvent::Register( - [] { - DolphinAnalytics::PerformanceSample perf_sample; - perf_sample.speed_ratio = - Core::System::GetInstance().GetSystemTimers().GetEstimatedEmulationPerformance(); - perf_sample.num_prims = g_stats.this_frame.num_prims + g_stats.this_frame.num_dl_prims; - perf_sample.num_draw_calls = g_stats.this_frame.num_draw_calls; - DolphinAnalytics::Instance().ReportPerformanceInfo(std::move(perf_sample)); + [](const Core::System& system) { + DolphinAnalytics::Instance().ReportPerformanceInfo({ + .speed_ratio = system.GetSystemTimers().GetEstimatedEmulationPerformance(), + .num_prims = g_stats.this_frame.num_prims + g_stats.this_frame.num_dl_prims, + .num_draw_calls = g_stats.this_frame.num_draw_calls, + }); }, "Statistics::PerformanceSample"); diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index fd2ec0ad44..c6305a5813 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -459,7 +459,7 @@ private: void OnFrameEnd(); Common::EventHook m_frame_event = - AfterFrameEvent::Register([this] { OnFrameEnd(); }, "TextureCache"); + AfterFrameEvent::Register([this](Core::System&) { OnFrameEnd(); }, "TextureCache"); }; extern std::unique_ptr g_texture_cache; diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 1309ea4a47..94d609c23f 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -117,9 +117,11 @@ VertexManagerBase::~VertexManagerBase() = default; bool VertexManagerBase::Initialize() { - m_frame_end_event = AfterFrameEvent::Register([this] { OnEndFrame(); }, "VertexManagerBase"); + m_frame_end_event = + AfterFrameEvent::Register([this](Core::System&) { OnEndFrame(); }, "VertexManagerBase"); m_after_present_event = AfterPresentEvent::Register( - [this](PresentInfo& pi) { m_ticks_elapsed = pi.emulated_timestamp; }, "VertexManagerBase"); + [this](const PresentInfo& pi) { m_ticks_elapsed = pi.emulated_timestamp; }, + "VertexManagerBase"); m_index_generator.Init(); m_custom_shader_cache = std::make_unique(); m_cpu_cull.Init(); diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 51ab90fb7e..e11776d356 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -395,5 +395,5 @@ void CheckForConfigChanges() // TODO: Move everything else to the ConfigChanged event } -static Common::EventHook s_check_config_event = - AfterFrameEvent::Register([] { CheckForConfigChanges(); }, "CheckForConfigChanges"); +static Common::EventHook s_check_config_event = AfterFrameEvent::Register( + [](Core::System&) { CheckForConfigChanges(); }, "CheckForConfigChanges"); diff --git a/Source/Core/VideoCommon/VideoEvents.h b/Source/Core/VideoCommon/VideoEvents.h index 191db9802c..1d8b329265 100644 --- a/Source/Core/VideoCommon/VideoEvents.h +++ b/Source/Core/VideoCommon/VideoEvents.h @@ -6,6 +6,11 @@ #include "Common/CommonTypes.h" #include "Common/HookableEvent.h" +namespace Core +{ +class System; +} + // Called when certain video config setting are changed using ConfigChangedEvent = Common::HookableEvent<"ConfigChanged", u32>; @@ -16,7 +21,7 @@ using BeforeFrameEvent = Common::HookableEvent<"BeforeFrame">; // Useful for "once per frame" usecases. // Note: In a few rare cases, games do multiple XFB copies per frame and join them while presenting. // If this matters to your usecase, you should use BeforePresent instead. -using AfterFrameEvent = Common::HookableEvent<"AfterFrame">; +using AfterFrameEvent = Common::HookableEvent<"AfterFrame", Core::System&>; struct PresentInfo { diff --git a/Source/Core/VideoCommon/Widescreen.cpp b/Source/Core/VideoCommon/Widescreen.cpp index 1b3f6002c8..6cc12c7fc1 100644 --- a/Source/Core/VideoCommon/Widescreen.cpp +++ b/Source/Core/VideoCommon/Widescreen.cpp @@ -26,8 +26,8 @@ WidescreenManager::WidescreenManager() auto& system = Core::System::GetInstance(); if (!system.IsWii()) { - m_update_widescreen = - AfterFrameEvent::Register([this] { UpdateWidescreenHeuristic(); }, "WideScreen Heuristic"); + m_update_widescreen = AfterFrameEvent::Register( + [this](Core::System&) { UpdateWidescreenHeuristic(); }, "WideScreen Heuristic"); } } From 16d8b6e6b3af87e5d7684bf34ca79b765ff44d33 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 31 Jan 2024 13:16:48 -0500 Subject: [PATCH 2/2] Common/HookableEvent: std::move callback instance in Register() Potentially avoids reallocations if the capture buffer of the callback is quite large. --- Source/Core/Common/HookableEvent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/HookableEvent.h b/Source/Core/Common/HookableEvent.h index be97a8ab9b..987880de98 100644 --- a/Source/Core/Common/HookableEvent.h +++ b/Source/Core/Common/HookableEvent.h @@ -97,7 +97,7 @@ public: std::lock_guard lock(storage.m_mutex); DEBUG_LOG_FMT(COMMON, "Registering {} handler at {} event hook", name, EventName.value); - auto handle = std::make_unique(callback, std::move(name)); + auto handle = std::make_unique(std::move(callback), std::move(name)); storage.m_listeners.push_back(handle.get()); return handle; }