Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
anszom opened this issue Mar 18, 2024 · 2 comments
Open

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

anszom opened this issue Mar 18, 2024 · 2 comments

Comments

@anszom
Copy link

anszom commented Mar 18, 2024

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

@ocornut
Copy link
Owner

ocornut commented Mar 19, 2024

Hello, please note that I haven't checked yet as objC is entirely foreign to me, but could this be related to #7393 and #6528 ?

@anszom
Copy link
Author

anszom commented Mar 19, 2024

My experience with osx is quite limited, but I think these issues are not directly related.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants