在Retina iPad上使用CoreGraphics绘制图像速度较慢。

10
在我的iPad应用程序中,我正在渲染到离屏位图,然后将该位图绘制到屏幕上。(这是因为我想重用现有的位图渲染代码。) 在iPad 2 上,这非常顺畅,但在新的带Retina显示屏的iPad上,绘制位图非常慢,尽管分辨率仍然相同。
为了绘制位图,我们使用常规的Quartz 2D函数: 使用由CGDataProviderCreateWithData创建的数据提供程序的CGImageCreate,32位RGBA格式并使用kCGImageAlphaNoneSkipLast。在显示位图的UIView中,在drawRect:中,我们使用CGContextDrawImage将其绘制到由UIGraphicsGetCurrentContext返回的上下文中。
请注意,我甚至没有尝试以双倍分辨率绘制:目前我对与iPad 2上使用的相同分辨率感到满意。看起来CoreGraphics在内部加倍像素,然后将其发送到GPU,即使我正在制作的CGImage应该适合直接传递给GPU。有任何想法吗?
1个回答

15
看起来CoreGraphics在内部将像素加倍,然后将其发送到GPU。 准确地说(至少在精神上):
1. UIKit将CGBitmapContext设为视图边界的大小,在设备像素中 2. 将该上下文设置为当前上下文 3. 将CGImage绘制到该上下文中 4. ...因此CG必须重新缩放源图像,并触摸所有目标像素 5. 绘制完成后,UIKit从位图上下文中创建CGImage 6. 并将其分配给视图层的内容。
我正在制作的CGImage应该可以直接传递给GPU。 如果要实现这一点,您需要通过剪切上面的某些步骤告诉系统执行该操作。 (UIKit、CoreAnimation和CoreGraphics之间没有提供您期望的“快速路径”的链接。) 最简单的方法是创建一个UIImageView,并将其image设置为包装您的CGImageRef的UIImage。 或者,将您的view.layer.contents设置为您的CGImageRef。(并确保不要覆盖-drawRect:,不要调用-setNeedsDisplay,并确保contentMode不是UIViewContentModeRedraw。使用UIImageView更容易。)

谢谢提供的信息,这可能会帮助很多。视图是动画的,因此它经常重绘。我认为,因此使用view.layer.contents可能比将新图像分配给UIImageView更有效,对吗? - Frederik Slijkerman
1
尝试过了,view.layer.contents方法非常好用,再次感谢! - Frederik Slijkerman
据我所知,这两种方法在性能上几乎相等,但一如既往:如果有影响,请尝试并查看结果。 - Kurt Revis
2
如果有人像我一样想知道,你必须将图像引用转换为 id,如下所示:view.layer.contents = (id) myUIImage.CGImage; 当使用 ARC 时,你还应该使用桥接转换 view.layer.contents = (__bridge id) myUIImage.CGImage;。详情请参见此处:https://dev59.com/Bm035IYBdhLWcg3wYO91#5455139 - nacross

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接