Options for reducing frame latency?

What are my options for having as little frame latency as possible?

I could use this hint but my targets include x11, mac and likely windows so it won’t be enough SDL2/SDL_HINT_VIDEO_DOUBLE_BUFFER - SDL2 Wiki

Would rendering with opengl inside of SDL cut down on latency? What about sdl_gpu? I tried a gpu example, seems to have the same latency. What else can I do? My code usually takes 2ms to render and it’s not unusual for the previous frame to be the same

You can just turn off vsync.

With SDL_GPU and other 3D graphics APIs you can control how many frames are in flight.

How would I prevent tearing the screen?

I have some test code that I measured having less latency using the functions below. I rather have the flexibility of SDL choosing metal/vulkan/d3d/whatever is best for the OS

SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
SDL_FlushRenderer(renderer);
glFlush();
SDL_GL_SwapWindow(window);

In SDL_GPU you can set the type of presentation mode. Regular vsync, where it waits to show the next completed frame until the monitor refreshes, mailbox (same as vsync, but instead of going on to the next completed frame when the monitor refreshes it jumps to showing the most recently completed frame), and then of course no vsync at all.

Also, that SDL_GL_SetAttribute() call doesn’t affect the same thing as that SDL hint in your first post, AFAIK.

If you’re using SDL_Renderer(), your options are limited to vsync on or off.

Also, glFlush() has nothing to do with latency, and it’s implicitly called when you call SDL_GL_SwapWindow(). Essentially, all it does is tell the GL implementation to send any pending buffered commands to the hardware, in case the implementation was waiting until the buffer was full before sending them off. It’s kind of a holdover from the early days of OpenGL, and AFAIK you really only need to call it manually if you’re using multiple OpenGL contexts.

If your application is running in a window, the window compositor itself may introduce an unavoidable frame of latency.

That’s what you say, but I wrote it in because on my x11 desktop, I’ll get no rendering if I don’t call glFlush. This is when calling SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0); before create window

Which is probably because you are bizarrely turning off double buffering.

The thread is called reducing frame latency for a reason :stuck_out_tongue:

Like I mentioned earlier, SDL_GL_DOUBLEBUFFER isn’t associated with that SDL hint you linked to in the OP.

Turning off double buffering means OpenGL should render to the front buffer, instead of rendering to a back buffer, and I suspect the only reason you aren’t seeing your app flash and flicker as everything gets drawn is because the window compositor is also keeping a frame.

edit: the SDL docs specify that SDL_GL_SwapWindow() only does anything if you’re using double buffering.

1 Like