Is it possible to make a GL context current on another thread under Windows

I’m on Linux so I don’t have any way to test this myself, nor do I know much about Windows, but I do need my program to be generally compatible with both Linux and Windows since Windows is the dominant OS. I’m trying to get something like e.g. this example working on Linux currently, but looking at the code, it looks like MakeCurrent requires a reference to the window even when called on the other thread, and I’ve read Windows doesn’t let you do any references to a window from any other thread than the main one, so would that cause a problem? Thanks!

I managed to make it work under Linux and Windows.
The finished win-bin then runs with wine.

I hope this helps you

/*
  Linux:
  gcc main.c -o main -lSDL2

  Windows:
  x86_64-w64-mingw32-gcc main.c -o main.exe -lSDL2 -I/usr/local/include -L/usr/local/bin
*/

#include <SDL2/SDL.h>
#include <stdio.h>

int WinMain(int argc, char* argv[]) {
    SDL_Init(SDL_INIT_VIDEO);   
    SDL_Window *window = SDL_CreateWindow("An SDL2 window", 0, 0, 640, 480, SDL_WINDOW_OPENGL);
    SDL_Delay(3000);  
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}
1 Like

I don’t know about Windows specifically but I know that SDL has certain recommendations that you should not call video/render functions from other threads. I think it’s exactly for the reasons you mention.

The SDL Development FAQ says:

Can I call SDL video functions from multiple threads?
No, most graphics back ends are not thread-safe, so you should only call SDL video functions from the main thread of your application.

I actually tested the example out on a windows computer my girlfriend had, and it turns out it does work on windows too. I suspect because I’m only ever calling MaleCurrent from one thread at a time (ensured using locks) so the lack of thread safety doesn’t matter much, and because it’s only really manipulating the SDL Window type and the GL context.

Just because it appears to work doesn’t mean it’s guaranteed to work.

That is a very fair point, but it occurs to me that if sdl’s function for making an opengl context current wasn’t something you could call from a different thread, then it wouldn’t have any point, because the whole point of making an opengl context current is to make it current on a different threat. Also, I happen to cross several issues where everyone, including the sdl maintainers, takes the idea that you should be using make current on another thread as written.

Isn’t it also useful in single-threaded programs if you have multiple windows and you want to change which one to draw to?

It seems like SDL_GL_MakeCurrent calls WIN_GL_MakeCurrent on Windows which calls wglMakeCurrent.
(The SDL_Window argument to SDL_GL_MakeCurrent is used to determine the first argument to wglMakeCurrent)

It indeed looks like wglMakeCurrent is thread-safe but what about the rest of the code in SDL_GL_MakeCurrent and WIN_GL_MakeCurrent? :man_shrugging:

Several OpenGL windows can be accessed without any problems.
I made a little demo here. It’s not in C but in Pascal, but the relevant commands are the same.