使用电池供电时,CVDisplayLink计时器的稳定性

时间:2016-10-16 12:22:06

标签: macos timer metal core-video

我试图让动画在没有屏幕撕裂的情况下以显示器的刷新率顺利运行。动画使用Metal渲染。据我所知,Apple告诉您使用基于CVDisplayLink的计时器,这就是我所做的。

当桌面计算机和笔记本电脑连接到电源适配器时,一切正常。然而,当笔记本电脑使用电池运行时,特别是当电池电量不足时,我可以看到动画中非常明显的卡顿。但是,没有撕裂。似乎每次刷新屏幕都不会触发计时器。

我很确定这不是因为CPU受到限制。 CPU利用率低于10%,动画计算和渲染时间不到2毫秒;在60Hz时,它将有16ms的速度。

为了它的价值,这就是我设置计时器的方式:

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。

1 个答案:

答案 0 :(得分:1)

如果我正确阅读您的代码,您可以假设CVDisplayLink在某个不可更改的时间间隔内被调用。根本没有承诺。系统完全可以自由修改刷新间隔或丢帧。所有实时系统必须包括丢帧的能力。这就是&#34;实时的核心所在。&#34;

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