diff --git a/Source/Core/Common/EventHook.h b/Source/Core/Common/EventHook.h index f4d6ea0863..49a3b9514a 100644 --- a/Source/Core/Common/EventHook.h +++ b/Source/Core/Common/EventHook.h @@ -8,10 +8,13 @@ #include #include +#include #include #include #include +namespace Common +{ // A hookable event system. // Define Events in a header as: @@ -43,10 +46,13 @@ public: using CallbackType = std::function; private: - struct HookImpl : public HookBase + struct HookImpl final : public HookBase { ~HookImpl() override { Event::Remove(this); } - HookImpl(CallbackType callback, std::string name) : m_fn(std::move(callback)), m_name(std::move(name)) {} + HookImpl(CallbackType callback, std::string name) + : m_fn(std::move(callback)), m_name(std::move(name)) + { + } CallbackType m_fn; std::string m_name; }; @@ -55,6 +61,7 @@ public: // Returns a handle that will unregister the listener when destroyed. static EventHook Register(CallbackType callback, std::string name) { + std::lock_guard lock(m_mutex); DEBUG_LOG_FMT(COMMON, "Registering {} handler at {} event hook", name, EventName.value); auto handle = std::make_unique(callback, std::move(name)); m_listeners.push_back(handle.get()); @@ -63,6 +70,7 @@ public: static void Trigger(const CallbackArgs&... args) { + std::lock_guard lock(m_mutex); for (auto& handle : m_listeners) handle->m_fn(args...); } @@ -70,10 +78,12 @@ public: private: static void Remove(HookImpl* handle) { - auto it = std::find(m_listeners.begin(), m_listeners.end(), handle); - if (it != m_listeners.end()) - m_listeners.erase(it); + std::lock_guard lock(m_mutex); + std::erase(m_listeners, handle); } inline static std::vector m_listeners = {}; + inline static std::mutex m_mutex; }; + +} // namespace Common diff --git a/Source/Core/Common/StringLiteral.h b/Source/Core/Common/StringLiteral.h index 33ecee31e5..6da9afd24d 100644 --- a/Source/Core/Common/StringLiteral.h +++ b/Source/Core/Common/StringLiteral.h @@ -5,6 +5,8 @@ #include +namespace Common +{ // A useful template for passing string literals as arguments to templates // from: https://ctrpeach.io/posts/cpp20-string-literal-template-parameters/ template @@ -14,3 +16,5 @@ struct StringLiteral char value[N]; }; + +} // namespace Common diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index f49261483d..1f627705e9 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -132,7 +132,7 @@ static thread_local bool tls_is_gpu_thread = false; static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi); -static EventHook s_frame_presented = AfterPresentEvent::Register( +static Common::EventHook s_frame_presented = AfterPresentEvent::Register( [](auto& present_info) { const double last_speed_denominator = g_perf_metrics.GetLastSpeedDenominator(); // The denominator should always be > 0 but if it's not, just return 1 diff --git a/Source/Core/Core/FifoPlayer/FifoRecorder.h b/Source/Core/Core/FifoPlayer/FifoRecorder.h index 6c26ba5934..c0a1845471 100644 --- a/Source/Core/Core/FifoPlayer/FifoRecorder.h +++ b/Source/Core/Core/FifoPlayer/FifoRecorder.h @@ -76,5 +76,5 @@ private: std::vector m_Ram; std::vector m_ExRam; - EventHook m_end_of_frame_event; + Common::EventHook m_end_of_frame_event; }; diff --git a/Source/Core/VideoBackends/D3D/D3DGfx.h b/Source/Core/VideoBackends/D3D/D3DGfx.h index 8bbf998e36..853599224c 100644 --- a/Source/Core/VideoBackends/D3D/D3DGfx.h +++ b/Source/Core/VideoBackends/D3D/D3DGfx.h @@ -16,7 +16,7 @@ class SwapChain; class DXTexture; class DXFramebuffer; -class Gfx : public ::AbstractGfx +class Gfx final : public ::AbstractGfx { public: Gfx(std::unique_ptr swap_chain, float backbuffer_scale); diff --git a/Source/Core/VideoBackends/Metal/MTLGfx.h b/Source/Core/VideoBackends/Metal/MTLGfx.h index a7d5e170b6..22795a0183 100644 --- a/Source/Core/VideoBackends/Metal/MTLGfx.h +++ b/Source/Core/VideoBackends/Metal/MTLGfx.h @@ -69,7 +69,6 @@ public: void BindBackbuffer(const ClearColor& clear_color = {}) override; void PresentBackbuffer() override; - // Returns info about the main surface (aka backbuffer) SurfaceInfo GetSurfaceInfo() const override; private: diff --git a/Source/Core/VideoBackends/Vulkan/VKGfx.h b/Source/Core/VideoBackends/Vulkan/VKGfx.h index 8217533f06..bc254874fd 100644 --- a/Source/Core/VideoBackends/Vulkan/VKGfx.h +++ b/Source/Core/VideoBackends/Vulkan/VKGfx.h @@ -19,7 +19,7 @@ class VKFramebuffer; class VKPipeline; class VKTexture; -class VKGfx : public ::AbstractGfx +class VKGfx final : public ::AbstractGfx { public: VKGfx(std::unique_ptr swap_chain, float backbuffer_scale); @@ -77,7 +77,6 @@ public: void SetFullscreen(bool enable_fullscreen) override; bool IsFullscreen() const override; - // Returns info about the main surface (aka backbuffer) virtual SurfaceInfo GetSurfaceInfo() const override; // Completes the current render pass, executes the command buffer, and restores state ready for diff --git a/Source/Core/VideoCommon/FrameDumper.h b/Source/Core/VideoCommon/FrameDumper.h index cdf6d9359d..859a4140e3 100644 --- a/Source/Core/VideoCommon/FrameDumper.h +++ b/Source/Core/VideoCommon/FrameDumper.h @@ -98,7 +98,7 @@ private: std::mutex m_screenshot_lock; std::string m_screenshot_name; - EventHook m_frame_end_handle; + Common::EventHook m_frame_end_handle; }; extern std::unique_ptr g_frame_dumper; diff --git a/Source/Core/VideoCommon/FramebufferManager.h b/Source/Core/VideoCommon/FramebufferManager.h index 087c5023aa..7921a70d41 100644 --- a/Source/Core/VideoCommon/FramebufferManager.h +++ b/Source/Core/VideoCommon/FramebufferManager.h @@ -238,7 +238,7 @@ protected: std::vector m_color_poke_vertices; std::vector m_depth_poke_vertices; - EventHook m_end_of_frame_event; + Common::EventHook m_end_of_frame_event; }; extern std::unique_ptr g_framebuffer_manager; diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h index 9115d8f45d..ed0063444a 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModManager.h @@ -54,7 +54,7 @@ private: std::unordered_set m_groups; - EventHook m_end_of_frame_event; + Common::EventHook m_end_of_frame_event; }; extern std::unique_ptr g_graphics_mod_manager; diff --git a/Source/Core/VideoCommon/ShaderCache.h b/Source/Core/VideoCommon/ShaderCache.h index f0982b3104..809ebb23eb 100644 --- a/Source/Core/VideoCommon/ShaderCache.h +++ b/Source/Core/VideoCommon/ShaderCache.h @@ -252,7 +252,7 @@ private: // Texture decoding shaders std::map, std::unique_ptr> m_texture_decoding_shaders; - EventHook m_frame_end_handler; + Common::EventHook m_frame_end_handler; }; } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Statistics.cpp b/Source/Core/VideoCommon/Statistics.cpp index ecca851968..231bb470b4 100644 --- a/Source/Core/VideoCommon/Statistics.cpp +++ b/Source/Core/VideoCommon/Statistics.cpp @@ -18,10 +18,10 @@ Statistics g_stats; -static EventHook s_before_frame_event = +static Common::EventHook s_before_frame_event = BeforeFrameEvent::Register([] { g_stats.ResetFrame(); }, "Statistics::ResetFrame"); -static EventHook s_after_frame_event = AfterFrameEvent::Register( +static Common::EventHook s_after_frame_event = AfterFrameEvent::Register( [] { DolphinAnalytics::PerformanceSample perf_sample; perf_sample.speed_ratio = SystemTimers::GetEstimatedEmulationPerformance(); diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index ce14075552..8b5e56af37 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -780,10 +780,10 @@ void TextureCacheBase::OnFrameEnd() // Flush any outstanding EFB copies to RAM, in case the game is running at an uncapped frame // rate and not waiting for vblank. Otherwise, we'd end up with a huge list of pending // copies. - g_texture_cache->FlushEFBCopies(); + FlushEFBCopies(); } - g_texture_cache->Cleanup(g_presenter->FrameCount()); + Cleanup(g_presenter->FrameCount()); } void TCacheEntry::DoState(PointerWrap& p) diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index c38f2578b9..958d7704fe 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -123,8 +123,8 @@ struct TCacheEntry bool is_efb_copy = false; bool is_custom_tex = false; bool may_have_overlapping_textures = true; - bool has_arbitrary_mips = false; // indicates that the mips in this texture are arbitrary - // content, aren't just downscaled + // indicates that the mips in this texture are arbitrary content, aren't just downscaled + bool has_arbitrary_mips = false; bool should_force_safe_hashing = false; // for XFB bool is_xfb_copy = false; bool is_xfb_container = false; @@ -438,7 +438,8 @@ private: void OnFrameEnd(); Common::Flag m_force_reload_textures; - EventHook m_frame_event = AfterFrameEvent::Register([this] { OnFrameEnd(); }, "TextureCache"); + Common::EventHook m_frame_event = + AfterFrameEvent::Register([this] { OnFrameEnd(); }, "TextureCache"); }; extern std::unique_ptr g_texture_cache; diff --git a/Source/Core/VideoCommon/VertexManagerBase.h b/Source/Core/VideoCommon/VertexManagerBase.h index 18e0f1d402..775d8e2787 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.h +++ b/Source/Core/VideoCommon/VertexManagerBase.h @@ -230,7 +230,7 @@ private: std::vector m_scheduled_command_buffer_kicks; bool m_allow_background_execution = true; - EventHook m_frame_end_event; + Common::EventHook m_frame_end_event; }; extern std::unique_ptr g_vertex_manager; diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index dfbc0d3952..38ee680bf3 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -355,5 +355,5 @@ void CheckForConfigChanges() // TODO: Move everything else to the ConfigChanged event } -static EventHook s_check_config_event = +static Common::EventHook s_check_config_event = AfterFrameEvent::Register([] { CheckForConfigChanges(); }, "CheckForConfigChanges"); diff --git a/Source/Core/VideoCommon/VideoEvents.h b/Source/Core/VideoCommon/VideoEvents.h index a2e0760075..57d44cbe59 100644 --- a/Source/Core/VideoCommon/VideoEvents.h +++ b/Source/Core/VideoCommon/VideoEvents.h @@ -7,16 +7,16 @@ #include "Common/EventHook.h" // Called when certain video config setting are changed -using ConfigChangedEvent = Event<"ConfigChanged", u32>; +using ConfigChangedEvent = Common::Event<"ConfigChanged", u32>; // An event called just before the first draw call of a frame -using BeforeFrameEvent = Event<"BeforeFrame">; +using BeforeFrameEvent = Common::Event<"BeforeFrame">; // An event called after the frame XFB copy begins processing on the host GPU. // 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 = Event<"AfterFrame">; +using AfterFrameEvent = Common::Event<"AfterFrame">; struct PresentInfo { @@ -76,8 +76,8 @@ struct PresentInfo // frame. // // frame_count: The number of frames -using BeforePresentEvent = Event<"BeforePresent", PresentInfo&>; +using BeforePresentEvent = Common::Event<"BeforePresent", PresentInfo&>; // An event that is triggered after a frame is presented. // The exact timing of this event depends on backend/driver support. -using AfterPresentEvent = Event<"AfterPresent", PresentInfo&>; +using AfterPresentEvent = Common::Event<"AfterPresent", PresentInfo&>; diff --git a/Source/Core/VideoCommon/Widescreen.h b/Source/Core/VideoCommon/Widescreen.h index 78430ca9bf..c8dc5847ec 100644 --- a/Source/Core/VideoCommon/Widescreen.h +++ b/Source/Core/VideoCommon/Widescreen.h @@ -27,8 +27,8 @@ private: bool m_is_game_widescreen = false; bool m_was_orthographically_anamorphic = false; - EventHook m_update_widescreen; - EventHook m_config_changed; + Common::EventHook m_update_widescreen; + Common::EventHook m_config_changed; }; extern std::unique_ptr g_widescreen;