← Blog

The Lumen Compositor: Accelerated Present Path in sigilOS

June 22, 2026 · sigil-video · Sigil-Docs
lumen compositor gpu video 0.6.0

The Lumen window manager's accelerated present path is now x86-verified: opaque blit, semi-transparent composite, and right-edge clipping all pass. This is the final seam that connects surface allocation in VRAM to pixel delivery on screen, completing the rendering chain the desktop compositor rides for every frame.

Lumen compositor gpucomp test on x86
GPUCOMP-PASS x86 — opaque blit + src-over composite verified

The rendering chain

Every pixel on the Lumen desktop travels through a fixed pipeline from draw call to scanout. The accelerated present path (present_accel) is the last stage — it takes a composited surface and puts it on screen.

1
Surface allocation gpu_fb_alloc(w,h) — VRAM bump at 0x3C0000, returns base + pitch. GPU MMU BO on accel backend; CPU-accessible bump on software floor.
2
Draw into surface App (or WM chrome) writes pixels into the allocated surface — fill_span, text, UI widgets. Cap gate: only the capability holder can write to the display surface.
3
Compositor blend comp_blit (opaque spans) or comp_composite (src-over alpha blend) merge window surfaces into the desktop framebuffer in stacking order.
4
Present (accel path) present_window_accel / present_window_composite_accel copy the composited region to the scanout framebuffer with right-edge clipping. This is the verified seam.
5
Scanout / DSO overlay fb_flip (syscall 37) triggers pre-flip overlay_present(), compositing any live Direct-Scene Overlay buffers, then hands the framebuffer to the display controller.

present_window_accel: opaque blit

present_window_accel(src, src_pitch, dst, dst_pitch, dx, dy, w, h) copies a rectangular region of pixels from a window surface into the scanout framebuffer with no alpha blending — it's the fast path for opaque windows like the terminal or a full-screen game.

Under the hood it calls comp_blit for each row: a copy_span that copies w pixels starting at src[dy*src_pitch + dx] into dst[dy*dst_pitch + dx]. On the GPU path, this is a DMA blit; on the software floor it's a word-by-word copy. Either way the output is identical.

Right-edge clipping is handled before the blit: if dx + w > scanout_width, w is clamped to scanout_width - dx. The test verifies this with dx=78 on a 4-pixel-wide window with scanout_width=80 — only columns 78 and 79 land.


present_window_composite_accel: src-over blend

present_window_composite_accel is the semi-transparent path — shadows, translucent panels, notification overlays. It calls comp_composite for each row, which implements the standard Porter-Duff src-over formula per channel:

out = (src * a + dst * (255 - a)) / 255

The test uses a source alpha of A=64 (25% opaque) over a white (255,255,255) background. The oracle values:

Blue channel
src_b=0, dst_b=255, A=64
(0×64 + 255×191) / 255
ob = 191
Green channel
src_g=0, dst_g=255, A=64
(0×64 + 255×191) / 255
og = 191
Alpha channel
src_a=64, dst_a=255, A=64
255 (composited output fully opaque)
oa = 255

These are the exact values the test asserts. Any deviation from the Porter-Duff formula — rounding error, wrong channel order, integer overflow — shows up immediately in the oracle check.


DSO overlay integration

A variant of the present path, present_window_accel_ovl, punches holes in the scanout blit for Direct-Scene Overlay regions. Overlay slots are read from ovl_buf() at 0x929000 — the same scratch address the Kernel's overlay registry writes to. The hole-punch ensures that when Kernel's overlay_present() runs at pre-flip time, it composites into a clean region rather than over a stale blit.

This completes the DSO overlay pipeline: Kernel allocates overlay slots (syscall 103), the OS WM absorbs live overlays as managed windows, and the Video present path punches the scanout holes. Three repos, one coherent pipeline.


GPU-first, software floor always present

The accelerated present path follows the same dual-backend rule as every other Video seam. hal_accel() returns 1 if a GPU primary is available and 0 if the software floor is active. Both backends call the same comp_blit and comp_composite functions — the difference is that the GPU path issues DMA commands while the software floor does scalar copies. The Lumen compositor calls present_window_accel regardless of which backend is live; the HAL routes appropriately.

The PACCEL test runs on the software floor (QEMU x86 has no GPU DMA), which means the oracle values verify the floor path exactly. The GPU path produces identical output by construction — same formula, faster execution.

Accelerated present path on x86
PACCEL-PASS x86 — accelerated present path with DSO overlay hole-punch