I've written an OpenGL live wallpaper for Android that uses 17 pixel and 17 vertex shaders. On my HTC Legend, these take about 3 seconds to load and compile. Loading time is about 20% of this, the rest is compiling.
A live wallpaper has its OpenGL context destroyed every time a full-screen app is ran, and when the wallpaper becomes visible again, all shaders, textures and so on need to be reloaded, causing the screen to freeze for about 3 seconds each time, which is unacceptable to me :(
I've done some reading and apparently, it's not possible to precompile the shaders. What else could I do to fix this? Is it possible to load and compile shaders in a background thread? I could show some kind of progress animation in that case. Wouldn't be great, but better than nothing...
[EDIT1] Another big reason to speed this up is that the whole OpenGL based Live Wallpaper life cycle is difficult to get working properly on all devices (and that is an understatement). Introducing long load times whenever the context is lost/recreated adds more headaches than I want. Anyway:
As answer 1 suggests, I tried looking at the GL_OES_get_program_binary extension, to make some kind of compile-once-store-compiled-version-per-installed-app, but I'm worried about how widely this extension is implemented. For example, my Tegra2 powered tablet does not seem to support it.
Other approaches I'm considering:
1) Ubershader: putting all pixel shaders into one big shader, with a switch or if statements. Would this slow down the pixel shader dramatically? Would it make the shader too big and make me overrun all those pesky register/instruction count/texture lookup limits? Same idea for the vertex shaders. This would reduce my entire shadercount to 1 pixel and 1 vertex shader, and hopefully make compiling/linking lots faster. Has anyone tried this? [EDIT2] I just tried this. Don't. Compiling/linking now takes 8 seconds before giving up with a vague "link failed" error :(
2) Poor man's background loading: don't load/compile the shaders at the beginning, but load/compile one shader per frame update for the first 17 frames. At least I would be refreshing the display, and I could show a progress bar to make the user see something is happening. This would work fine on the slow devices, but on the fast devices this would probably make the whole shader load/compile phase slower than it needs to be...