在什么时候vsync"等待" (块)?

时间:2014-06-10 08:03:52

标签: c++ opengl

假设我的程序非常快,如果禁用了vsync,则会运行> 60fps。 vsync何时强制程序等待?清除屏幕或翻转缓冲区时是否会阻塞?还是在其他时间我不知道?

顺便说一句,我指的是OpenGL。


奖金问题

鉴于阻塞发生的具体点不一定,我如何衡量阻塞的持续时间?换句话说,我如何计算程序可以运行的速度有多快?

1 个答案:

答案 0 :(得分:9)

对你的答案的评论表明,这仍然是一个有很多误解的话题。

简而言之:你的程序没有明确的阻止点。

交换缓冲区调用立即返回。别相信我?编写一个程序来测量在单个交换缓冲区调用中花费的时间(即不要进入渲染循环)。但是我听到你说:如果我启用V-Sync并在我的程序中测量帧速率,它会显示正确的帧速率,所以它必须阻止。

发生的事情是,在调用交换缓冲区后,后台缓冲区有点像#34;受保护&#34 ;;后缓冲区将显示在前缓冲区中,其内容是调用SwapBuffers的时间。所以下一个操作会在调用SwapBuffers之后改变后缓冲区块的内容,直到交换发生。

但是(而且这很大但是)OpenGL命令队列是异步的。什么块是命令队列的执行,但除非插入同步点或队列最大容量已达到,否则所有OpenGL调用将立即返回。 glFinish引入了同步点。但是如果你在SwapBuffers之后放置一个glFinish,因为它只对它自己和之前的SwapBuffers之间发生的任何绘图操作起作用,还没有什么可以完成的,它也可能立即返回。

因此,您处于渲染循环中并测量SwapBuffers的时间,并且突然间需要一个V-Sync间隔返回。发生了什么事?好吧,SwapBuffers意味着glFlush。但更重要的是,缓冲区交换使后台缓冲区处于未定义状态,这意味着缓冲区交换操作与绘图命令处于相同级别的缓冲区内容修改。但是因为只有两个缓冲区(前面和后面),如果已经排队的缓冲区交换,下面的一个调用同步块,直到执行了前一个交换。这会使命令队列停顿,最终最终生成一个OpenGL绘图命令或SwapBuffers命令块。