wayray/docs/ai/adr/005-rendering-strategy.md
Till Wegmueller 167c6c17c6
Add project documentation, architecture decisions, and usage book
Comprehensive documentation for WayRay, a SunRay-like thin client
Wayland compositor targeting illumos and Linux:

- CLAUDE.md: project context and conventions
- docs/ai/plans: 6-phase implementation roadmap
- docs/ai/adr: 9 architecture decision records (Smithay, QUIC,
  frame encoding, session management, rendering, audio, project
  structure, illumos support, pluggable window management)
- docs/architecture: system architecture overview with diagrams
- docs/protocols: WayRay wire protocol specification
- book/: mdbook user guide (introduction, concepts, server/client
  guides, admin, development)
- RESEARCH.md: deep research on remote display protocols
2026-03-28 20:47:16 +01:00

72 lines
2.9 KiB
Markdown

# ADR-005: Rendering Strategy
## Status
Accepted
## Context
The WayRay server compositor must render Wayland client surfaces into a framebuffer for network transmission. The server may or may not have a GPU. The rendering path must support efficient framebuffer capture.
## Options Considered
### 1. GlesRenderer only (GPU required)
- Hardware-accelerated compositing
- ExportMem via glReadPixels (GPU -> CPU readback)
- Requires EGL/OpenGL ES 2.0 capable GPU on server
- Can feed DMA-BUF directly to hardware video encoder (zero-copy)
### 2. PixmanRenderer only (CPU software rendering)
- Pure software rendering, no GPU needed
- ExportMem is essentially free (pixels already in CPU memory)
- Lower throughput for complex scenes
- Perfect for headless server deployments (cloud VMs, containers)
### 3. Dual renderer with runtime selection
- PixmanRenderer as default/fallback
- GlesRenderer when GPU is available
- Configuration-driven or auto-detected
- Covers both headless and GPU-equipped deployments
## Decision
**Dual renderer with runtime selection.** PixmanRenderer as the default, GlesRenderer when a GPU is available and the admin opts in.
## Rationale
- Many server deployments are headless VMs or containers without GPUs
- PixmanRenderer gives us zero-overhead framebuffer capture (no GPU readback needed)
- GlesRenderer + DMA-BUF export to VAAPI enables zero-copy hardware encoding
- The Smithay Renderer trait makes both interchangeable
- Niri and cosmic-comp demonstrate this dual-renderer pattern successfully
## Rendering Pipeline
### PixmanRenderer path (default)
```
Wayland clients commit surfaces
-> PixmanRenderer composites all surfaces into output buffer
-> OutputDamageTracker identifies changed regions
-> copy_framebuffer() returns pixels (zero-copy, already in RAM)
-> Frame encoder processes damaged regions
-> Transmit to client
```
### GlesRenderer path (GPU available)
```
Wayland clients commit surfaces (may use DMA-BUF)
-> GlesRenderer composites via OpenGL ES
-> OutputDamageTracker identifies changed regions
-> Option A: copy_framebuffer() via glReadPixels -> CPU -> encode
-> Option B: DMA-BUF export -> VAAPI encoder (zero-copy)
-> Transmit to client
```
## Frame Cadence
- Render on damage (not fixed rate): only render when clients commit new content
- Cap at client's display refresh rate (sent during capability exchange)
- During suspension (no client connected): stop rendering entirely
- Coalesce rapid commits: batch within ~4ms window to avoid excessive rendering
## Consequences
- PixmanRenderer cannot handle GPU-only client buffers (DMA-BUF with no CPU-accessible format)
- Mitigation: advertise only SHM formats when running with PixmanRenderer
- glReadPixels is a synchronization point that stalls the GPU pipeline
- Mitigation: use PBO (Pixel Buffer Objects) for async readback
- Dual renderer adds code complexity; managed via Smithay's trait-based abstraction