display: pluggable scanout backend seam (v2 V1)

Extract scanout from the compositor into backend.zig — a `Backend` tagged union
with info()/surface()/present(damage) and canModeSet/hasVsync flags. The v1 GOP
path becomes `backend.Gop` (claim the display node, WC-map the LFB, keep the
cacheable back buffer, present = the damage-rect WC copy); display.zig now
composes into backend.surface() and calls backend.present(damage), with no LFB or
framebuffer geometry left in the compositor core. The selection decision is the
pure chooseKind(native_available), split from the syscall-bound bring-up, ready
for the native-if-present branch at V4.

Pure refactor: display-service, display-demo, and zig build test all pass
unchanged.
This commit is contained in:
Daniel Samson
2026-07-14 09:40:15 +01:00
parent f3342118f5
commit 9333d0572f
3 changed files with 234 additions and 144 deletions
+12 -11
View File
@@ -40,21 +40,22 @@ used ring**. Those two together (pixel-readback + flush-ack) are the automated s
---
## V1 — The scanout backend seam (refactor, no behaviour change)
## V1 — The scanout backend seam (refactor, no behaviour change) ✅
Extract scanout from the compositor so today's path becomes one backend among future ones.
- [ ] A `Backend` interface in `system/services/display/`: `surface() -> {ptr, pitch,
format, width, height}`, `present(damage: Rect)`, and capability flags
(`canModeSet`, `hasVsync`, both false for now).
- [ ] Wrap the v1 GOP path as `GopBackend` (claim the `display` node, WC-map the LFB,
`present` = the current damage-rect WC copy). The compositor composes into
`backend.surface()` and calls `backend.present(damage)` — no direct LFB references
left in the compositor core.
- [ ] Pure backend-selection logic factored so it's host-testable.
- [x] `system/services/display/backend.zig`: a `Backend` tagged union with `info()`,
`surface()` (the cacheable compose target), `present(damage)`, and capability flags
(`canModeSet`/`hasVsync`, both false for GOP).
- [x] The v1 GOP path is now `backend.Gop` (claims the `display` node, WC-maps the LFB,
keeps the cacheable back buffer, `present` = the damage-rect WC copy). display.zig
composes into `backend.surface()` and calls `backend.present(damage)` — no LFB or
framebuffer geometry left in the compositor core.
- [x] The selection decision is the pure `chooseKind(native_available)` (gop unless a
native driver announced), split from the syscall-bound `select()`/`Gop.init()`.
**Gate:** `display-service` + `display-demo` still pass unchanged (pure refactor; GOP is
the only backend), and `zig build test` stays green.
**Gate (met):** `display-service` + `display-demo` pass **unchanged** (pure refactor; GOP
is the only backend), and `zig build test` stays green.
## V2 — The `shm` cross-process memory capability (kernel)