【发布时间】: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