2

Our product contains a kind of software image decoder that essentially produces full-frame pixel data that needs to be rapidly copied the screen (we're running on iOS).

Currently we're using CGBitmapContextCreate and we access the memory buffer directly, then for each frame we call CGBitmapContextCreateImage, and then draw that bitmap to the screen. This is WAY too slow for full-screen refreshes on the iPad's retina display at a decent framerate (but it was okay for non-Retina-devices).

We've tried all kinds of OpenGL ES-based approaches, including the use of glTexImage2D and glTexSubImage2D (essentially rendering to a texture), but CPU usage is still high and we can't get more than ~30 FPS for full-screen refreshes on the iPad 3. The problem is that with 30 FPS, CPU usage is nearly at %100 just for copying the pixels to the screen, which means we don't have much to work with for our own rendering on the CPU.

We are open to using OpenGL or any iOS API that would give us maximum performance. The pixel data is formatted as a 32-bit-per-pixel RGBA data but we have some flexibility there...

Any suggestions?

4

4 回答 4

2

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

于 2013-08-22T07:37:30.830 回答
1

CoreVideo 很可能是您应该关注的框架。使用 OpenGL 和 CoreGraphics 方法,将位图数据从主内存移动到 GPU 内存的成本给您带来了沉重的打击。这种成本也存在于台式机上,但在 iPhone 上尤其痛苦。

在这种情况下,OpenGL 不会为您带来比 CoreGraphics 更快的速度提升,因为瓶颈是纹理数据复制。OpenGL 将为您提供更高效的渲染管道,但纹理副本已经造成损坏。

所以CoreVideo是要走的路。据我了解该框架,它的存在是为了解决您遇到的问题。

于 2016-09-12T23:03:50.050 回答
1

几年后,在遇到这种需求的几种不同情况下,我决定为 iOS实现一个基本的“像素查看器”视图。它支持多种格式的像素缓冲区的高度优化显示,包括 32-bpp RGBA、24-bpp RGB 和几种 YpCbCr 格式。

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

该代码经过高度优化(使用 OpenGL),甚至在 iPhone 5 或最初的 iPad Air 等较旧的 iOS 设备上也能实现出色的性能。在这些设备上,除了 24bpp 格式外,它在所有像素格式上都达到 60FPS,它达到了大约 30-50fps(我通常通过以设备的原始分辨率显示像素缓冲区来进行基准测试,因此显然 iPad 必须比 iPhone 推送更多的像素5)。

请查看EEPixelViewer

于 2016-09-12T00:01:42.807 回答
0

然后,pbuffer 或 FBO 可以用作纹理贴图,以供 OpenGL ES 进一步渲染。这称为渲染到纹理或 RTT。在 EGL 中搜索 pbuffer 或 FBO 的速度要快得多

于 2012-07-11T01:59:12.933 回答