我正在开发一个由两个NSOpengGLView
s (leftGLView
和rightGLView
) 并排放置在 NSWindow contentView 内的 OSX 应用程序。这两个视图不共享NSOpenGLContext
但都是双缓冲的,并将缓冲区交换与监视器回溯同步。
ACVDisplayLink
已设置并链接到第一个的NSOpenGLContext
and (比如左侧)。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
状态:
根据交换间隔上下文属性(参见 NSOpenGLCPSwapInterval),复制可能发生在监视器的垂直回溯期间,而不是在调用 flushBuffer 之后立即发生。一个隐式的 glFlush 在它返回之前由 flushBuffer 完成。为了获得最佳性能,应用程序不应在调用 flushBuffer 之前立即调用 glFlush。后续的 OpenGL 命令可以在调用 flushBuffer 后立即发出,但直到缓冲区复制完成后才会执行。
但是,在这种情况下,我有两个不同的NSOpenGLContext
缓冲区,因此应该可以将两个缓冲区一起刷新。
为了进一步研究这一点,我假设-flushBuffer
仅在交换(或复制)缓冲区后才返回,并且由于这仅与监视器回溯同步发生,因此对 flushBuffer 的第二次调用在该回溯上发生为时已晚。这可以解释我观察到的行为。因此,我尝试分离一个辅助线程来执行 flushBuffer 调用,但没有任何区别。
我终于尝试使用两种不同CVDisplayLink
的 s,一种用于左侧 GLView,另一种用于右侧。然而,这种技术似乎也没有解决问题,并且增加了保持两个 CVDisplayLink 线程同步的额外复杂性。
有没有办法让这两个flushBuffer
在两个 NSOpenGLViews 之间同步发生?