I’m writing a context class which needs to
work with multiple threads. The question is,
for safety, should I initialise the proc
addresses for extensions in each thread as
well as for each gl context.
Since a thread shares the parent processes
address space, I would assume not, but I want this to be as safe/correct as possible.
In practise, so long as all your contexts are opened on the same device, you generally only have to initialise the proc addresses once per process, but I want to make sure.
A quote from the wglGetProcAddress documentation in MSDN:
The extension function addresses are unique for each pixel format. All rendering contexts of a given pixel format share the same extension function addresses.
So, on Windows, you have to get the function pointers for all rendering contexts with their own pixel format. Under Linux glxGetProcAddress, however, returns context-independent function entry points. Note that in either case you still have to make sure the function entry points are actually available by checking the extension string.
from some other spec:
[b]Additions to the WGL Specification[/b]
First, close your eyes and pretend that a WGL specification actually
existed. Maybe if we all concentrate hard enough, one will magically
So, close your eyes, and don’t treat MSDN’s WGL too seriously (if it was serious, we would have gl1.4 on windows). Pretend the restriction actually not existed, and your app will be magically working fine.
[This message has been edited by MZ (edited 02-05-2003).]
Does it matter what function address it is. I think it will be the same for all threads that use the same vendor/renderer (?). I am under the impression that per thread context selection is not done using different function entry points, but by the functions themselves.
Mesa3D uses POSIX thread specific keys (equivalent to Win32 thread local storage) to determine which context to use for each thread. I would imagine that most GL implementations do something similar.
OpenGL is not thread-safe. That means, you can use OpenGL only in the thread that created the context. Therefore i don´t know how one can use OpenGL calls in more than one thread.
I had the same problem. When i called a gl function from my rendering thread it was ok, but when i did it from my other thread, it either didn´t work at all, or it crashed.
However i found quite an easy solution. I created a messaging system. Now when i want to change a state or so, i send a message to the responsible class. Everytime my rendering thread runs, it updates all objects, which means, they process all messages that have been sent to them.
This way i can execute gl commands even from other threads, without much effort.
And i don´t have the problem wether i have to initialize function pointers in every thread
Maybe you want to use a similar approach.
I have no problems rendering to separate OpenGL contexts from different threads. This can be a performance issue since N contexts accessing one device is going to have the overhead of flushing the OpenGL pipeline each time the system switches between the threads.
The limitation that is documented in the excellent MSDN docs is that a context can only be current in one thread at a time, which implies that you can make a context current in different threads, just not at the same time.
You have to be careful with rendering to pbuffers and using that as a read source or texture source for another context in a different thread. Some simple locking usually suffices to avoid such problems.
If you set up a context in one thread, and then use it in another thread, do you have to re-init your proc addrs. I’ve had no problems when not doing this, but wanted to check if it was safe.
Your message passing idea is interesting but my class needs to be a small generic drop-in, so I don’t want to have to maintain a seperate thread in the class, and I don’t want to bind the programmer to use a message queue (although such a thing combined with state sorting can be very fast).
Thanks for all your replies.
Originally posted by Jan2000:
OpenGL is not thread-safe. That means, you can use OpenGL only in the thread that created the context.
OpenGL IS thread safe. Just as News said, it’s just a question about exclusive access for a thread to each context. You can’t wglMakeCurrent on a single context from two threads at the same time.
Regarding function pointers and GetProcAddress, I strongly suspect that all threads use the same entry point. If you link statically with opengl32.lib, you get the same DLL entry point, regardless of which thread you’re calling from, right? It must be the same thing with GetProcAddress. I think they have to resolve which context is current (for the calling thread) for each gl function call.
OpenGL IS thread safe - of course it is. Jeez.
Originally posted by marcus256:
Regarding function pointers and GetProcAddress, I strongly suspect that all threads use the same entry point. If you link statically with opengl32.lib, you get the same DLL entry point, regardless of which thread you’re calling from, right? It must be the same thing with GetProcAddress.
When all the contexts use the same pixel format, then the addresses obtained with wglGetProcAddress is identical, but otherwise it’s not guaranteed that it will be identical.
As for GetProcAddress, it’s reasonable to assume you always get the same addresses but I dont know for sure.
I think they have to resolve which context is current (for the calling thread) for each gl function call.
This shouldn’t be hard to do, since your window will have an associated current RC. It would be intersting to know what exactly goes on behind the scene.