PDA

View Full Version : Xlib and openGl in multithreading



Rosario Leonardi
01-08-2011, 07:37 PM
The basic X11 program is always something like that


while(end)
{
while(XPending(d)>0){
XNextEvent(d, &event);
event management(event);
}
renderScene();
glXSwapBuffers()
}

this works, but the manage event can be slow and freeze for some time the render.
What I'm trying to do is to decouple event management and rendering in two threads.
Thread1


while(true){
renderScene()
glXSwapBuffers()
}

Thread2


while(end)
{
XNextEvent(d, &event);
manageEvent(event);
}

In this way the thread two will wait for event (and don't need polling) while the thread one will render the scene without freeze.
Theoretically.... what's append is that the thread2 is waiting for event and put a lock on the whole Xlib while thread1 is trying to do glXSwapBuffer but the Xlib are locked by thread 2.

There is a solution on this problem?
Thanks.

eile
01-09-2011, 06:04 AM
It should work if you either call XInitThreads() or use a separate Display* connection for each thread.

Alternatively you can use one thread and poll for events using:

while( XPending( display )) { XNextEvent( display, &xEvent ); ...; }

Edit: I just saw that you already do the latter. Why is this slow? Is it your event processing code?

Rosario Leonardi
01-09-2011, 09:54 AM
Thank for the answare, but I'm already using XInitThreads (without it crash).
And using two separate display connection won't works. I have to create the windows using a connection and receiving event in another.


d1 = XOpenDisplay()
d2 = XOpenDisplay()

win = XCreateWindow(d1)
oglCtx = glXCreateContext(d1)
startRenderThread(win, oglCtx)

while(end){
XNextEvent(d2);
manageEvent()
}

This way I'll never receive event from the window.

I'm writing an framework for LUA (lunatic.sourceforge.net), so the manage event will call a lua function. Also cause the whole code is driven by script is not forbidden to create two or more windows.
I'm still making some test to check if this is possible.
Here the whole test code -> http://pastebin.com/ffwktc53

Need the c++0x standard and gcc 4.5 to compile
gcc xthread.cpp -lX11 -lGL -lstdc++ -pthread -std=c++0x -g -o xt

Rosario Leonardi
01-09-2011, 11:19 AM
I have put a usleep(16000) in the render queue and now it works fine event with more windows.
This look like a X11 bugs, I'll try to ask on Xlib mailing list.

Waiting for wayland... >_>

edit: work fine means that I didn't get deadlock, but the problem is not solved

Rosario Leonardi
01-09-2011, 12:13 PM
And here it is the bug still unsolved after more than one year.
http://lists.freedesktop.org/archives/xcb/2009-April/004538.html
https://bugs.freedesktop.org//show_bug.cgi?id=17010

Excellent.. now my application is not thread safe. :-/

Rosario Leonardi
01-09-2011, 02:59 PM
Now using XLib-Xcb work correctly.

http://xcb.freedesktop.org/opengl/

I create the display and the openGl context using Xlib and then wait for the event using XCb. I made some test with 3 concurrent window and everything running smooth.

Who was the one that said "I never found a bug in X"? :D

If someone want more detail I'll write a tutorial on my blog.

eile
01-10-2011, 08:53 AM
And using two separate display connection won't works. I have to create the windows using a connection and receiving event in another.


man XSelectInput

eile
01-10-2011, 09:04 AM
Have you thought about doing the CPU-intensive event processing in a second thread, i.e, doing all X/glX stuff in the main thread and dispatch the work to a second thread?

Rosario Leonardi
01-10-2011, 02:45 PM
Thanks, I didn't know about XSelectInput, I'll give it a try.
Yes, I also thought about running lua in another thread but also LUA is not thread safe too.
Cause is lua that run my code as an extension I have to make a lot of workaround to run the lua code on another thread.

Actually I'm satisfied with the Xcb solution, I'll try the solution with two X connection using XSelectInput

_arts_
01-11-2011, 03:51 AM
I never had such problems with X events.

Can you develop more ? Like, what is your system ? Can you provide a demo of your issue ?

Rosario Leonardi
01-11-2011, 12:44 PM
I get the problem both on Ubuntu 10.10 64-bit Gnome driver nVidia
and Fedora 14 32-bit Xcfe driver Intel. Both with kernel 2.6.35

The problem arise when Xlib is implemented with Xcb. Xcb lock the X connection while waiting for event locking the other thread.

I have posted the whole source in the third message if you wanna try it.

Rosario Leonardi
01-23-2011, 02:41 PM
Changed distro.. and BAM the same problem again.. :D
The only reliable solution is the one suggested by aile with N X connection. One for read the event and one for each window.

Here the full code:
http://pastebin.com/NgLQVYht

With this solution I have to poll for WM_DELETE_MESSAGE event in the window thread. There is any way to get the ClientMessage in the main thread?