PDA

View Full Version : Sharing opengl context with worker thread



Lauvak
11th November 2010, 12:53
Hello,
I am using QGLWidget to display an opengl scene in the main thread.
I would like to load the texture from a worker QThread.
My problem is that I cannot find a way to share the opengl context between the threads.

I tried to:
- create a QGLWidget in the worker thread with shareWidget= main thread QGLWidget. Crash
- create a QGLContext with create(glWidget->context()); . No crash but opengl return errors and textures are not updated.

Any advice?

tbscope
11th November 2010, 14:44
You should at all times avoid sharing objects between threads, unless you absolutely must share one.
It's a nightmare to maintain code that does this, let alone to get it right in the first place.

Instead, create the texture in the thread and notify the main thread that the texture is finished. Then, from within your main thread, get the texture from the worker thread and use the context from within the main thread.

Lauvak
11th November 2010, 15:23
You should at all times avoid sharing objects between threads, unless you absolutely must share one.
It's a nightmare to maintain code that does this, let alone to get it right in the first place.
Thanks for your answer. It does indeed look like something difficult to achieve properly.


Instead, create the texture in the thread and notify the main thread that the texture is finished. Then, from within your main thread, get the texture from the worker thread and use the context from within the main thread.
This is the method I'm using at the moment but I'm not satisfied with the speed:
- The worker thread reads one texture from file and uses a QSemaphore release to notify the main thread.
- In the main thread QGLWiget paintGL routine (maybe it is not the best place) I check for the semaphore and get the texture in the opengl context.

The problem is that the number of textures read is limited by the frames per second and the sync between thread seems to even make things worse since I get only around 10 textures/s (whereas the worker thread is able to produce around 150 textures/s).

One way would be to read textures and accumulate them in a buffer.
But this will make the code more complex.

I was hoping to be able to share opengl context to just load the textures directly from the worker thread.