在ios7上glTexSubImage2D速度慢

时间:2014-01-16 13:07:08

标签: ios opengl-es ios7

我有一个项目,我需要更新纹理的多个区域,并在每一帧将这些区域同步到openGL。我正在使用openGL ES 2.0和xcode5中的项目为iDevices。

为了同步这些纹理变化,我使用glTexSubImage2D,对于绑定纹理的小区域,每帧可能会调用此函数几百次。在运行ios6的iPhone4上进行测试时,这足以满足我的需求。

当我在运行ios7的iPad Mini Retina上进行测试时,它显着停滞。 这些档位出现在mach_msg_trap中,来自glTexSubImage2D下的三个函数。

不幸的是我无法发布配置文件的图像(由于缺少信誉点),但是这三个函数是从agxuBlitRender调用的,占用了86.1%的CPU: agxuCreateRenderTarget(38.2%) SubmitPackets(25.5%) agxuReleaseAllRenderTargets(16.2%)

我很感激mach_msg_trap只是意味着线程在等待时旋转,但我无法从分析器中确定它在等待什么。

我最初想知道它是否可能正在重建mip-maps或ios7强制执行的其他一些过程。我没有打开mipmap,虽然根据gl.h中的选项,我可能没有多少选择(所有TextureMinFilters都是面向mipmap的,即使我将它设置为GL_NEAREST,它可能默认为GL_NEAREST_MIPMAP_NEAREST,如果它认为GL_NEAREST无效)。 iPhone4版本使用完全相同的代码的事实可能不是决定因素,如果它处理引擎盖下的mipmapping。

虽然我已经尝试过每帧复制一次整个纹理,但是当更大的纹理尺寸时,当在openGL的核心深处的函数twiddle32x32_32每帧占用大部分CPU时,这会变得非常慢。

感激不尽的任何帮助。

2 个答案:

答案 0 :(得分:1)

glTexSubImage2D()在使用PowerVR GPU的所有设备上都非常慢,因为它们具有延迟渲染的基于图块的设计,并且因为它的笨拙。我更熟悉Android,您可以通过使用EGL图像扩展来获取纹理的虚拟指针并直接访问像素。这通常快4倍。但是,我已经读过iOS中也可以使用类似的功能。例如:

Using OpenGL ES texture caches instead of glReadPixels to get texture data

答案 1 :(得分:0)

调用glTexSubImage2D()“每帧数百次”非常糟糕。你应该退后一步,问问自己为什么需要这样做。它在任何平台上都会很慢,因为GPU不是为支持它而设计的。

你在做什么需要在运行时更新纹理?

如果必须,一个选项是在主存储器中保留纹理的副本(作为BGRA或LUMINENCE像素的数组)。在那里执行更新。然后通过一个呼叫将其上传到GPU。您应该只在帧的开头或结尾上传,以最大限度地减少CPU停滞。 (如果GPU当前正在使用该纹理,CPU将阻塞很长时间。)