Is SDL_RenderPresent synchronized with VSYNC signal?

Let’s assume I have a fast CPU which is capable of generating frame 100 times faster than VSYNC. The program calls SDL_RenderPresent after it completes drawing one frame. Does SDL_RenderPresent not wait for VSYNC signal and return immediately back to program, or does it hand up inside the API and swap the two buffers during VSYNC? If SDL_RenderPresent returns immediately, should there be an OS thread that wait for VSYNC for actual buffer swap? If so, will new frames generated by the fast CPU overwrite the old not-yet-swapped one? The program runs on both Windows and Linux. Thank you.

My guess and hope would be that RenderPresent returns immediately the first time but waits the 2nd time if the previous present is waiting for a VSYNC. That’s how it should work and appears to be working in my experience, but hopefully someone can confirm this?

If you created the renderer with the SDL_RENDERER_PRESENTVSYNC flag, and the API SDL is using behind the scenes supports vsync, then SDL_RenderPresent() will block until the image is presented (which is to say, on a 60Hz display, you could be waiting around 16 milliseconds for the function to return if your program is going pretty fast). If we don’t have vsync enabled, it should return almost immediately. In this case, what usually happens at the lowest level is your new image overwrites a previous thing you drew that maybe wasn’t yet presented, and depending on the system, you risk showing half of one frame and half of another (what is called generally called “tearing”).

In practice, tearing isn’t the end of the world, but can be annoying to watch. On the other hand, going at 60FPS or whatnot is more than enough, even if your program can produce frames at a much higher rate.

1 Like

Thank you, icculus. One more question: If SDL_RENDERER_PRESENTVSYNC flag is enabled so SDL_RenderPresent() will block, is the block busy-wait or the SDL program suspends its execution to relinquish the control to the operating system (Let’s say Ubuntu 18.04)?

This depends on the OpenGL driver, but I’m pretty sure most don’t busy-wait.

So, so far as SDL is concerned, when SDL_RenderPresent() is blocked for VSYNC, SDL surely relinquishes its control to operating system, instead of conducting busy-wait itself, am I right?

Incidentally, the OS then calls OpenGL driver to handle the details of waiting for VSYNC, is that right? I am using Windows 10 + Quadro K5000 with latest driver and Ubuntu 16.04 + another unknown nVidia Kepler graphics card with OpenGL driver installed. They should not do busy-waiting for VSYNC, right?

SDL leaves it up to the OpenGL driver what to do on vsync, it does not busy-wait itself.

At least in the past nvidia Linux drivers seemed to busy-wait in vsync (it might have changed with more recent driver versions). That behaviour could be changed by setting the __GL_YIELD environment variable to USLEEP.

1 Like

It won’t be able to give the CPU back to the OS, the problem is that each scheduled program is given like 15-30ms before being reconsidered, so if it were to take the program off the hot seat then it would drop frames like a madman. However, it will not be a busy wait, because that’ll destroy battery life of laptops and the livelihood the process (And also cause more heat and ramp up fans). Instead, it will communicate to the CPU to be in a “sleep” mode that uses very low power and only checks the internal mutex / atomic every once and a while. The code itself will look like a while loop, but it wont be a tight loop because it’ll be checking the value thousands to tens of thousands of times per second instead of billions of times per second