-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
How to multithreading? #8550
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
Comments
In general terms (main lib) nothing ever changed. Dear ImGui function may not be run in parallel for the same context.
Specifically about the OSX backend: I personally don't know/understand how it works. So I encourage you to use git blame to find trace of why things were changed, and we can advise if there an improvement to make.
It should be thread_local if you want to create multiple contexts and access them from different thread (with 1 context per thread) but this doesn't seem like what you are describing below. Do you have multiple contexts? If you don't the regular global variable is enough. As per your setup the correct answer depends on details you haven't provided. What do want to to do in each and at which point do they overlap aka call ImGui code for the same context simultaneously? It's hard to understand what your "Render context" mean if it calls For the render thread if you need to render output for frame N while the context is already processing a subsequent frame, you may want to extract the ImDrawData as in #8532 but again I am not sure if that's part of your problem or not. |
Thank you for your response. I'll provide some more details which hopefully clears it up a bit. I am not trying to share contexts for parallel usage on multiple threads. Instead, i'm trying to do as suggested, only access a context from a single thread. This is impossible with the macos backend because it contains a ImGuiObserver that is called from the event pump running on the main thread. The implementation inside ImGuiObserver accesses GImGui directly. This changes things from Use one context per thread to You can only have a single context and everything must happen on the main thread. This is because at any point the main thread may require access to the context, so at no point another thread may have access to it. Imagine this:
This setup requires GImGui to be thread_local. Once i change that, no context was ever active on the main thread. The instance of GImGui is still null on the main thread. When the ImGuiObserver::onApplicationBecomeActive is executed, this runs on the main thread. There is no context there, so it crashes. I have found this commit e66fc22 removed ImGui_ImplOSX_HandleEvent. Previously i was able to provide events manually while providing the NSView. Now how do i do this if the backend's ImGuiObserver handles events and just assumes there's a thread_local instance being set on the main thread? My endgoal is to be able to run UI on all (lets say three) connected displays. These displays may have varying display resolutions as well as framebuffer scales. My current approach is to have one window per display and one ImGuiContext per window. I can then use varying |
We would need to investigate why I made this change (somehow the decision appears to be buried in #4821) and decide on another change to the OSX backend that allows your situation to work while fullfilling whatever reason this change was initially aimed at.
You would be better off using a single context and multi-viewports. You'll probably need a few hacks for framebufferscale support (we have dozens of related open issues until this hopefully is solved in 1.92.x). |
I'm going back to a single (non thread_local) context on a single thread. Should i be able to call |
A naive approach to handling multithreading might be: ensure all ImGui method calls are wrapped within a std::lock_guardstd::mutex scope. |
Why going back? Could you investigate fixing the initial issue by reintroducing the event handler in backend? Please open separate issues for the problem so we can track and fix separately. I wasn’t aware of this IME thing. Does the language somehow magically allows queuing something for the main thread? |
Version/Branch of Dear ImGui:
docking
Back-ends:
imgui_impl_osx.cpp + imgui_impl_vulkan.cpp
Compiler, OS:
appleclang
Full config/build information:
No response
Details:
Where can i find information on how multithreading is expected to work?
I just updated to the latest docking branch, and am confused as to what the new way to do multithreading is now. The macos backend was changed so that applications no longer provide inputs, instead the backend does this on it's own. However, i dont see a way to make it exclusively acquire the context, or activate one for that matter.
imgui.cpp hints that the GImGui member should be thread_local, so i've done that.
On thread 2 (control) i call ImGui::CreateContext(), and then initialize vulkan resources+fonts off of any realtime threads. I need the context later on thread 3 (render/process) so i store the result.
On thread 3 (render) i call ImGui::SetCurrentContext and then ImGui::NewFrame etc.
On thread 1 (main/ui) the ImGuiObserver::onApplicationBecomeActive is called, it calls ImGui::GetIO, but there's no context active so it asserts and reads out of bounds.
Am i supposed to intercept os events and activate the context prior to dispatch it through NSApp sendEvent? If so, then how do i know which context to activate. I might have multiple ones active for multiple windows.
Screenshots/Video:
No response
Minimal, Complete and Verifiable Example code:
The text was updated successfully, but these errors were encountered: