Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

At what point does vsync "wait" (block)?

Tags:

c++

opengl

Say I have a program that is really fast and, if vsync were disabled, would run >60fps. When does vsync force the program to wait? Does it block when you clear the screen or when you flip the buffers? Or is it some other time I'm not aware of?

I'm referring to OpenGL, incidentally.


BONUS QUESTION

Given there's not necessarily a specific point at which the blocking occurs, how would I measure how long the blocking is taking? In other words, how would I work out how fast the program could run?

like image 350
Clonkex Avatar asked Dec 26 '22 08:12

Clonkex


1 Answers

The comments to your answer show, that this remains still a topic with a lot of misconceptions.

To make a long story short: There is no explicit point at which your program will block.

The swap buffer call returns immediately. Don't believe me? Write a program that measures the time spent in one single swap buffers call (i.e. don't enter a rendering loop). But I hear you say: If I enable V-Sync and measure the frame rate in my program it shows the right frame rate, so somewhere it has to block.

Whats happening is, that after a call to swap buffers the back buffer is kind of "protected"; the back buffer is to be presented on the front buffer with the contents it had the the time of calling SwapBuffers. So the next operation that would alter the contents of the back buffer blocks after a call to SwapBuffers until the swap happened.

BUT (and that's a big but) the OpenGL command queue is asynchronous. What blocks is the execution of the command queue, but unless a synchronization point is inserted or the queue maximum capacity has reached all the OpenGL calls will return immediately. glFinish introduces a synchronization point. But if you place a glFinish right after a SwapBuffers, since it only acts on any drawing operation happening between itself and the previous SwapBuffers, there's nothing to finish yet and it will likely return immediately as well.

So you're in a rendering loop and measure the time of SwapBuffers there, and all of a sudden it takes one V-Sync interval to return. What's going on? Well, SwapBuffers implies a glFlush. But more importantly a buffer swap leaves the back buffer in an undefined state, which means, that a buffer swap operation is on the same level of buffer content modification as drawing commands. But because there are only two buffer (front and back) if there's already a buffer swap queued, the following one invokes a synchronization block until the previous swap has been performed. This stalls the command queue and ultimately makes one OpenGL drawing command or the SwapBuffers command block eventually.

like image 88
datenwolf Avatar answered Jan 11 '23 06:01

datenwolf