gpt4 book ai didi

macos - 制作连续重绘Metal NSView的正确方法

转载 作者:行者123 更新时间:2023-12-03 16:19:15 26 4
gpt4 key购买 nike

我正在学习 Metal 和 Cocoa,并尝试制作一个样板应用程序作为 future 实验的平台。作为该过程的一部分,我正在实现一个 View ,该 View 将以 60fps 的速度重绘自身(或者更准确地说,其 CAMetalLayer 的内容)。同样出于教育目的,我避免使用 MTKView (用于“学习 Cocoa 部分”)。以下是我如何解决该问题的简短代码片段:

@implementation MyMetalView // which is a subclass of NSView

- (BOOL) isOpaque {
return YES;
}

- (NSViewLayerContentsRedrawPolicy) layerContentsRedrawPolicy {
return NSViewLayerContentsRedrawOnSetNeedsDisplay;
}

- (CALayer *) makeBackingLayer {
// create CAMetalLayer with default device
}

- (BOOL) wantsLayer {
return YES;
}

- (BOOL) wantsUpdateLayer {
return YES;
}

- (void) displayLayer:(CALayer *)layer {
id<MTLCommandBuffer> cmdBuffer = [_commandQueue commandBuffer];
id<CAMetalDrawable> drawable = [((CAMetalLayer *) layer) nextDrawable];

[cmdBuffer enqueue];
[cmdBuffer presentDrawable:drawable];

// rendering

[cmdBuffer commit];
}

@end

int main() {
// init app, window and MyMetalView instance

// invocation will call [myMetalViewInstance setNeedsDisplay:YES]
[NSTimer scheduledTimerWithTimeInterval:1./60. invocation:setNeedsDisplayInvokation repeats:YES];

[NSApp run];
return 0;
}

这是做我想做的事情的正确方法吗?或者我选择了一个冗长且不推荐的方法?

最佳答案

强烈建议使用 CVDisplayLink 而不是通用的 NSTimer 来驱动需要匹配显示器刷新率的动画。

您需要创建一个 ivar 或属性来保存 CVDisplayLinkRef:

CVDisplayLinkRef displayLink;

然后,当您的 View 进入屏幕并且您想要开始动画时,您将创建、配置并启动显示链接:

CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self);
CVDisplayLinkStart(displayLink);

显示链接回调应该是静态函数。它将在显示器的 v-blank 周期开始时调用(在没有物理 v-blank 的现代显示器上,这仍然以常规 60Hz 节奏发生):

static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
{

[(MyMetalView *)displayLinkContext setNeedsDisplay:YES];
return kCVReturnSuccess;
}

当您的 View 离开显示时,或者如果您想暂停,您可以释放显示链接并将其清空:

CVDisplayLinkRelease(displayLink);

关于macos - 制作连续重绘Metal NSView的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37794646/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com