WinAPI - 同步SwapBuffers

时间:2014-06-02 13:44:20

标签: c multithreading winapi opengl

是否可以在许多线程中同步SwapBuffers?当我尝试打开垂直同步(wglSwapIntervalEXT)时,它会停止所有线程,直到它没有打勾(例如,当我打开3个窗口时,每个窗口大约有20帧[60/3]) 每个窗口都有单独的线程,当然每个线程都有自己的SwapBuffer函数。

2 个答案:

答案 0 :(得分:2)

WGL中的交换控制是 每窗口 (当您设置它时,它将应用于当前渲染上下文的窗口拴)。渲染上下文和窗口之间的关联与设备上下文相关联(请参阅wglMakeCurrent (...))。如果您可靠地击中< 3,那么您可能只需要3个窗口中的1个VSYNC ~5.6 每帧的帧时间。

这里你应该考虑的是让你的一个上下文将交换间隔设置为 1 ,剩下的2个使用 0 。同步到VBLANK的上下文(交换间隔= 1 )将引导其他两个线程。也就是说,让另外两个线程调用glFlush (...),然后 忙等待 ,直到第一个线程在调用SwapBuffers (...)之前停止阻塞VSYNC。 glFlush (...)的原因是,当您等待第一个(同步)交换完成时,其他两个线程完成一些有用的渲染任务。

这听起来很有趣 - 几乎就像撕裂的食谱一样 - 但鉴于Windows Vista / 7/8合成窗口管理器的性质,VSYNC实际上并不能防止撕裂。窗口管理器本身通过异步合成来实现,它有效地执行三重缓冲。但是,VSYNC允许你做什么(当正确完成时)让你的所有3个窗口每次刷新都会更新它们的内容(避免延迟帧)。

如果您在VBLANK开头没有开始系列缓冲区交换,则可能会遇到合成窗口管理器显示2帧旧帧的情况,因为您在VBLANK中间交换了缓冲区。当然,如果你绘制一个过长的框架,你仍然可以遇到这种情况,但它解决了一个不幸的是,一个短框架交换得太接近垂直回扫截止时间以便及时完成的​​情况。

答案 1 :(得分:0)

为什么不在调用SwapBuffers之前/之后添加barrier