desugar-64 / imla

Hardware-Accelerated Real-time Blur Effect for Android Jetpack Compose
MIT License
117 stars 5 forks source link

Imla - (Experimental) GPU-Accelerated Blurring for Android Jetpack Compose UI

⚠️ Disclaimer: This project is experimental and not intended for use in production applications.

Description

Imla (Ukrainian for "Haze", pronounced [ˈimlɑ] (eem-lah)) is an experimental project exploring GPU-accelerated view blurring on Android. It aims to implement efficient blurring effects using OpenGL, targeting devices from Android 6 (API 23) onwards.

The project serves as a playground for experimenting with GPU rendering and post-processing effects, with the potential to evolve into a full-fledged library in the future.

Features

Demo

Pixel 6
Gradient blur demo Blur demo
Neat blur algorithm bug Noise blend demo
Mosaic blur demo Gamma corrected blur
Nexus 5
Live blur demo
Blur gamma correction side-by-side
Mosaic blur

How It Works

Imla uses a combination of GraphicsLayer from Jetpack Compose and OpenGL ES 3.0 to achieve fast, GPU-accelerated blurring. The processing pipeline does multiple steps to achieve blurred effect:

  1. A specified view is rendered as a background texture using Surface and SurfaceTexture( see RenderableRootLayer.kt).
  2. The rendered texture is copied to a post-processing framebuffer.
  3. The BackdropBlur composable wraps child composable elements that need a blurred background.
  4. The blurred texture is rendered as a SurfaceView background to the wrapped elements, creating the illusion of a blurred backdrop.

The post-processing pipeline includes:

  1. Down-sampling the background texture, RenderableRootLayer.kt;
  2. Applying a two-pass blur algorithm with gamma correction, BlurEffect;
  3. Blending with a noise texture for a frosted glass effect, NoiseEffect;
  4. (Optional) Application of a mask for progressive or gradient blur effects, MaskEffect.

Importantly, all blur color processing is performed in the linear color space, with appropriate gamma decoding and encoding applied to ensure colors blend naturally, preserving vibrancy and contrast.

Rendering Abstraction

The project reuses the OpenGL abstractions from another experimental project: desugar-64/android-opengl-renderer. This repo is a playground to learn graphics and OpenGL, including some convenient abstractions for setting up OpenGL data structures and calling various OpenGL functions.

The current implementation uses a fully dynamic renderer, which pushes vertex data each frame. While this approach offers flexibility, it introduces some performance overhead. Future iterations aim to optimize this aspect of the rendering pipeline.

Performance

Current performance metrics for the blur effect on a Pixel 6 device:

Trace
trace_blur_effect
trace_total_pass00
trace_total_pass01

These timings indicate that the blur effect and rendering process are relatively fast, but there's still room for optimization.

Future Plans

Contributing

This project is open to suggestions and contributions. Feel free to open issues or submit pull requests on GitHub.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Development Updates

For project development updates and history, refer to this Twitter thread.