OpenGL ES 2.0 片段着色器在 iPhone 5S 上编译缓慢



我有一个使用大量片段着色器的应用程序。着色器都是在应用启动时编译的(在后台队列上)。我最近在iPhone 5S上测试了该应用程序,一切正常,但是着色器需要更长的时间来编译。在 5 上,编译需要 0.8 秒。在 5S 上,它需要 10 秒以上。有人知道这里发生了什么吗?

在 iPhone 5(运行 iOS 7.0.2)上:

   2013-10-16 16:53:41.949 Socialcam[1096:1603] -[EffectCaptureController compileShaders]: start
   2013-10-16 16:53:42.753 Socialcam[1096:1603] -[EffectCaptureController compileShaders]: end

在 iPhone 5S(运行 iOS 7.0.2)上:

   2013-10-16 16:46:52.856 Socialcam[9757:1603] -[EffectCaptureController compileShaders]: start
   2013-10-16 16:47:03.303 Socialcam[9757:1603] -[EffectCaptureController compileShaders]: end  

使用更多信息进行编辑

进一步研究这个问题,看起来iPhone 5S无法像以前的设备那样处理那么多的制服。这实际上不是编译问题。对于我的一个着色器,链接阶段挂起 10 秒,然后失败。对于所有其他着色器,没有问题,编译和链接只需几毫秒。有问题的着色器使用由 768 个 vec4 组成的统一数组,以及三个纹理。如果我删除任何纹理或减小数组的大小,它的链接没有问题。

由于听起来大制服是问题所在,这里有一些替代方案:

  • 如果您在 iPhone 5s 上运行时使用 OpenGL ES 3.0,则可以利用统一缓冲区对象 (UBO),它允许比统一数组更大的存储空间。另请注意,即使您在支持 ES3 的设备上运行时没有真正利用 ES3 功能,使用 ES3 上下文也会给您带来更大的限制(MAX_TEXTURE_IMAGE_UNITS等)。

  • 批量数据的另一个好地方是纹理。您在该着色器中使用了三个纹理单元,因此您有足够的空间来添加第四个纹理单元,它可以容纳具有与统一数组相同数据的 32x32 图像,并且可能会更快地采样。(一般建议是注意此处的依赖纹理获取,但在 A7 上没有惩罚,因此您可以在特定于新 GPU 的代码中执行此操作。

最新更新