2012-07-11 60 views
2

我们的产品包含一种软件图像解码器,它基本上可以生成需要快速复制屏幕(我们在iOS上运行)的全帧像素数据。将RGB像素数据高效复制到iOS屏幕上

目前我们使用的是CGBitmapContextCreate,我们直接访问内存缓冲区,然后对每一帧调用CGBitmapContextCreateImage,然后将该位图绘制到屏幕上。这对于在iPad的视网膜显示器上进行全屏刷新的速度太慢了,但是对于非视网膜设备来说,这还是可以的。我们尝试了各种基于OpenGL ES的方法,包括使用glTexImage2D和glTexSubImage2D(本质上是渲染纹理),但CPU使用率仍然很高,我们无法获得超过30 FPS的在iPad 3上进行全屏刷新。问题在于,使用30 FPS时,仅将像素复制到屏幕上时,CPU使用率接近于100%,这意味着我们没有太多工作来处理我们自己的渲染。中央处理器。

我们愿意使用OpenGL或任何iOS API来提供最佳性能。像素数据格式化为每像素32位RGBA数据,但我们在这里有一些灵活性...

有什么建议吗?

+0

您是否使用仪器来查看所有CPU的操作?我做了类似的事情,发现花了很多时间将RGBA转换为ARGB(并不是说这是你的问题,但如果你还没有做到这一点,它可能有助于看到一个配置文件) – nielsbot 2012-07-11 00:27:59

+0

“到底画什么”屏幕“是什么意思?你是在绘制一个UIView的'-drawRect:'方法,还是将CGImage放在一个图层中,或者使用UIImageView?后两种方法应该明显更快 - 请参阅此[以前的答案](http://stackoverflow.com/questions/10410106/drawing-image-with-coregraphics-on-retina-ipad-is-slow/10424635#10424635 )。 – 2012-07-11 02:45:25

+0

你的“glTexSubImage2D”方法是什么?我相信如果做得正确,这应该足够快。我如何理解你在做什么是你在CPU上处理原始像素数据并将这些数据推送到GPU并渲染它们。这是最大的约4kx4kx4B(64MB)的数据被推到一个完整的纹理(对于iPad3),似乎并不太多..无论如何,如果在任何情况下,这是什么原因导致fps的下降,我没有看到任何更好的方式,然后直接在像素的GPU上工作。 – 2012-07-11 08:30:30

回答

0

然后可以将pbuffer或FBO用作由OpenGL ES进一步呈现的纹理贴图。这被称为渲染到纹理或RTT。它在EGL中的搜索缓冲区或FBO更快搜索

+0

Render to Texture如何解决这个问题?我们希望从CPU中取出现有的位并将它们传送到屏幕上。我们的渲染是由CPU完成的,而不是由GPU完成的。 – ldoogy 2012-07-11 04:31:51

+0

根据我的说,UIImage是最快速的从CPU访问IOS – 2012-07-11 08:23:15

+0

@talktomevintron - 不,它绝对不是。在我的基准测试中,从UIImage中提取原始像素数据时有很大的核心图形开销。用其他格式的原始像素数据处理会更好。 – 2012-07-13 19:33:02

2

所以,坏消息是你遇到了一个非常困难的问题。我已经在这个特定的领域做了大量的研究,目前唯一的方法就是使用h.264解码器来实现将全屏大小为2x的帧缓冲区。一旦图像数据已经解码成实际的内存(看一下GPUImage),就可以用OpenGL完成一些不错的技巧。但是,最大的问题不在于如何将像素从实时内存移动到屏幕上。真正的问题是如何将像素从磁盘上的编码形式移动到实时内存中。可以使用文件映射内存来保存磁盘上的像素,但是IO子系统速度不够快,无法将足够的页面交换出来,以便能够从映射内存中传输2个全屏大小的图像。这个功能在1x全屏大小的情况下效果很好,但现在2倍大小的屏幕实际上是内存量的4倍,硬件无法跟上。您也可以尝试以更加压缩的格式将帧存储在磁盘上,例如PNG。但是,然后解码压缩格式会将问题从IO绑定到CPU绑定,并且您仍然卡住。请查看我的博客文章opengl_write_texture_cache,了解我在该方法中找到的完整源代码和时序结果。如果你有一个非常具体的格式,你可以限制输入图像数据(比如8位表格),那么你可以使用GPU通过着色器将8位数据作为32BPP像素进行传输,如下例所示:xcode project opengl_color_cycle 。但是,我的建议是考虑如何使用h.264解码器,因为它实际上能够解码硬件中的大量数据,并且没有其他方法可能会为您提供所需的结果。

0

经过几年以及我遇到这种需求的几种不同情况,我决定为iOS实现一个基本的“pixel viewer”视图。它支持高度优化的各种格式的像素缓冲区显示,包括32-bpp RGBA,24-bpp RGB和几种YpCbCr格式。

它还支持所有UIViewContentMode *的用于智能的缩放,缩放,以适应/填充等

该代码是高度优化的(使用OpenGL),并在更老iOS设备如iPhone实现优良的性能5或原装iPad Air。在这些设备上,除了24bpp格式之外,所有像素格式都达到60fps,达到30-50fps(我通常通过在设备原始分辨率下显示像素缓冲区来进行基准测试,所以显然iPad必须推出比iPhone更多的像素5)。

请检查出EEPixelViewer

1

CoreVideo很可能是您应该查看的框架。借助OpenGL和CoreGraphics方法,您将受到将主存储器中的位图数据移动到GPU内存上的成本的困扰。这笔费用也存在桌面上,但在iPhone上尤其痛苦。

在这种情况下,OpenGL不会为CoreGraphics提高速度,因为瓶颈是纹理数据副本。 OpenGL将为您提供更高效的渲染管道,但损坏将由纹理副本完成。

所以CoreVideo是要走的路。就我所了解的框架而言,它解决了您遇到的问题。