화면이 끊어지지 않고 디스플레이의 재생 빈도로 부드럽게 움직이는 애니메이션을 얻으려고합니다. 애니메이션은 Metal을 사용하여 렌더링됩니다. 애플이 당신에게 이것을 위해 CVDisplayLink 기반의 타이머를 사용하라고 말한 것을 이해한다면, 그것이 내가 한 일이다.배터리 전원이 켜져있을 때 CVDisplayLink 타이머의 안정도
전원 어댑터에 연결하면 모든 것이 데스크톱 컴퓨터와 랩톱에서 정상적으로 작동합니다. 그러나 랩톱이 배터리로 작동 할 때, 특히 배터리가 가득차 있지 않은 경우 애니메이션에서 매우 눈에 띄는 끊김 현상을 볼 수 있습니다. 그래도 눈물은 없습니다. 모든 화면을 새로 고침 할 때 타이머가 실행되지 않는 것 같습니다.
나는 CPU가 줄어들 기 때문에 이것이 아니라고 확신한다. CPU 사용률이 10 % 미만이고 애니메이션이 계산 및 렌더링에 2ms 미만 소요됩니다. 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에 타이머가 모든 화면을 새로 고침 할 때마다 실행되도록 보장 할 수 있습니까? 이것이 금속 문제입니까? 배터리로 잘 돌아가는 게임과 화면 보호기를 보았지만 OpenGL을 사용한다고 가정합니다.
감사합니다. 나는 여러분이 작성한 것을 이해하고, 'CACurrentMediaTime'으로 검색 한 경과 시간에 애니메이션을 기반으로한다고하더라도 콜백에 대한 인수로 전달 된 시간을 사용하면 차이가 있는지 여부를 확인하려고 노력할 것입니다. 즉, 내 진짜 질문은 내 코드가 충분히 빠르며 시스템이 그렇지 않으면 부하가 많이 걸리지 않는 한 "프레임을 건너 뛰지"않는 타이머를 얻고 자 할 때 취해야 할 접근 방식입니다. 게임 개발자는이 작업을 수행 할 수있는 방법이 있어야합니다. 그렇지 않으면 게임에서도 배터리가 누락 될 수 있습니다. –
시스템이 절전을 위해 프레임을 버릴 수 있습니다. 저는 시스템이 저전력 모드로 전환되지 않도록 요청할 수있는 전원 단언을 할 수 있다고 믿습니다. 그러나 배터리를 훨씬 더 빠르게 태울 것이므로 실제로는 이걸 가져야 만하지 않는 한 까다 롭습니다. 일반적으로 출력 시간 (현재 시간 아님)을 사용하는 경우 부드럽게 처리해야합니다. https://developer.apple.com/videos/play/wwdc2012/711/ –
'CACurrentMediaTime'을 사용하는 경우에도 솔직히 말더듬을 재현 할 수 없습니다. 어쨌든, 답안에서 제안 된대로 콜백에 전달 된 출력 시간을 사용하면 개선 된 것이므로 지금 구현했습니다. 그래서 나는 이것을 올바른 대답으로 받아 들일 것입니다. –