如何在Android上加速着色器加载/编译

如何在Android上加速着色器加载/编译,android,opengl-es,glsl,live-wallpaper,Android,Opengl Es,Glsl,Live Wallpaper,我已经为Android编写了一个OpenGL live墙纸,它使用17个像素和17个顶点着色器。在我的HTC Legend上,加载和编译这些代码大约需要3秒钟。加载时间约为其中的20%,其余时间在编译 每次运行全屏应用程序时,实时壁纸的OpenGL上下文都会被破坏,当壁纸再次可见时,所有着色器、纹理等都需要重新加载,导致屏幕每次冻结约3秒,这是我无法接受的:( 我已经读了一些书,显然,不可能预编译着色器。我还可以做些什么来解决这个问题?可以在后台线程中加载和编译着色器吗?在这种情况下,我可以显示

我已经为Android编写了一个OpenGL live墙纸,它使用17个像素和17个顶点着色器。在我的HTC Legend上,加载和编译这些代码大约需要3秒钟。加载时间约为其中的20%,其余时间在编译

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

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

[第1版] 加快此速度的另一个重要原因是,整个基于OpenGL的Live Wallper生命周期很难在所有设备上正常工作(这是一个轻描淡写的说法)。每当上下文丢失/重新创建时引入较长的加载时间会增加比我想要的更多的麻烦。无论如何:

正如答案1所示,我尝试查看GL_OES_get_program_二进制扩展,为每个安装的应用程序创建某种编译一次存储编译版本,但我担心这个扩展的实现范围有多广。例如,我的Tegra2平板电脑似乎不支持它

我正在考虑的其他方法:

1) Ubershader:使用开关或if语句将所有像素着色器放入一个大着色器中。这会显著降低像素着色器的速度吗?它会不会使着色器太大,使我超出所有那些讨厌的寄存器/指令计数/纹理查找限制?顶点着色器也有同样的想法。这将使我的整个着色器计数减少到1个像素和1个顶点着色器,并有望加快编译/链接速度。有人试过这个吗? 我刚试过这个。不要。编译/链接现在需要8秒钟,然后会出现模糊的“链接失败”错误:(


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

检查您的实现是否支持。

我会这样做,谢谢!我想你是建议我编译它们一次,首先执行,保存二进制文件,然后下次重新加载它们?这需要额外的SD访问权限,但我想我可以接受。一旦我知道更多,我会更新这个问题/答案。好吧,在我拥有的两台设备(一台HTC Legend和一台华硕EEE transformer)上试用。结果有点令人惊讶:更老、更弱的HTC Legend支持此扩展,而更新的“令人敬畏”的NVidia Tegra2则不支持。另一方面,在Asus上,编译着色器所需的时间要少得多(尚未计时,但肯定不到一秒钟)。我有点担心这个命令在各个硬件供应商中的应用范围有多广,以及是否值得我花时间来实现整个缓存方案……如何从驱动程序中获取二进制文件?它就在扩展规范中:
glgetprogrammabinaryoes()
。您找到了其他解决方案吗?没有。现在,我每帧加载一个着色器,并使用glViewport和glClear绘制进度条。虽然很悲伤,但它确实有效。