![](/img/trans.png)
[英]What is the correct way to optimise scrolling performance of NSImageView and NSView
[英]Correct way to initialize / sync OpenGL for NSView
我遵循苹果的文档创建了一个自定义OpenGLView而不是使用NSOpenGLView
。 绘图似乎很好,但似乎我这里有线程同步问题。 由于NSView应该在主线程中,然后在如何同步线程中,我的意思是CADisplayLink
似乎在不同的线程上工作,因此在旋转或缩放到3D场景后,某些节点会保持其旧的转换(缓慢转换),直到旋转/缩放完成为止。 但是如果我在显示链接绘图中使用dispatch_sync/dispatch_async
似乎是正确的。 但是我不确定它如何影响性能。
Q1:在displaylink cb中使用dispatch_sync是否正确? 还是更好的选择?
Q2:另外我没有绘制全屏视图,会有可可控件或多个openglviews。 由于主线程不是专用于opengl的,所以我不知道它如何影响FPS或可可粉控件。 那么可以在单独的线程中运行opengl绘图操作吗?
对于缩放/旋转情况,我有一个解决方案,我向场景或节点添加了一个标志(更改缩放/旋转时),然后在渲染功能时,我检查了该标志然后应用了变换。 渲染/绘图似乎也是正确的。 但这是一种情况。 将来还会有其他问题。 所以我需要同步我认为的线程
CVReturn
displaylink_cb(CVDisplayLinkRef CV_NONNULL displayLink,
const CVTimeStamp * CV_NONNULL inNow,
const CVTimeStamp * CV_NONNULL inOutputTime,
CVOptionFlags flagsIn,
CVOptionFlags * CV_NONNULL flagsOut,
void * CV_NULLABLE displayLinkContext) {
dispatch_sync(dispatch_get_main_queue(), ^{
[(__bridge GLView *)displayLinkContext renderOnce];
});
return kCVReturnSuccess;
}
- (void)syncWithCurrentDisplay {
NSOpenGLContext *openGLContext;
CGLContextObj cglContext;
CGLPixelFormatObj cglPixelFormat;
GLint swapInt;
openGLContext = [self openGLContext];
swapInt = 1;
/* Synchronize buffer swaps with vertical refresh rate */
[openGLContext setValues: &swapInt
forParameter: NSOpenGLCPSwapInterval];
/* Create a display link capable of being used with all active displays */
CVDisplayLinkCreateWithActiveCGDisplays(&m_displayLink);
/* Set the renderer output callback function */
CVDisplayLinkSetOutputCallback(m_displayLink,
display_link_cb,
(__bridge void *)self);
/* Set the display link for the current renderer */
cglContext = [openGLContext CGLContextObj];
cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(m_displayLink,
cglContext,
cglPixelFormat);
}
- (void) renderOnce {
NSOpenGLContext *context;
context = [self openGLContext];
[context makeCurrentContext];
/* because display link is threaded */
CGLLockContext([context CGLContextObj]);
[[self delegate] render];
[context flushBuffer];
CGLUnlockContext([context CGLContextObj]);
}
OpenGL渲染可以在任何线程上进行,只要一次只在一个线程上进行即可。 仅仅因为您拥有NSView并不意味着您的上下文必须在主线程上呈现。
请参见下面的示例。 呈现是在显示链接的线程上完成的,除了在主线程上发生视图框架更改通知期间外,因此代码使用锁在主线程上呈现该一帧(这实际上不是必需的,但是如果您这样做,该锁将显示操作方法)。
https://developer.apple.com/library/content/samplecode/GLFullScreen/Introduction/Intro.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.