From ea43d656361174ae729e8956bd153a4dbeb2ee55 Mon Sep 17 00:00:00 2001 From: srkizer Date: Thu, 15 Feb 2024 07:52:40 +0900 Subject: [PATCH] Fix memory ownership on AddFontFromImGuiHeapAllocatedMemory (#1651) --- .../FontAtlasFactory.BuildToolkit.cs | 19 ++++++++++++++++++- .../FontAtlasFactory.Implementation.cs | 6 ++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs index 396c8b26a..a57e6d036 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs @@ -185,6 +185,7 @@ internal sealed partial class FontAtlasFactory dataSize, debugTag); + var font = default(ImFontPtr); try { fontConfig.ThrowOnInvalidValues(); @@ -192,6 +193,7 @@ internal sealed partial class FontAtlasFactory var raw = fontConfig.Raw with { FontData = dataPointer, + FontDataOwnedByAtlas = 1, FontDataSize = dataSize, }; @@ -203,7 +205,7 @@ internal sealed partial class FontAtlasFactory TrueTypeUtils.CheckImGuiCompatibleOrThrow(raw); - var font = this.NewImAtlas.AddFont(&raw); + font = this.NewImAtlas.AddFont(&raw); var dataHash = default(HashCode); dataHash.AddBytes(new(dataPointer, dataSize)); @@ -240,8 +242,23 @@ internal sealed partial class FontAtlasFactory } catch { + if (!font.IsNull()) + { + // Note that for both RemoveAt calls, corresponding destructors will be called. + + var configIndex = this.data.ConfigData.FindIndex(x => x.DstFont == font.NativePtr); + if (configIndex >= 0) + this.data.ConfigData.RemoveAt(configIndex); + + var index = this.Fonts.IndexOf(font); + if (index >= 0) + this.Fonts.RemoveAt(index); + } + + // ImFontConfig has no destructor, and does not free the data. if (freeOnException) ImGuiNative.igMemFree(dataPointer); + throw; } } diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs index 4968bc891..883fcbbfc 100644 --- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs +++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.Implementation.cs @@ -46,6 +46,9 @@ internal sealed partial class FontAtlasFactory private class FontAtlasBuiltData : IRefCountable { + // Field for debugging. + private static int numActiveInstances; + private readonly List wraps; private readonly List substances; @@ -73,6 +76,9 @@ internal sealed partial class FontAtlasFactory this.Garbage.Add(() => ImGuiNative.ImFontAtlas_destroy(atlasPtr)); this.IsBuildInProgress = true; + + Interlocked.Increment(ref numActiveInstances); + this.Garbage.Add(() => Interlocked.Decrement(ref numActiveInstances)); } catch {