2012-01-03 40 views
4

我已经为Android编写了一个使用17个像素和17个顶点着色器的OpenGL动态壁纸。在我的HTC Legend上,这些需要大约3秒来加载和编译。加载时间约为此的20%,其余的正在编译。如何加速着色器在Android上的加载/编译

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

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

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

如答案1所示,我试着寻找GL_OES_get_program_binary扩展,来制作某种编译一次编译的商店编译版本的安装应用程序,但我担心这个扩展的程度有多广泛已实施。例如,我的Tegra2平板电脑似乎不支持它。

我正在考虑其他的方法:

1)Ubershader:将所有像素渲染成一个大着色器,具有开关或if语句。这会显着降低像素着色器的速度吗?它是否会使着色器太大,并让我超出所有那些烦人的寄存器/指令计数/纹理查找限制?顶点着色器的想法也一样。这会将我的整个shadercount减少到1个像素和1个顶点着色器,并希望能够更快地编译/链接。有没有人试过这个? [编辑2]我刚试过这个。别。编译/链接现在需要8秒钟,然​​后放弃模糊的“链接失败”错误:(

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

+0

您是否找到更多解决方案? – Zammbi 2012-08-13 21:28:58

+1

没有。我现在加载所有我的着色器,并使用glViewport和glClear绘制进度条。悲伤,但它的作品。 – 2012-08-16 10:17:39

回答

3

检查您的实现是否支持OES_get_program_binary

+0

我会那样做,谢谢!我假设你建议我编译它们一次,首先执行,保存二进制文件,下次重新加载它们?这将需要额外的SD访问权限,但我想我可以忍受。一旦我知道更多,我会更新这个问题/答案。 – 2012-01-05 13:51:26

+0

好的,在我拥有的两款设备(HTC Legend和一款华硕EEE变压器)上试用过。结果有点令人惊讶:年龄较大,较弱的HTC Legend支持这种扩展,更新的“真棒”NVidia Tegra2不支持。另一方面,在华硕上,编译着色器所花费的时间要少得多(还没有计时,但肯定不到一秒钟)。我有点担心这个命令已经被各种硬件厂商实现了多么广泛,以及是否值得我的时间来实现这个整个缓存方案...... – 2012-01-07 09:47:11

+0

如何从驱动程序获取二进制文件? – Zammbi 2012-05-24 21:14:08