| # Texture Compressor | |
| This directory contains a compressor for GPU texture formats. It is primarily | |
| meant for compressing thumbnails to save memory. Currently, only the ETC1 format | |
| is supported, and this is only used on Android. | |
| ## Goals | |
| * Fast: Compressing a 4K screenshot takes less than 100ms (roughly 100 | |
| megapixels/s). Currently, it can achieve 220 megapixels/s on x64 desktop. | |
| * Safe: Free of memory safety issues and suitable for running in the | |
| privileged browser process. | |
| * Portable: SIMD code shared across x86 (SSE) and ARM (NEON). Easy to modify | |
| and validate for correctness. | |
| ## Algorithm | |
| Vectorization is done by assigning each 4x4 SIMD lane to a different block. This | |
| minimizes cross-lane shuffle operations (which are typically architecture | |
| dependent) and makes the code significantly more portable. | |
| Compression of ETC1 is done by first searching through the flip / no-flip and | |
| individual / differential space to decide on the quantization of average, then | |
| searching through selector tables and values for each subblock. | |
| Detailed comments about the algorithm can be found in the source. | |
| ## Tools | |
| ### Performance Evaluation for Decoder | |
| This directory also contains a tool to measure decoder performance. | |
| #### Evaluation Methodology | |
| To ensure accurate and consistent results, the tool follows this process: | |
| 1. Warm-up: Performs an initial decoding pass (discarded) to prime the CPU caches and branch predictors. | |
| 2. Measurement: Executes the decoding process 100 times (`BENCHMARK_RUNS`). | |
| 3. Analysis: Calculates the average and standard deviation of the execution time. | |
| #### Usage | |
| To build and run the performance evaluation tool on an Android device: | |
| ```bash | |
| # 1. Build | |
| autoninja -C out/Debug/ texture_compressor_benchmark | |
| # 2. Push executable and data | |
| adb push out/Debug/texture_compressor_benchmark /data/local/tmp/ | |
| adb push input.png /data/local/tmp/ | |
| # 3. Run | |
| adb shell /data/local/tmp/texture_compressor_benchmark /data/local/tmp/input.png /data/local/tmp/output.png | |
| # 4. Pull the image decoded from ETC1 file | |
| adb pull /data/local/tmp/output.png | |
| ``` | |
| ## Similar projects | |
| * [etcpak][etcpak] heavily inspired this project. Most of the algorithm | |
| (except vectorization scheme) and math tricks are borrowed from etcpak. | |
| * [ISPC Texture Compressor][ispctexcomp] influenced the vectorization scheme. | |
| Unlike this project, the compressor is written in ISPC and requires a | |
| dedicated compiler. | |
| * [AOSP ETC1 library][aospetc1] also uses a similar search algorithm and is | |
| easier to read, thanks to the scalar implementation. | |
| While reading the code, the [ETC1 specification][etc1spec] should also be | |
| useful. | |
| ## (Currently) Missing Pieces | |
| This project is functional, but still a work-in-progress. The following pieces | |
| are missing: | |
| * Testing coverage | |
| * Dynamic dispatch (multiversioning) and AVX2 support | |
| * Running on stable toolchain (using the `wide` crate instead of | |
| `#[feature(portable_simd)]`) | |
| [etcpak]: https://github.com/wolfpld/etcpak | |
| [ispctexcomp]: https://github.com/GameTechDev/ISPCTextureCompressor | |
| [aospetc1]: https://cs.android.com/android/platform/superproject/main/+/main:frameworks/native/opengl/libs/ETC1/ | |
| [etc1spec]: https://registry.khronos.org/DataFormat/specs/1.1/dataformat.1.1.html#ETC1 |