Opt-in VG-Lite compositor checkpoint
Date: 2026-09-23. This is a source and host contract checkpoint, not physical GPU, cache, scanout, interaction, or performance acceptance. The default shell still selects Pixman. The experiment must remain outside the default image.
Pinned interfaces and ownership
wlroots 0.20.2 defines renderer/texture/pass implementations in
include/wlr/render/interface.h and operation fields in
include/wlr/render/pass.h. types/scene/wlr_scene.c:1480-1578 supplies
non-null regions, opacity/luminance pointers, default premultiplied blending,
and default bilinear filtering even for unscaled opaque buffers. Its background
at line 2577 excludes visible opaque scene regions. The renderer supports that
ordinary full-redraw shape, as demonstrated by the host scene-region test.
The renderer locks only the output buffer passed by wlroots. It obtains dma-buf
attributes and a real CPU mapping through that buffer’s API; it never opens
DRM, becomes master, allocates a scanout buffer, modesets, or commits. The
existing Sway/wlroots DRM backend remains responsible for all those operations.
The mapping must match the dma-buf format and stride and remains held until GPU
completion or lifetime quarantine. The SDK refuses vg_lite_map with both a
NULL memory pointer and zero physical address even for its dma-buf flag.
Recording copies clips, opacity, luminance, and primaries. Each texture operation captures immutable RGBA pixels and a paired Pixman texture, so original textures can be updated/destroyed and caller options released before submit. Texture readback/allocation/region-copy failure fails the whole recorded pass; no prefix is submitted. No GPU command occurs while recording.
Current eligibility
Only WLR_RENDERER=vglite selects the fork. GPU submission additionally requires
exactly K230_VGLITE_ALLOW_UNPROVEN_CACHE=1; other strings, including 0,
retain full-pass Pixman replay. This flag acknowledges missing physical proof.
- Target: one linear DRM RGB565 plane, matching dimensions, zero offset, valid
descriptor, adequate 64-byte-aligned stride, checked size, and matching CPU
mapping. It maps to
VG_LITE_BGR565, supported by the prior private-buffer board probe. Other targets replay with Pixman. - Rectangles: opaque colors, converted from the same 16-bit values as Pixman; arbitrary region intersections become disjoint GPU clear rectangles. Alpha rectangles replay with Pixman.
- Textures: CPU-accessible XRGB8888/ARGB8888 input only; arbitrary dma-buf input
is ineligible. Readback uses DRM ABGR8888, whose little-endian bytes are
R,G,B,A, matching the selected
VG_LITE_RGBA8888byte convention. Integer source crops are copied into padded GPU allocations. Integer nearest upscales, or unscaled bilinear (identical sampling), with normal orientation are eligible. Partial texture clips, fractional/downscale geometry, color metadata and extra opacity replay with Pixman. Premultiplied blending is GPU-eligible only for fully opaque sources; otherSRC_OVERcases remain Pixman.NONEreplaces destination RGB with the source’s premultiplied RGB. - Damage: the union of eligible writes must cover the entire target. A typical clipped background plus opaque scene texture is supported. Partial damage replays the complete recorded list with Pixman, preserving undamaged pixels.
- Timelines: neither renderer advertises/implements explicit synchronization. Waits fail recording before source readback; output signals reject begin. Output color transforms and timers also reject begin because paired Pixman cannot implement those contracts. Texture color metadata follows paired Pixman’s existing fallback behavior; the renderer advertises no color transformation feature.
GPU failures after commands start fail submit and permanently disable GPU use in that process; they never start Pixman on the partially written target. The next pass uses Pixman. Every allocated GPU source stays alive through finish. If finish fails, target access/lock, GPU mappings and GPU allocations are quarantined for process lifetime: no free, unmap, close, or buffer reuse can race unproven completion. A process-global mutex serializes the vendor context, including multiple renderer instances.
Vendor cache and geometry audit
SDK pin: kendryte/k230_linux_sdk commit
1104236db4d1e47873bd68924f912747b820228c, under
buildroot-overlay/package/vg_lite/:
VGLite/vg_lite.c:2510:vg_lite_blitcleans/invalidates CPU source memory before queuing.vg_lite_blit_rectat line 2990 omits that cache operation. The renderer consequently crops during upload and usesblit.VGLite/vg_lite_matrix.c:73-106: matrix helpers post-multiply, so scale then translate incorrectly scales the destination translation. The renderer sets the affine matrix explicitly using crop-local coordinates.VGLite/vg_lite_image.c:123-157:upload_buffercopies destination stride bytes per row, potentially reading past a tightly packed source. The renderer instead copies each checked row into the padded allocation itself.VGLite/vg_lite.c:4114-4180: mapping requires a CPU/physical address and maps the supplied dma-buf.finishat line 4298 submits, waits, and then performs target cache maintenance on its normal path. Its error returns establish no quiescence.closeat line 3650 invokes termination; it is not a proven reset after failed completion.- The renderer cleans/invalidates its CPU target before GPU ownership with the
same C908 sequence packaged in
nix/vglite-probe.nix. CPU upload to GPU read, GPU write to CPU read, and GPU write to DRM scanout still require physical observations. Source inspection and a mock cannot prove them.
Host proof and remaining gates
Run the behavior test with the pinned source paths:
WLROOTS_SOURCE=/path/to/pinned-wlroots-0.20.2 \
VGLITE_SOURCE=/path/to/pinned-sdk/buildroot-overlay/package/vg_lite \
tools/test-vglite-renderer.sh
nix build .#shell-compositor-vglite --no-link --print-out-paths
The test compiles the actual renderer and pinned wlroots Pixman pass, uses real
Pixman image operations as its reference, and injects an asynchronous mock VG
API. It checks every output pixel plus padding, source/option lifetime, complete
recording failures, import rejection, source allocation failure before/after GPU
commands, command failures, failed finish quarantine, and following-pass Pixman
recovery under ASan/UBSan. It does not emulate physical GPU rounding or caches.
tools/test-vglite-fallback.py remains only a source wiring check.
Committed host evidence records exact commands, source artifacts, and output package. The OpenSpec tasks for physical RGBA/alpha correctness, cache ownership, live Sway scene use, fallback rates, scanout ownership, interaction and matched performance comparison remain open.