From 07c5fe013c140221760ce9599a25846de9068cbf Mon Sep 17 00:00:00 2001 From: meli <57847713+ff-meli@users.noreply.github.com> Date: Sun, 12 Jan 2020 08:13:50 -0800 Subject: [PATCH 1/4] Remove renderdoc debug helpers --- Dalamud/Interface/InterfaceManager.cs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs index 96c49d856..2bbf4474f 100644 --- a/Dalamud/Interface/InterfaceManager.cs +++ b/Dalamud/Interface/InterfaceManager.cs @@ -1,5 +1,3 @@ -//#define RENDERDOC_HACKS - using System; using System.Runtime.InteropServices; using Dalamud.Game; @@ -27,20 +25,6 @@ namespace Dalamud.Interface { public class InterfaceManager : IDisposable { -#if RENDERDOC_HACKS - [DllImport("user32.dll", SetLastError = true)] - static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - - [DllImport("RDocHelper.dll")] - static extern IntPtr GetWrappedDevice(IntPtr window); - - [DllImport("RDocHelper.dll")] - static extern void StartCapture(IntPtr device, IntPtr window); - - [DllImport("RDocHelper.dll")] - static extern uint EndCapture(); -#endif - [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate IntPtr PresentDelegate(IntPtr swapChain, uint syncInterval, uint presentFlags); @@ -98,13 +82,7 @@ namespace Dalamud.Interface { if (this.scene == null) { -#if RENDERDOC_HACKS - var hWnd = FindWindow(null, "FINAL FANTASY XIV"); - var device = GetWrappedDevice(hWnd); - this.scene = new RawDX11Scene(device, swapChain); -#else this.scene = new RawDX11Scene(swapChain); -#endif this.scene.OnBuildUI += HandleMouseUI; this.ReadyToDraw?.Invoke(this, null); } From 92b7482e87247824c86b0c73099389f1e68644eb Mon Sep 17 00:00:00 2001 From: meli <57847713+ff-meli@users.noreply.github.com> Date: Sun, 12 Jan 2020 08:16:12 -0800 Subject: [PATCH 2/4] Simplify draw delegate handling --- Dalamud/Dalamud.cs | 2 +- Dalamud/Interface/InterfaceManager.cs | 28 +++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index 78591c0b3..02f24244e 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -85,7 +85,7 @@ namespace Dalamud { this.WinSock2 = new WinSockHandlers(); this.InterfaceManager = new InterfaceManager(this.sigScanner); - this.InterfaceManager.ReadyToDraw += (sender, args) => this.InterfaceManager.OnBuildUi += BuildDalamudUi; + this.InterfaceManager.OnDraw += BuildDalamudUi; this.InterfaceManager.Enable(); try { diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs index 2bbf4474f..67b83f184 100644 --- a/Dalamud/Interface/InterfaceManager.cs +++ b/Dalamud/Interface/InterfaceManager.cs @@ -37,13 +37,7 @@ namespace Dalamud.Interface /// /// This event gets called when ImGUI is ready to draw your UI. /// - public event RawDX11Scene.BuildUIDelegate OnBuildUi - { - add => this.scene.OnBuildUI += value; - remove => this.scene.OnBuildUI -= value; - } - - public EventHandler ReadyToDraw; + public event RawDX11Scene.BuildUIDelegate OnDraw; public InterfaceManager(SigScanner scanner) { @@ -83,8 +77,7 @@ namespace Dalamud.Interface if (this.scene == null) { this.scene = new RawDX11Scene(swapChain); - this.scene.OnBuildUI += HandleMouseUI; - this.ReadyToDraw?.Invoke(this, null); + this.scene.OnBuildUI += Display; } this.scene.Render(); @@ -92,14 +85,25 @@ namespace Dalamud.Interface return this.presentHook.Original(swapChain, syncInterval, presentFlags); } - private void HandleMouseUI() + private void Display() { // this is more or less part of what reshade/etc do to avoid having to manually // set the cursor inside the ui - // This effectively means that when the ui is hovered, there will be 2 cursors - - // the normal one from the game, and the one for ImGui + // This will just tell ImGui to draw its own software cursor instead of using the hardware cursor + // The scene internally will handle hiding and showing the hardware (game) cursor + // If the player has the game software cursor enabled, we can't really do anything about that and + // they will see both cursors. // Doing this here because it's somewhat application-specific behavior ImGui.GetIO().MouseDrawCursor = ImGui.GetIO().WantCaptureMouse; + + // invoke all our external ui handlers, giving each a custom id to prevent name collisions + // because ImGui control names are globally shared + foreach (var del in this.OnDraw?.GetInvocationList()) + { + //ImGui.PushID(someId); + del.DynamicInvoke(); + //ImGui.PopID(); + } } } } From 14b2fc09abfae47902252563099f35050b1b6d20 Mon Sep 17 00:00:00 2001 From: meli <57847713+ff-meli@users.noreply.github.com> Date: Sun, 12 Jan 2020 08:18:03 -0800 Subject: [PATCH 3/4] Hack: prevent frequent crashes on unload. This is not a great way to handle the problem, but it should also virtually always succeed... and it's far better than the current crashing behavior, until we can come up with something cleaner. --- Dalamud/Dalamud.cs | 2 ++ Dalamud/Interface/InterfaceManager.cs | 27 ++++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Dalamud/Dalamud.cs b/Dalamud/Dalamud.cs index 02f24244e..bffe6a405 100644 --- a/Dalamud/Dalamud.cs +++ b/Dalamud/Dalamud.cs @@ -140,6 +140,8 @@ namespace Dalamud { } public void Dispose() { + this.InterfaceManager.Dispose(); + Framework.Dispose(); this.BotManager.Dispose(); diff --git a/Dalamud/Interface/InterfaceManager.cs b/Dalamud/Interface/InterfaceManager.cs index 67b83f184..f134275d3 100644 --- a/Dalamud/Interface/InterfaceManager.cs +++ b/Dalamud/Interface/InterfaceManager.cs @@ -10,15 +10,12 @@ using Serilog; // general dev notes, here because it's easiest /* * - Hooking ResizeBuffers seemed to be unnecessary, though I'm not sure why. Left out for now since it seems to work without it. - * - It's probably virtually impossible to remove the present hook once we set it, which again may lead to crashes in various situations. * - We may want to build our ImGui command list in a thread to keep it divorced from present. We'd still have to block in present to * synchronize on the list and render it, but ideally the overall delay we add to present would then be shorter. This may cause minor * timing issues with anything animated inside ImGui, but that is probably rare and may not even be noticeable. * - Our hook is too low level to really work well with debugging, as we only have access to the 'real' dx objects and not any * that have been hooked/wrapped by tools. - * - ^ May actually mean that we bypass things like reshade through sheer luck... but that may also mean that we'll have to do extra - * work to play nicely with them. - * - Might need to render to a separate target and composite, especially with reshade etc in the mix. + * - Might eventually want to render to a separate target and composite, especially with reshade etc in the mix. */ namespace Dalamud.Interface @@ -56,19 +53,35 @@ namespace Dalamud.Interface public void Enable() { this.presentHook.Enable(); + + if (this.scene != null) + { + this.scene.Enable(); + } } public void Disable() { this.presentHook.Disable(); + + if (this.scene != null) + { + this.scene.Disable(); + } } public void Dispose() { + // HACK: this is usually called on a separate thread from PresentDetour (likely on a dedicated render thread) + // and if we aren't already disabled, disposing of the scene and hook can frequently crash due to the hook + // being disposed of in this thread while it is actively in use in the render thread. + // This is a terrible way to prevent issues, but should basically always work to ensure that all outstanding + // calls to PresentDetour have finished (and Disable means no new ones will start), before we try to cleanup + // So... not great, but much better than constantly crashing on unload + this.Disable(); + System.Threading.Thread.Sleep(100); + this.scene.Dispose(); - // this will almost certainly crash or otherwise break - // we might be able to mitigate it by properly cleaning up in the detour first - // and essentially blocking until that completes... but I'm skeptical that would work either this.presentHook.Dispose(); } From aac9e3a4855db82d9dc7a49fe238c9232d1ecaa5 Mon Sep 17 00:00:00 2001 From: meli <57847713+ff-meli@users.noreply.github.com> Date: Sun, 12 Jan 2020 08:21:23 -0800 Subject: [PATCH 4/4] Pull in ImGuiScene updates --- lib/ImGuiScene | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ImGuiScene b/lib/ImGuiScene index c714c8ad1..04bd99314 160000 --- a/lib/ImGuiScene +++ b/lib/ImGuiScene @@ -1 +1 @@ -Subproject commit c714c8ad1a677d4476ae81953feddcb4a697ea4c +Subproject commit 04bd99314d74d62b3c6f979aa3ffcc6db33858fd