Expand description
Headless backend for CPU-only rendering without a display server.
Used with AZUL_HEADLESS=1 for E2E testing, CI, and screenshot capture.
Headless backend for CPU-only rendering without a display server.
This module provides the resource management and rendering pipeline for
running Azul applications without any platform windowing APIs. It works
in combination with HeadlessWindow (in dll/src/desktop/shell2/headless/) which
provides the PlatformWindow trait implementation.
§Architecture
The headless backend replaces the WebRender GPU pipeline with a purely CPU-based approach. Here’s how each resource type is managed:
┌──────────────────────────────────────────────────────────┐
│ Normal (GPU) Path │
│ │
│ LayoutWindow ──→ DisplayList ──→ WebRender ──→ GL │
│ │ │ │
│ │ RenderApi ←─── Renderer │
│ │ (font/image │ │
│ │ registration) AsyncHitTester │
│ │ │
└──────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Headless (CPU) Path │
│ │
│ LayoutWindow ──→ DisplayList ──→ cpurender ──→ PNG│
│ │ │ │
│ │ HeadlessResources (agg-rust │
│ │ (font/image Pixmap) │
│ │ management) │
│ │ CpuHitTester │
│ │ │
└──────────────────────────────────────────────────────────┘§Key Differences from GPU Path
| Concern | GPU Path | Headless Path |
|---|---|---|
| Window | NSWindow / HWND / X11 | HeadlessWindow (no-op) |
| OpenGL | GlContextPtr | None |
| Renderer | webrender::Renderer | None (skip) |
| RenderApi | WrRenderApi | None (skip) |
| Hit Testing | AsyncHitTester (WR) | CpuHitTester (layout) |
| Font Registration | RenderApi::add_font() | FontManager only |
| Image Registration | RenderApi::add_image() | ImageCache only |
| Frame Generation | generate_frame() + WR | generate_frame() only |
| Screenshot | glReadPixels | cpurender → Pixmap |
| Display List | WR DisplayList | solver3 DisplayList |
| Present/Swap | swapBuffers | no-op |
§Resource Lifecycle (Headless)
Fonts and images are managed entirely through LayoutWindow:
Font Loading:
1. FcFontCache discovers system fonts (same as GPU path)
2. FontManager loads + caches parsed fonts
3. TextLayoutCache shapes text and caches glyph positions
4. cpurender reads glyph outlines directly from ParsedFont
(no GPU texture atlas needed)
Image Loading:
1. ImageCache stores decoded images (same as GPU path)
2. cpurender blits pixels directly from DecodedImage
(no GPU texture upload needed)§Usage
The headless backend is activated by setting AZUL_HEADLESS=1:
AZUL_HEADLESS=1 ./my_azul_appOr combined with the debug server for remote inspection:
AZUL_HEADLESS=1 AZ_DEBUG=1 ./my_azul_appStructs§
- CpuHit
Tester - CPU-based hit tester that works without WebRender.
- Headless
Config - Configuration for headless rendering.
- Headless
Renderer - Headless renderer for CPU-based screenshot capture.