evidence · 5.2 KiB

README.md

Committed at docs/evidence/vglite-scene-board/context-lifetime/README.md. This is what grounds the requirements that cite it.

Open raw source

Retain the serialized GPU context across frames

The board cost profile measured about 107 ms of initialization/cleanup in a 149 ms GPU pass. Pinned kernel source confirms that opening and closing its last context triggers clock/reset sequences with sleeps. The opt-in renderer now retains one process-global context under its existing mutex and closes it when the last renderer owner is destroyed.

Only clear and image-blit operations are admitted. Initialization uses (0, 0) to omit unused tessellation storage; the pinned SDK demonstrates this in test/samples/imgIndex/main.c and imgIndex.c. Its VGLite/vg_lite.c set_render_target updates target dimensions per pass, so output-size changes do not depend on tessellation dimensions. Source ownership, per-pass imported targets, whole-pass replay, and explicit finish before release are unchanged.

A failed finish still disables GPU use and quarantines context, source memory, and target mapping for process lifetime. Last-owner destruction does not call close in that state. A failed shutdown close similarly prevents a second close or reinitialization; future renderer instances use Pixman. Successful final shutdown permits a later new owner to initialize a fresh context.

The ASan/UBSan production-renderer suite passes. New tests cover repeated frames at different dimensions, two renderer owners, first-owner destruction, last-owner close, subsequent reinitialization, shutdown-close failure, and last-owner destruction after failed-finish quarantine. Existing exact Pixman pixel, crop, scale, fallback, and failure tests remain passing.

TMPDIR=/mnt/MediaVolume/home/jadams \
WLROOTS_SOURCE=/nix/store/r2zcb3d3dgmz09qjaqsy945inal2h41r-source \
VGLITE_SOURCE=/nix/store/pvpqrg3diyi9mcgmqjc0f80hpdmk699p-source/buildroot-overlay/package/vg_lite \
  tools/test-vglite-renderer.sh
nix build .#shell-compositor-vglite --max-jobs 1 --cores 8 --no-link --print-out-paths

The narrow cross-build passes: /nix/store/rr671hlb8pg35qx2fl9hwxl42rlj7bgg-sway-1.12. Board cost, capture and recovery comparisons are recorded below. Retaining a context also retains its allocations and active device clock state between frames; idle-power impact is unmeasured. This is still opt-in, with the normal shell on Pixman and every broader acceptance gate unchanged.

Three paired board repeats

On 2026-09-23, the candidate at source f656f199059a ran three GPU/forced-Pixman pairs on the same boot, with the same animated SHM parent/child client, native 568x1232 RGB565 output and padded allocation. scene-check.py records the 45-second watchdog and 30-second client commands. Each round-N directory contains original fixed-schema cost/decision logs, exact executable and system identities, two native captures per mode, parser summaries and a palette check. The first 20 frames are excluded from timing aggregates; each run retains at least 470 measured frames. All six runs returned zero, observed one Sway process and restored both normal shell and seatd. GPU runs had zero Pixman replays.

RoundGPU framesPixman framesGPU mean wall/passPixman mean wall/passGPU mean process CPU/passPixman mean process CPU/pass
149557143.959 ms36.242 ms37.046 ms32.471 ms
249256644.191 ms36.647 ms37.259 ms32.594 ms
349056744.452 ms36.523 ms37.205 ms32.646 ms

Compared with the earlier 149.210 ms GPU baseline, mean render-pass wall time fell about 70%. Steady-state initialization plus cleanup fell from about 106.7 ms to 0.55–0.58 ms. GPU completion remains about 2.38 ms. All three parent/child palette comparisons pass exactly, including the later captures. This compares stable region colors across different animation frames, not whole-frame equality or every format/blend/scale/cache case.

The GPU path still loses to its paired fallback: about 21% more wall time and 14% more process CPU per pass. Immutable snapshots cost about 20 ms wall time and allocation/conversion/upload another 17 ms. Source preparation is therefore the next measured bottleneck; claiming an offload benefit or changing the normal default would be premature. Frame counts are completed diagnostic render passes, not optical refresh or input latency. This fixed GPU-then-Pixman order is not a randomized benchmark, and process CPU excludes separately accounted IRQ and whole-device cost. Ordinary-service access, the normal renderer comparison, physical controls, idle power and broader correctness gates remain open; no proposal task is closed by this diagnostic alone.

python3 tools/vglite-cost.py \
  docs/evidence/vglite-scene-board/context-lifetime/round-1/gpu/costs.log \
  --minimum-frames 100 --discard-frames 20
python3 docs/evidence/vglite-scene-board/context-lifetime/round-1/analyze-palette.py
# Repeat for rounds 2 and 3; parse both modes.

The transferred archive SHA256 matched the board: 54d86bdc243adfb95ef38c74466d2ff0ebdd8b630372fbc620be37aefbe46428. Only the named results, fixed-schema logs and captures were transferred; raw service logs remain private. The normal shell and seatd were checked active again after collection. No board reboot, image replacement or real-finger observation was performed.