![](/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.