【问题标题】:Can I get 60fps with a 10ms drawRect?我可以用 10ms drawRect 获得 60fps 吗?
【发布时间】:2014-12-15 22:32:30
【问题描述】:

我问了一个更笼统的问题,关于CADisplayLinkdrawRect 的行为here,但由于这个问题还没有任何答案,我想我会问一个更具体的问题:有没有人设法通过 drawRect 方法让应用以 60fps 的速度运行,执行时间约为 10 毫秒?

在我的应用中,我像这样配置CADisplayLink

displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

update 方法只是在我的自定义 UIView 上调用 setNeedsDisplay(以及检查跳帧):

- (void)update
{
    static CFTimeInterval timestamp = 0;

    // check for skipped frame
    CFTimeInterval newTimestamp = displayLink.timestamp;
    if ((newTimestamp - timestamp) > (displayLink.duration * (displayLink.frameInterval + 0.5)))
        NSLog(@"Frame skipped!");
    timestamp = newTimestamp;

    [myView setNeedsDisplay];
}

只要drawRect 花费超过 4 或 5 毫秒,就会开始跳帧。就我而言,它最多需要大约 10-11 毫秒,但我认为给定 1/60fps = 16.7 毫秒,这应该没问题。

有人做到了吗?我做错了什么?

【问题讨论】:

  • 从您的描述看来,您所做的一切都是正确的。在理想情况下 60 fps 是不错的,但即使是原生 Apple UI 元素也会下降到 40-50 fps,例如在快速滚动表格视图时。
  • 另外,我认为您可能已经在这样做了,但是在 drawRect: 中,请确保您使用的是 displayLink.timestamp 中的增量(而不是一些硬编码的增量,例如 5 个点)来计算你的动作。
  • 问题是,当更新方法花费的时间稍微过长时,显示链接会错过下一次触发,并且帧速率会下降到 30fps。
  • 是的,我正在使用增量。当帧率在 60 到 30fps 之间跳跃时,它看起来仍然很糟糕。我只是不明白为什么我不能在帧之间使用完整的 16 毫秒。

标签: ios uiview cadisplaylink


【解决方案1】:

我只是不明白为什么我不能使用帧之间的完整 16 毫秒

当屏幕刷新时,除了您正在处理的一个视图之外,还会绘制其他内容。 (例如,状态栏时钟。)此外,drawRect: 中的任何内容都不是硬件加速的。因此,其中一些计算能力正在做其他事情(后台下载、iCloud 同步等)

使用drawRect: 永远无法可靠地获得 60fps。您可以尝试使用缓存和 Apple 的其他一些 drawing tips 来提高性能。您还可以使用经过高度优化的 Core Animation 或 SceneKit 获得更好的性能。

【讨论】:

  • 感谢您的提示。实际上,我使用drawRect: 确实可以可靠地获得 60fps,只要它花费不到 4 毫秒左右。我不明白为什么 drawRect: 在显示链接触发后 10 毫秒才被调用(请参阅我的链接问题)。你是说所有的时间都花在了绘制状态栏之类的东西上?这对我来说似乎不太可能......
  • @deltacrux 好吧,这不仅仅是绘画。由于drawRect: 没有硬件加速,所有其他操作需要大约 10 毫秒,而不仅仅是绘图操作。
  • 我确信在那段时间我的代码都没有运行。如果这 10 毫秒用于其他操作(它们会是什么?),是否有某种方法可以使用线程来允许并行处理我的绘图代码?我知道这有时会对 UI 响应能力产生很大影响(例如stackoverflow.com/questions/7551411/…),但我不太了解如何实现多线程...
  • 可能在后台发生的其他操作:重新连接到手机信号塔、下载电子邮件或应用程序更新、播放音乐、重新索引 Spotlight 等等。您无法在上面执行绘图代码另一个线程,因为图形上下文仅在 drawRect: 返回之前有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 2017-03-29
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
相关资源
最近更新 更多