Ok, I found an answer to my question. It’s possible to run SDL2 headless with or without graphics.
So there are 2 cases
- Headless without graphics
- Headless with graphics
=== 1 - Headless without graphics ===
Concept is to define video driver as dummy via environment variable. With this, we cannot create window, or renderer, or grab opengl context as it depends on window.
SDL_VIDEODRIVER value in environment variable to be dummy via
putenv("SDL_VIDEODRIVER=dummy"); in your code before you do
- You still call
SDL_Init(SDL_INIT_VIDEO | ...) which includes
SDL_INIT_VIDEO normally though, it just doesn’t create window for you.
- Don’t create window, or renderer.
(From what I understand and tested), event loop won’t work, so if you need to capture key input (mouse not possible), then do it manually via Event loop still works, and you can simulate sending event via
Note: if you try to create window via
SDL_CreateWindow, it will print out error like this
Failed to create window: OpenGL support is either not configured in SDL or not available in current SDL video driver (dummy) or platform.
=== 2 - Headless with graphics ===
(I didn’t test this yet) but seems glfw is also capable of doing this, thus the concept should be applied to SDL2 and others in general.
So basically do initialization stuff as did normally but for SDL_CreateWindow, specify
SDL_WINDOW_HIDDEN as one of flags. I believe we cannot just detect event like mouse position,
interaction at least button presses event works, etc as there’s no window now but hidden, anyway graphics operations should be normal; in off-screen. So we can do some opengl operation via command line i.e. generate image output from shader code then write to file etc.
If you specify
SDL_WINDOW_HIDDEN and run the app, at I tested this on macOS, there will be in icon on your dock showing the app is running but if you click on it, it won’t show any window whatsoever. So this suits our need! Further test is to involve graphics operations, I’ll post update again.
It works! Headless also works with graphics. Practically no changes in code at all, only just specify parameter for hidden window. So do things normally the way you would do without regard to headless topic. Specify parameter of
SDL_WINDOW_HIDDEN when call
SDL_CreateWindow, do graphics operation then call it a day. I just did a sample test taking a snapshot of current opengl frame, then write into .tga file then quit the program. It works.