我正在开发一个OSX应用程序,该应用程序由两个NSOpengGLView
s(leftGLView
和rightGLView
)并排放置在NSWindow contentView中。
这两个视图不共享NSOpenGLContext
,但都是双缓冲的,并将缓冲区交换与监视器回扫同步。
CVDisplayLink
已设置并链接到第一个NSOpenGLContext
的{{1}}和NSOpenGLPixelFormat
(例如左侧的NSOpenGLView
。
在CVDisplayLink回调中,我使用以下代码绘制到两个视图:
-(CVReturn)draw {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
CGLLockContext([[leftGLView openGLContext] CGLContextObj]);
[[leftGLView openGLContext] makeCurrentContext];
... draw code ...
[[leftGLView openGLContext] flushBuffer];
CGLUnlockContext([[leftGLView openGLContext] CGLContextObj]);
CGLLockContext([[rightGLView openGLContext] CGLContextObj]);
[[rightGLView openGLContext] makeCurrentContext];
... draw code ...
[[rightGLView openGLContext] flushBuffer];
CGLUnlockContext([[rightGLView openGLContext] CGLContextObj]);
[pool release];
return kCVReturnSuccess;
}
这种方法的问题是两个flushBuffer
并不总是同步的。右侧NSOpenGLView有时会比左侧更新(可能在下一次监视器刷新期间)。
关于-flushBuffer
州的Apple文档,这并非完全出乎意料:
根据swap interval context属性(参见 NSOpenGLCPSwapInterval),副本可能在垂直期间发生 追溯显示器,而不是在flushBuffer之后立即追踪 调用。隐式glFlush由flushBuffer在返回之前完成。 为获得最佳性能,应用程序不应调用glFlush 在调用flushBuffer之前立即执行。 后续的OpenGL命令可以 在调用flushBuffer后立即发出,但不执行 直到缓冲区副本完成。
但是,在这种情况下,我有两个不同的NSOpenGLContext
,因此应该可以将两个缓冲区冲洗在一起。
为了进一步研究这一点,我假设-flushBuffer
仅在交换(或复制)缓冲区之后才返回,因为这只与监视器回扫同步,第二次调用flushBuffer就太晚了在那次追溯。这可以解释我正在观察的行为。
因此,我试图分离一个辅助线程来执行flushBuffer调用,但没有区别。
我终于尝试使用两个不同的CVDisplayLink
s,一个用于左侧GLView,另一个用于右侧一个。然而,这种技术似乎也没有解决问题,并增加了使两个CVDisplayLink线程保持同步的额外复杂性。
有没有办法让两个NSOpenGLViews之间发生两个flushBuffer
同步?