macos - 电池供电时 CVDisplayLink 定时器的稳定性

标签 macos timer metal core-video

我试图让动画以显示器的刷新率平稳运行,而不会出现屏幕撕裂。动画是使用 Metal 渲染的。据我了解,Apple 告诉您为此使用基于 CVDisplayLink 的计时器,这就是我所做的。

当台式电脑和笔记本电脑连接到电源适配器时,一切正常。但是,当笔记本电脑使用电池运行时,尤其是当它们的电池未充满时,我可以在动画中看到非常明显的卡顿。不过,没有撕裂。似乎每次屏幕刷新时都不会触发计时器。

我很确定这不是因为 CPU 被限制了。 CPU利用率低于10%,动画计算和渲染时间不到2ms;在 60Hz 时,它需要 16ms 的时间。

对于它的值(value),这就是我设置计时器的方式:

private func makeDisplayLink(window: NSWindow) -> CVDisplayLink
{
    func displayLinkOutputCallback(_ displayLink: CVDisplayLink, _ inNow: UnsafePointer<CVTimeStamp>, _ inOutputTime: UnsafePointer<CVTimeStamp>, _ flagsIn: CVOptionFlags, _ flagsOut: UnsafeMutablePointer<CVOptionFlags>, _ displayLinkContext: UnsafeMutableRawPointer?) -> CVReturn {
        unsafeBitCast(displayLinkContext, to: MetalScreenSaverView.self).animateOneFrame()
        return kCVReturnSuccess
    }

    var link: CVDisplayLink?
    let screensID = UInt32(window.screen!.deviceDescription["NSScreenNumber"] as! Int)
    CVDisplayLinkCreateWithCGDisplay(screensID, &link)
    CVDisplayLinkSetOutputCallback(link!, displayLinkOutputCallback, UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()))
    return link!
}

后来我通过调用 CVDisplayLinkStart 开始链接以链接作为参数。完整代码,如果您有兴趣,可以在以下位置找到:https://github.com/thoughtworks/dancing-glyphs/blob/master/Library/MetalScreenSaverView.swift

有任何想法吗?我可以告诉 OS X 以确保在每次屏幕刷新时触发计时器吗?这是 Metal 的问题吗?我见过在电池上运行良好的游戏和屏幕保护程序,但我假设使用 OpenGL。

最佳答案

如果我正确阅读了您的代码,则您假设 CVDisplayLink在某个不可更改的间隔被调用。这根本没有 promise 。系统完全可以自由修改刷新间隔或丢帧。所有实时系统都必须具备丢帧的能力。这就是“实时”的核心。

您已通过“当前显示”时间和“目标输出”时间。您应该使用它们来计算目标输出的正确帧。我没有看到您在代码中使用输出时间。

关于macos - 电池供电时 CVDisplayLink 定时器的稳定性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40070195/

相关文章:

Java 定时器与静态方法

iOS Metal : Unable to create compute pipeline state with function

python - 带有 py2app 的 OSX 10.11?

macos - 在Mac上为Docker Toolbox添加命令

macos - 在 OS X 上以编程方式检测当前 CPU 时钟速度?

JavaScript 定时器用法

.net - 线程 sleep 和Windows服务

swift - 这个快速扩展是扩展了 metalview 类还是向量?

ios - 如何开始使用 Video-To-Texture 渲染?

python - Sqlite3写入只读数据库