In the reference documentation for
glfwMakeContextCurrent, it mentions the following:
When moving a context between threads, you must make it non-current on the old thread before making it current on the new one.
How should this be done? I’m not sure how to do this other than just calling
glfwMakeContextCurrent on the thread I’d like to render on, making sure it’s not called on another thread while the rendering is happening.
Hi @bmitc welcome to the GLFW forum.
To make the context non-current on the old thread call
glffMakeContextCurrent(NULL); as per the documentation:
[in] window The window whose context to make current, or
NULL to detach the current context.
Oh, goodness. I’m not sure how I missed that. I’ve been reading the documentation a lot, but I just plain missed it. Part of it maybe that I’m using F# for my windowing and GUI library, with bindings to GLFW, so I don’t think in
null a lot. Haha.
Thank you for the quick response! And I am in general really impressed with the documentation. It’s honestly refreshing, especially for such a low-level library, to have documentation that I can just read to figure out how things work instead of guessing.
A couple of follow-ups on this though.
I haven’t been making the current context non-current before another window making its context current. This hasn’t seem to have caused any issues. Have I just been lucky? I’ll certainly do it moving forward.
Regarding the architecture of when to make the current context non-current, should I just make it non-current when I’m done swapping buffers?
So I think I just answered (1) for myself. Currently, I am not making context’s current across threads. Although I have multiple windows being managed, everything is currently single threaded. However, I am starting to move towards a multi-threaded environment such that the rendering occurs in separate threads for each window. This is my attempt to support both GUI-like windows that should wait on events and animation-like windows that may want to poll or request updates rather than waiting on events. (I’m going to ask in another thread about that architecture design.)
I think question (2) still remains, but I’ll need some thread synchronization management to ensure that only one thread is making its context current at a time and then releases its context before another thread makes its context current.
How you handle (2) is going to very much depend on your application’s architecture, so it’s difficult to answer. If you simply want to run separate threads for each window’s rendering then you might only need to create the windows on the main thread and then make the context current on the window’s render thread since a window is created with it’s context non-current.
If you simply want to run separate threads for each window’s rendering then you might only need to create the windows on the main thread and then make the context current on the window’s render thread since a window is created with it’s context non-current.
I think that’s what I want to do. I’m going to keep playing with this, and I may make a follow-up post to get some feedback on how to handle GUI plus animation windows in the same application. I am making a GUI framework and want to support something like Processing, where one window may be a traditional GUI window with editor like functionality (thus, waits on events) and another window may be an animation window (thus, wants frequent updates and thus polling).
But just to be sure I understand the current context: when I want to render a window, I should make its context current, render, swap buffers, and then make its context non-current, making sure that this entire render process does not overlap with another window’s render process?
You don’t have to make the context non-current unless you intent to make another context current or use this context on another thread.
You can overlap render processes for different windows as they will have different contexts.
Thank you @dougbinks! I indeed kept messing up the fact that every window gets its own unique context. Thank you for re-clarifying that. Apologies for the late delay, but I was just working on all of this with the feedback and more reading to make sure I was getting it.
I got all this working where the window management happens on the main thread, and then every window gets its own rendering thread. However, since moving the rendering to its own thread for a given window, I am having some unexplained flickering issues when resizing (as if the canvas I’m drawing to moves), but I’m going to make a new post for that. It’s confusing behavior for sure!