假设我的程序非常快,如果禁用vsync,则运行速度> 60fps.vsync何时强制程序等待?清除屏幕或翻转缓冲区时是否会阻塞?还是在其他时间我不知道?
顺便说一句,我指的是OpenGL.
奖金问题
鉴于阻塞发生的特定点不一定,我如何衡量阻塞的持续时间?换句话说,我将如何工作,如何快速的程序可以运行?
你的答案的评论表明,这仍然是一个有很多误解的话题.
长话短说:你的程序没有明确的阻止点.
交换缓冲区调用立即返回.不相信我?编写一个程序来测量在单个交换缓冲区调用中花费的时间(即不要进入渲染循环).但我听到你说:如果我启用V-Sync并在我的程序中测量帧速率,它会显示正确的帧速率,因此它必须阻止.
发生的事情是,在调用交换缓冲区后,后台缓冲区有点"受保护"; 后缓冲区将显示在前缓冲区中,其内容是调用SwapBuffers的时间.所以下一个操作会在调用SwapBuffers之后改变后缓冲区块的内容,直到交换发生.
但是(这是一个很大的但是)OpenGL命令队列是异步的.什么块是命令队列的执行,但除非插入同步点或队列最大容量已达到,否则所有OpenGL调用将立即返回.glFinish介绍了一个同步点.但是如果你在SwapBuffers之后放置一个glFinish,因为它只对它自己和之前的SwapBuffers之间发生的任何绘图操作起作用,没有什么可以完成的,它也可能立即返回.
因此,您处于渲染循环中并测量其中的时间SwapBuffers,并且突然间需要一个V-Sync间隔返回.这是怎么回事?嗯,SwapBuffers意味着一个glFlush.但更重要的是,缓冲区交换使后台缓冲区处于未定义状态,这意味着缓冲区交换操作与绘图命令处于相同级别的缓冲区内容修改.但是因为只有两个缓冲区(前面和后面),如果已经有一个缓冲区交换排队,下面一个调用一个同步块,直到执行了前一次交换.这会使命令队列停顿,最终最终生成一个OpenGL绘图命令或SwapBuffers命令块.