【问题标题】:How to speed up shader loading/compiling on Android如何在 Android 上加快着色器加载/编译
【发布时间】:2012-01-08 04:08:12
【问题描述】:

我为 Android 编写了一个使用 17 像素和 17 个顶点着色器的 OpenGL 动态壁纸。在我的 HTC Legend 上,加载和编译大约需要 3 秒。加载时间大约是其中的 20%,其余时间正在编译。

每次运行全屏应用时,动态壁纸都会破坏其 OpenGL 上下文,当壁纸再次可见时,需要重新加载所有着色器、纹理等,导致屏幕冻结约 3 秒每次,这对我来说是不可接受的:(

我已经阅读了一些资料,显然无法预编译着色器。我还能做些什么来解决这个问题?是否可以在后台线程中加载和编译着色器?在这种情况下,我可以显示某种进度动画。不会很好,但总比没有好......

[编辑1] 加快这一速度的另一个重要原因是整个基于 OpenGL 的动态壁纸生命周期很难在所有设备上正常工作(这是轻描淡写的)。每当上下文丢失/重新创建时引入较长的加载时间会比我想要的更令人头疼。无论如何:

正如答案 1 所暗示的,我尝试查看 GL_OES_get_program_binary 扩展,以制作某种 compile-once-store-compiled-version-per-installed-app,但我担心此扩展的实施范围。例如,我的 Tegra2 驱动的平板电脑似乎不支持它。

我正在考虑的其他方法:

1) Ubershader:将所有像素着色器放入一个大着色器中,使用 switch 或 if 语句。这会显着减慢像素着色器的速度吗?它会让着色器太大,让我超出所有那些讨厌的寄存器/指令计数/纹理查找限制吗?顶点着色器的想法相同。这会将我的整个着色器数量减少到 1 个像素和 1 个顶点着色器,并有望使编译/链接速度更快。有没有人试过这个? [EDIT2] 我刚试过这个。不。现在编译/链接需要 8 秒才能放弃一个模糊的“链接失败”错误:(

2) 可怜人的后台加载:不要在开始时加载/编译着色器,而是在前 17 帧的每帧更新中加载/编译一个着色器。至少我会刷新显示,我可以显示一个进度条让用户看到正在发生的事情。这在速度较慢的设备上可以正常工作,但在速度较快的设备上,这可能会使整个着色器加载/编译阶段比它需要的要慢...

【问题讨论】:

  • 您找到更多解决方案了吗?
  • 不。我现在每帧加载一个着色器,并使用 glViewport 和 glClear 绘制进度条。悲伤,但它有效。

标签: android opengl-es glsl live-wallpaper


【解决方案1】:

检查您的实现是否支持OES_get_program_binary

【讨论】:

  • 我会这样做的,谢谢!我假设你建议我编译一次,第一次执行,保存二进制文件,下次重新加载它们?这需要额外的 SD 访问权限,但我想我可以接受。一旦我知道更多,我会更新这个问题/答案。
  • 好的,在我拥有的两台设备(HTC Legend 和 Asus EEE 变压器)上试了一下。结果有点出人意料:旧的、弱的 HTC Legend 支持这个扩展,更新的,“真棒”NVidia Tegra2 没有。另一方面,在华硕上,编译着色器所需的时间要少得多(还没有计时,但肯定不到一秒)。我有点担心这个命令被各种硬件供应商广泛实施,是否值得我花时间来实施整个缓存方案......
  • 如何从驱动中获取二进制文件?
  • 就在扩展规范中:glGetProgramBinaryOES()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-02
  • 2014-06-15
  • 2012-01-18
  • 1970-01-01
  • 2021-09-11
相关资源
最近更新 更多