Sharing rendering context between threads?

Is it possible to share a rendering context and display lists/texture objects between threads? From what I’ve read, I get the impression it isn’t, but this is kind of a last gasp before I have to reorganize my code.

My apologies if this question has been answered before, but if it has, I couldn’t find it.

As long as you only have the single context current in one thread at a time it should work.
(eg.

//Lock to prevent other threads from using the context while we render with it
MutexLock();

//Activate the context on the thread
wglMakeCurrent(context/device ID);


…Rendering…


//Release the context on the thread
wglMakeCurrent(NULL,NULL);

//Release mutex
MutexUnLock();

If you want to have a context per thread and share texture/list/vbo type resources, you can call wglShareLists(…) on context creation.

Thanks for the reply. I suspected I might have to explicitly switch contexts when necessary, but was just hoping there was a single state I could set somewhere that would allow it.

The problem with this solution, and please correct me if I am wrong, is that I only have the one context, and wglShareLists expects two. My aim was to just have one context owned by the rendering thread, but to temporarily hand it off to the application thread.

The problem I’m having is that the app thread is calling the renderer’s asset loading functions, which make OpenGL calls. They’re failing because the rendering thread owns the context, not the app one. I don’t want to give the app thread its own context just to load stuff. Maybe a rewrite is inevitable…

Well basically, you either need to allow the main app thread to borrow the context from the render thread, or either code some mechanism in which the app thread can ask the render thread to perform a task and then wait until the task is done.

Or, you can just make a context for the main thread and share its textures/vbo’s/etc via wglShareLists.

I think you misunderstood what I was saying.

I was implying that you would have to do a mutex type lock and manually set the context on the threads,

OR

have multiple contexts with wglShareLists

The other option is to just have the application thread do all the disk loading/conversions etc (which should be 90% of the loading time) then store it in a buffer that the rendering thread reads from. (perhaps at the start of every frame it checks to see if there is data pending?)

Yes, you’re right - I thought I had to do both. I was under the misapprehension that it wasn’t possible to use those kinds of resources if they were created in a different thread - but they’re bound to the context, not the thread. Also learned that it is actually possible to share them. I will try the context switching. Thanks for the help!