Another great Android OpenGL ES 3.0 sample from Cristiano Ferreira - Graphics Software Engineer with Intel Corporation.
Programmatically compiling all shaders the first time an application is run and saving the binaries for reuse can significantly reduce load times for games in subsequent runs. The OpenGL* ES 3.0 sample code introduced here demonstrates a simple implementation of this capability.
Precompiling shaders is a technique to improve the user experience for games and other applications that use large numbers of complex shaders, by reducing load times.
- The first time the application is executed, it compiles all of the shaders, and the binaries produced are saved to local storage.
- For subsequent runs of the application, shader compilation is not necessary, because the required binaries have already been produced and are available at runtime.
This approach enhances efficiency for resource-constrained mobile devices and improves responsiveness from the user’s perspective.
A key benefit of the precompiled shader approach discussed here, relative to some alternatives, is that the shader binaries are built natively for the execution platform, using the target device’s actual runtime environment. That overcomes limitations faced by developers who seek a similar result by compiling shaders and packaging the binaries as assets before distributing the application, for example, which can result in cross-platform incompatibilities.
Downloading and installing the sample
The code sample is available for download from GitHub. To build and deploy the application to your Android device, follow the steps below.
- Navigate to PrecompiledShaders\projects\android
- Run the following:
android update project –p .
ndk-build
ant debug
ant installd
Details of the implementation
This sample implements shader precompilation by caching the shader binary on the first run and then using that file on each subsequent run. The implementation operates as follows:
- Cache the shader on the first run only.
- Compile and link the program in the usual way.
- Use glGetProgramBinary to save the compiled/linked program binary into an array.
- Load the shader.
- Use glProgramBinary to load the program binary into the program object.
Performance comparison: precompiled versus runtime-compiled shaders
The following chart compares load times for precompiled shaders with those for shaders compiled at runtime, using the code sample introduced here with a very simple shader. These results clearly demonstrate the value of shader precompilation.
Conclusion
While the shader precompilation technique used in this sample doesn’t require significant development effort, it is a flexible, cross-platform approach to decrease load times significantly. This approach should be used routinely to optimize the user experience within the hardware constraints of mobile devices.
Additional Resources
OpenGL ES: The Standard for Embedded Accelerated 3D Graphics is Khronos Group’s official OpenGL ES page; it describes the standard and provides links to specifications, header files, and reference materials.
Android Developer Guide for OpenGL ES provides background and guidance for use of the OpenGL ES API with Android, including management of compatibility between the two.
OpenGL® ES 3.0 and Beyond: How To Deliver Desktop Graphics on Mobile Platforms describes capabilities of both OpenGL ES 3.0 and 3.1, including how they are supported on Intel’s Bay Trail platform.
Intel® Open Source Technology Center Intel Graphics for Linux* provides downloads, documentation, and community resources related to graphics for Linux on Intel® platforms.