Skip to content

imgui_impl_metal: resource leak when using thread-local GImGui #7419

@anszom

Description

@anszom

Version/Branch of Dear ImGui:

git commit 9a5da23, but the code is the same on master

Back-ends:

imgui_impl_metal.cpp + custom platform backend

Compiler, OS:

macOS + Clang 14

Full config/build information:

No response

Details:

My Issue/Question:

I'm using multiple ImGui contexts within a single application, with a thread_local GImGui pointer, as described in imgui.cpp:

struct ImGuiContext;
extern thread_local ImGuiContext* GImGui_tls;
#define GImGui GImGui_tls

I'm observing a significant memory leak with the Metal backend. I've traced it down to the buffers allocated in dequeueReusableBufferOfLength:device:. The asynchronous callback responsible for releasing the buffers is running on a thread without any ImGui context active, therefore the buffers are never released.

I suggest the following changes to fix the problem.

diff --git a/3rdparty/imgui/imgui_impl_metal.mm b/3rdparty/imgui/imgui_impl_metal.mm
index 23870f37..1206187a 100644
--- a/3rdparty/imgui/imgui_impl_metal.mm
+++ b/3rdparty/imgui/imgui_impl_metal.mm
@@ -310,17 +310,14 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
         indexBufferOffset += (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
     }
 
+    __block MetalContext* SharedMetalContext = bd->SharedMetalContext;
     [commandBuffer addCompletedHandler:^(id<MTLCommandBuffer>)
     {
         dispatch_async(dispatch_get_main_queue(), ^{
-            ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
-            if (bd != nullptr)
+            @synchronized(SharedMetalContext.bufferCache)
             {
-                @synchronized(bd->SharedMetalContext.bufferCache)
-                {
-                    [bd->SharedMetalContext.bufferCache addObject:vertexBuffer];
-                    [bd->SharedMetalContext.bufferCache addObject:indexBuffer];
-                }
+                [SharedMetalContext.bufferCache addObject:vertexBuffer];
+                [SharedMetalContext.bufferCache addObject:indexBuffer];
             }
         });
     }];

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

No response

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions