WGPU Rendering Pipeline
Relevant source files
The following files were used as context for generating this wiki page:
The WGPU Rendering Pipeline is the core graphics engine of Kaleidux, responsible for high-performance, hardware-accelerated wallpaper rendering on Linux systems. It leverages the wgpu library to provide a cross-backend abstraction (supporting Vulkan, OpenGL, etc.) that handles both static image backgrounds and dynamic video frames with minimal CPU overhead.
The system is designed around a multi-stage process where wallpapers are uploaded as textures and blended using GLSL-based transitions. By utilizing GPU-side processing, the pipeline achieves smooth, high-framerate visual effects such as fades, zooms, and wipes across multiple monitors independently.
Sources: README.md:21-25, kaleidux-daemon/src/renderer.rs:104-120
Core Architecture
The architecture is built upon the WgpuContext, a shared resource containing the GPU device, command queues, and cached pipelines, and the Renderer, which manages the state and surface for a specific display output.
WGPU Context and Resource Management
The WgpuContext acts as a global singleton-like structure that manages long-lived GPU resources to prevent redundant allocations across different monitors.
- Pipeline LRU Cache: Manages a cache of
RenderPipelineobjects for transitions (up to 50) using a Least Recently Used eviction policy to minimize shader compilation stalls. - Texture Pool: Implements a pooling mechanism for
wgpu::Textureobjects (limited to 50 total) to reuse memory for video frames of the same resolution. - Bind Group Layouts: Defines standard layouts for transitions, blitting (copying to surface), and mipmap generation.
Sources: kaleidux-daemon/src/renderer.rs:37-100, kaleidux-daemon/src/renderer.rs:114-124
The Renderer State Machine
Each physical monitor is assigned its own Renderer instance. It tracks the "Previous" and "Current" textures to facilitate transitions.
The diagram above shows how assets move from input buffers into the renderer's texture states before being processed through the transition and blit pipelines.
Sources: kaleidux-daemon/src/renderer.rs:260-310, kaleidux-daemon/src/renderer.rs:1145-1175
Pipeline Stages
1. Asset Upload and Preparation
Data enters the pipeline either as raw RGBA bytes from decoded images or as GStreamer buffers from video streams.
| Feature | Implementation Detail |
|---|---|
| Image Upload | Decodes images, calculates mipmap levels, and generates them using a dedicated mipmap_pipeline. |
| Video Upload | Handles stride alignment (256-byte requirement for WGPU) and utilizes the texture pool for reuse. |
| Throttling | Throttles uploads if the Wayland frame callback is pending for too long (>1000ms) to prevent staging buffer accumulation. |
Sources: kaleidux-daemon/src/renderer.rs:985-1010, kaleidux-daemon/src/renderer.rs:1063-1090, kaleidux-daemon/src/main.rs:608-620
2. Transition Execution
When new content is uploaded while a previous wallpaper exists, the pipeline enters a transition state.
- Uniform Updates: The pipeline sends
TransitionUniformsto the GPU, including the currentprogress(0.0 to 1.0), screen aspect ratios, and shader-specific parameters. - Shader Execution: A specialized fragment shader is fetched from the
ShaderManagerand executed, sampling from bothprev_textureandcurrent_textureto produce a result in thecomposition_texture. - Batch Synchronization: Uses
batch_start_timeto synchronize transitions across multiple monitors inSynchronizedorGroupedmodes.
Sources: kaleidux-daemon/src/renderer.rs:15-22, kaleidux-daemon/src/renderer.rs:612-660, kaleidux-daemon/src/renderer.rs:670-690
3. Surface Presentation (Blitting)
The final stage copies (blits) the resolved image to the display surface.
This sequence illustrates the rendering loop, emphasizing the requirement of requesting a frame callback to maintain the display loop.
Sources: kaleidux-daemon/src/renderer.rs:563-590, kaleidux-daemon/src/renderer.rs:885-905
Performance Monitoring and Metrics
The pipeline is instrumented with a PerformanceMetrics system to track resource health and timing.
| Metric | Purpose | Source File |
|---|---|---|
| Frame Timing | Tracks avg, p50, p95, and p99 frame times in ms. | metrics.rs:252-270 |
| Texture Pool Hit Rate | Measures efficiency of texture reuse. | metrics.rs:320-330 |
| Resource Leak Detection | Samples texture and pipeline counts over time to warn of growth. | metrics.rs:385-410 |
| Component CPU Time | Measures microseconds spent in renderer vs video operations. | metrics.rs:200-220 |
Sources: kaleidux-daemon/src/metrics.rs:10-50, kaleidux-daemon/src/metrics.rs:430-450
Implementation Details
Transition Uniforms Structure
The uniform buffer layout is strictly defined for C-compatibility using repr(C).
#[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
struct TransitionUniforms {
progress: f32,
screen_aspect: f32, // width / height
prev_aspect: f32,
next_aspect: f32,
params: [[f32; 4]; 7], // Total 128 bytes (aligned)
}
Sources: kaleidux-daemon/src/renderer.rs:12-20
Multi-Backend Support
The pipeline differentiates between Wayland and X11 through the BackendContext.
- Wayland: Utilizes
LayerSurfaceand requires explicitframe()callbacks from the compositor to drive the render loop. - X11: Directly renders to windows and relies on a target frame time (default ~60 FPS) handled in the main loop since it lacks a native frame callback mechanism.
Sources: kaleidux-daemon/src/renderer.rs:30-35, kaleidux-daemon/src/main.rs:520-540, kaleidux-daemon/src/main.rs:770-790
The WGPU Rendering Pipeline ensures that Kaleidux provides a visually "premium" experience while maintaining the efficiency required for a background daemon. By offloading complex sampling and blending to the GPU, it achieves high-quality transitions even at 4K resolutions.