X Display Connections across threads and OpenGL Components


#1

OK, so following on posts about XInitThreads and OpenGl components used multi-threaded, here’s the upshot.

X Display Connections really aren’t thread safe, even with XInitThreads correctly initializing. They won’t crash if used across threads, but will throw a lot of std out messages and warnings, and hang on exit.

Meanwhile, a GLX context (OpenGL on Linux) created on one display connection will only work with that same connection.

The built-in OpenGLComponent is hard-wired to use the global display connection. This is fine and probably correct for normal use, but if you start to use the context on another thread, bad things start to happen.

So - I can skip the built-in component, which is sad as it works well and plays well with others, or try to patch it for Linux use, which will involve changes in Linux_Windowing.cpp that may apply to the OpenGLComponent. In essence, anything that will be used in a thread needs it’s own Display Connection, and possibly the connection needs to be protected. Any thoughts?

Bruce


#2

i think you’re right about X11 and thread (un)safety. That’s why also juce hangs when using xcb (which claims to be thread safe) as transport layer mainly cause the linux_Windowing follows the old thread unsafe X11 methodology.

We might consider writing a more decent and up to date version of the windowing code for xcb, but apart me… which other dev out there can join the effort ? That should clean any problem regarding thread safety and locking problems.


#3

Well, I’ve been mulling about how to fix this, such as doing a special case for the OpenGLContext in a thread, but there’s more problems than that, for instance I get a lot of problems from stuff like ‘isMinimized’ that uses a display connection.

Jules, is it feasible to do multi-threaded OpenGL components in Juce, really? Since this a a side feature, should I just abandon it and use my own class?

Is there a lightweight equivalent juce class that will appear to be in the component hierarchy but not do any system calls?

Bruce


#4

Tricky question… I guess it’s fine on windows and mac, but if X is causing this kind of nonsense, then I don’t know…


#5

It works for me on Mac, haven’t really tried my app on Win for a long time.

The X display connections are a real pain. If you wanted to say that on Linux, the OpenGL Component can’t be used across threads, that’s the way it is. If you had a strong feeling that you want it to work, then that would be good too, but it might be quite a job.

Is there a way for me to get Component ‘events’ but do all my own windowing stuff?

Bruce


#6

I’d like to be able to make it work, but it sounds like a can of worms.

Not sure exactly what you mean about doing your own windowing, but you could of course use a custom ComponentPeer.


#7

ComponentPeer? Yeah, that sounds like it. What I mean is that I need to make sure that no X window calls are made, so I will need to not add the component to the desktop.

If you wanted to fill it in, you’d have to find any code path that the OpenGLComponent could get to any X lib calls and check the thread. If the main thread and not OpenGL related then using the main connection would be fine. Anything touching OpenGL would have to protect a separate display connection - probably using the same context lock, and should all be on the same thread. I found that creating a context on one thread and using on another was tricky, and that creating on one display connection and using on another just doesn’t work.

Meanwhile, this is all using NVidia closed drivers and GLlib and a fairly new X Org. It will probably all be different with other combos!

Bruce