gpt4 book ai didi

ios - CGContextDrawLayerAtPoint 在 iPad 3 上很慢

转载 作者:行者123 更新时间:2023-11-28 18:07:08 25 4
gpt4 key购买 nike

我的应用程序中有一个自定义 View (继承自 UIView )。自定义 View 覆盖
- (void) drawRect:(CGRect) rect
问题是:drawRect:在 iPad 3 上执行的时间比在 iPad 2 上长很多倍(在 iPad 3 上大约 0.1 秒,在 iPad 2 上大约 0.003 秒)。它慢了大约 30 倍。

基本上,我使用了一些预先创建的图层并将它们绘制在 drawRect: 中。 .最后一次通话

CGContextDrawLayerAtPoint(context, CGPointZero, m_currentLayer);

花费大部分时间(大约 95% 的总时间在 drawRect: 中)

是什么让事情变得如此缓慢,我应该如何解决这个原因?

更新:

没有直接涉及的线程。我确实调用 setNeedsDisplay:在一个线程和 drawRect:被另一个人打电话,但就是这样。锁也是如此(没有使用锁)。

View 被重绘以响应触摸(它是一个着色书应用程序)。在 iPad 2 上,我在触摸和屏幕更新之间得到了合理的延迟。我想在 iPad 3 上达到同样的效果。

最佳答案

所以,iPad 3 在很多方面肯定要慢一些。我对此有一个理论。 Marco Arment noted该方法renderInContext在新 iPad 上速度慢得离谱。在尝试为自定义 TextView 创建放大镜时,我也发现了这种情况。最后我不得不放弃renderInContext用于自定义核心图形绘图。

我在击中可怕的 wait_fences 时也遇到了问题我在这里绘制的核心图形错误:Only on new iPad 3: wait_fences: failed to receive reply: 10004003 .

这是我到目前为止所知道的。 iPad 3 显然有 4 倍的像素来驱动。这可能会在两个地方引起问题:

  • 首先,CPU。所有核心图形的绘制都是由 CPU 完成的。在旋转事件的情况下,如果 CPU 绘制时间过长,它会命中 wait_fences错误,我认为这只是一个调用,告诉设备等待更长的时间才能实际执行旋转,从而延迟。
  • 将图像传输到 GPU。 GPU 显然可以很好地处理视网膜分辨率(请参阅 Infinity Blade 2)。但是当核心图形绘制时,它会将其图像直接绘制到 GPU 缓冲区以避免 memcpy。然而,要么 GPU 缓冲区自 iPad 2 以来没有改变,要么只是没有使它们变得足够大,因为这些缓冲区很容易过载。发生这种情况时,我相信 CPU 会将图像写入标准内存,然后在 GPU 缓冲区可以处理它时将它们复制到 GPU。我认为这是导致性能问题的原因。额外的副本对于如此多的像素非常耗时,并且会大大减慢速度。

  • 为了避免 memcpy,我推荐了几件事:
  • 只画你需要的。不惜一切代价避免在屏幕外画任何东西。如果您正在绘制一个大 View ,但只显示该 View 的一部分(例如覆盖它的 subview ),请尝试找到一种仅绘制可见内容的方法。
  • 如果您必须绘制一个大 View ,请考虑将 View 分解为 subview 或子层(在您的情况下可能是子层)。并且只重绘你需要的东西。以知名度应用程序为例。当您放大时,您可以从字面上看到它一次重绘一个正方形。或者在 Safari 中,您可以在滚动时看到它更新方 block 。不幸的是,我不必这样做,所以我不确定方法。
  • 尽量保持你的图纸简单。我有一个很棒的自定义核心 TextView ,必须在输入的每个字符上重新绘制。非常慢。我将背景更改为简单的白色(在核心图形中),它加速得很好。对我来说最好不要重绘背景。

  • 我想指出,我的理论是猜想。苹果并没有真正解释他们到底做了什么。我的理论只是基于他们所说的以及 iPad 的响应方式以及我自己的实验。

    更新

    所以苹果现在已经发布了 2012 WWDC 开发者视频。他们有两个视频可以帮助您(需要开发者帐户):
  • iOS App Performance: Responsiveness
  • iOS App Performance: Graphics and Animation

  • 我认为他们谈论的一件事可能会对您有所帮助,那就是使用以下方法: setNeedsDisplayInRect:(CGRect)rect .用这个方法代替普通的 setNeedsDisplay并确保您的 drawRect方法只绘制给它的矩形可以极大地帮助性能。我个人使用函数: CGContextClipToRect(context, rect);仅将我的绘图剪辑到提供的矩形。

    例如,我有一个单独的类,用于使用 Core Text 将文本直接绘制到我的 View 中。我的 UIView 子类保留对这个对象的引用并使用它来绘制它的文本,而不是使用 UILabel。我曾经在文本更改时刷新整个 View ( setNeedsDisplay )。现在我让我的 CoreText 对象计算更改后的 CGRect 并使用 setNeedsDisplayInRect仅更改包含文本的 View 部分。这确实有助于我在滚动时的表现。

    关于ios - CGContextDrawLayerAtPoint 在 iPad 3 上很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11100984/

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