Any difference between the main thread and other threads?

The GLFW FAQ , paragraph 2.9 states:

[...] it is highly recommended that all OpenGL and GLFW calls (except for flow control and synchronization calls) are made from the main thread , which should not be a big problem since only one window is supported. This method is also compatible with the future direction of GLFW.

The emphasis is mine.

So what is the difference between main thread and other threads?

+4
source share
2 answers

Statement

"Is ... thread safe? No. However, OpenGL is not."

wrong. OpenGL, of course, is thread safe.

Here's the deal: for each thread, either one or no context OpenGL can be tied to drawable (made current). OpenGL calls work in a context that is active in the thread from which the calls are made. It is possible to pass an OpenGL context between threads. For this, the context that needs to be transferred must be disconnected, then it can be a rebound in another thread.

Each OpenGL context manages its own set of state variables and objects (textures, buffers). However, the context may be "confused", i.e. Separate the space of objects. However, the state is still individual.

A single draw (window, PBuffer) can have several contexts from different flows to which it is attached. If contexts from different threads refer to the same conditions derived from the race condition, and the results are undefined. However, in the case of checking the depth, the result should be reasonable. However, simultaneous drawing on one drawing will greatly degrade performance, so it is better to avoid it.

The main use of multiple OpenGL contexts in multiple threads is to share their objects so that one thread can load and update data for another context. It makes sense to attach helper contexts to screens or hidden drawings to prevent race conditions.

There is no technical difference between the threads. From a programming point of view, each thread will have slightly different semantics that are superimposed by the program, not the system. For most OpenGL applications, the traditional semantics is that the main thread will create a window, draw all the elements visible to the user (including OpenGL operations), and collect user input. Threads launched from the main thread are workflows without direct user interaction. However, the distribution of this task is purely optional and because it turned out to work well. But it is quite possible, and sometimes advisable, to use a different scheme. And, as already mentioned, there is no technical difference in the flows within the program. All topics are citizens with equal rights in the process.

+5
source

The documentation may have been framed in a somewhat misleading manner. Best wording:

It is strongly recommended that all OpenGL and GLFW calls (with the exception of thread control and synchronization calls) be made from the same thread, preferably the same one that called glfwInit and glfwOpenWindow , which should not be a big problem since only one window is supported. This method is also compatible with the future direction of GLFW.

The reason for this is that OpenGL has the concept of a "current thread" for its contexts, which is the only thread that can legitimately modify or use this context at a given time. The context originally belongs to the thread that created it. You can make it “current” in some other thread by calling wglMakeCurrent or glxMakeCurrent , which, unlike GLFW, is not portable (but there may be a wrapper for GLFW for this, I'm not sure).

Of course, it is quite possible to have several independent contexts, and you can access the same context from several threads by making the same context in each thread before using it. And finally, you can have multiple contexts in multiple threads that share state.
However, none of these options is a common case, as it either includes unsafe synchronization overhead or is not suitable for general use of OpenGL. Any other thing than “one thread, one context”, as a rule, with very few exceptions, gives no advantages, but comes with unnecessary complexity.

Therefore, the regular case should have exactly one context that is used by exactly one thread, and possibly some working triads that help shuffle data into mapped buffers.

As for the “main stream” and “any stream”, there is no difference. The main thread is just occasionally the one that most of the time initializes GLFW (and therefore OpenGL).

+4
source

All Articles