PDA

View Full Version : Creating multiple OpenGL contexts with GLFW on different threads



Silverlan
09-19-2014, 01:40 AM
I'm using GLFW 3.0.4.
I'm trying to improve my loading times by having all resources, including textures, loaded on a separate thread. Problem is, to actually use any opengl functions in a different thread, without blocking the main one, I need a separate opengl context as well.
GLFW doesn't seem to provide any functions to create an independent context, you can only create it in combination with a window. That's not much of a problem however, considering you can just hide it. The problem is this:

Note: This function may only be called from the main thread.
(http://www.glfw.org/docs/latest/group__window.html#ga5c336fddf2cbb5b92f65f10fb6043 344)

So that path is basically down the drain.

Are there any alternatives for what I'm trying to do, or would I have to end up using a different library for creating the window/rendering context? If so, which one?

carsten neumann
09-19-2014, 03:42 AM
I don't know GLFW and I've not tried this, but can you not create your contexts before launching the threads, pass the GLFWwindow* to them and only make the context current inside the thread function?

Aleksandar
09-19-2014, 04:25 AM
I'm trying to improve my loading times by having all resources, including textures, loaded on a separate thread.
Resource preparation definitely should be done in separate thread(s).


Problem is, to actually use any opengl functions in a different thread, without blocking the main one, I need a separate opengl context as well.
But you don't need to upload them directly to the graphics card memory. HDD is the main bottleneck. Second, much faster but still important time consumer is transcoding (if your resources are not in a format suitable for GPU usage).
Upload from RAM to graphics memory can (and I suggest to do it so) be done by the rendering thread. I also suggest you to introduce quota for update per frame in order to have fluent rendering. Unless you have chance to use dual copy engine, it is impossible to render and upload data in parallel. So, reconsider the usage of separate context.

I have never used GLFW and have no suggestion about it.

Silverlan
09-19-2014, 05:13 AM
Thanks. I'll try your suggestion and make do without a separate context for now, to see how it goes.
One more thing, however:
Not all of my textures have all mipmaps integrated to save space, and instead I generate them on the fly using glGenerateMipmap.
That can take quite a bit for some textures, and without a second context, my only option is to generate them on the CPU instead.
I want the end-result to be the same, so I need to mimic glGenerateMipmap as closely as possible, both for regular 2D textures and cubemap textures.

Is there anywhere I can find more information about the inner workings of the function?

// EDIT:
Nevermind, found the information I need in this document (http://homepage.cs.uiowa.edu/~cwyman/classes/fall04-22C151/handouts/OGLmipmap.pdf).

GClements
09-19-2014, 03:03 PM
would I have to end up using a different library for creating the window/rendering context? If so, which one?
If you need to perform your own context management, GLFW is of no use to you. SDL and SFML allow you to manage contexts directly, as do more general GUI libraries such as Qt. Or you could just use the platform's native functionality (glX, wgl, etc).

IonutCava
09-28-2014, 07:52 AM
There is a way to use multiple contexts with GLFW.

Make a second invisible window that has the main window as the parent (the last parameter is for list sharing)
E.g.: GLUtil::_loaderWindow = glfwCreateWindow(1, 1, "whatever", nullptr, GLUtil::_mainWindow);
Create another thread and in its run()(or whatever) method call this: glfwMakeContextCurrent(GLUtil::_loaderWindow);

If you are using GLEW, build GLEW with the GLEW_MX define and call init() in the second thread as well. Read up on GLEW_MX about multithreaded usage. I strongly recommend boost thread specific pointers for this.

Remember to destroy the second window just like the main one. That's it. I've been using this method for background resource loading for years and haven't ran into any issues.

Hope it helps.