evidence · 6.1 KiB

README.md

Committed at docs/evidence/theme-picker/row-sprites-2026-10-12/README.md. This is what grounds the requirements that cite it.

Open raw source

Theme-row repaint as cached card sprites, 2026-10-12

Task 14.4 follow-up in change the-shell-swaps-themes-without-a-python-stall.

The operator reported, on the panel, that “it’s really janky moving between theme cards and it shouldn’t be”. This directory records the board measurements behind the fix, the install, and the operator’s response.

The source is branch perf/theme-row-paint, in worktree /home/jadams/tmp/k230-row-paint. The commits are:

Times are UTC.

Evidence classes:

No camera observation is claimed.

Measurement

swap-and-swipe-used.py ran as root over SSH. For each run it does the following:

  1. Points shell-ui at a given shell ELF through a non-persistent /run drop-in.
  2. Sets K230_TRACE_COUNTERS_ONLY=1 with a 55 s window.
  3. Opens Settings → Themes.
  4. Injects eight horizontal swipes on the theme row through a temporary K230 injected touchscreen.

Runs that left an empty trace are not counted. Those runs overlapped a restart and were repeated.

LabelShell ELFTrace files
oldinstalled k2z9z61k… (master 24804e19)old-3, old-4, old-5
first fixljrsf4… (f11c86fe)new-2, new-3, new-4
spriteb0yyyda8… (4d17b3c5)sprite-1, sprite-2

The table shows picker_row_repaint in the moving phase, plus scene_rebuild counts in the held and moving phases. All traces report dropped: 0.

RunRepaintsCPU / repaintWall / repaintMax wallFull rebuilds
old-34981.0 ms98.6 ms125.9 ms6
old-45179.4 ms101.0 ms124.7 ms6
old-55179.8 ms101.7 ms131.5 ms6
new-24675.1 ms120.2 ms246.4 ms0
new-35474.6 ms95.5 ms142.9 ms0
new-44477.1 ms122.3 ms225.6 ms0
sprite-19130.1 ms42.9 ms66.1 ms0
sprite-29230.4 ms43.5 ms87.4 ms0

The first fix removed the mid-swipe full rebuilds but barely changed the cost of each row repaint.

A board profile of the first-fix build (1,736 cpu-clock samples) showed:

On this RISC-V pixman, a clipped or anti-aliased fill whose source is a scaled surface takes the general per-span path. The sprite commit instead renders each card once into a cached surface and blits it untransformed. The scaled image, the scrim and the skewed rounded outline mask are all baked into that surface.

The sprite build roughly halves the repaint wall time and draws about 1.8 times as many frames during the same swipes. It is not 60 fps: the two cards that change size during a swipe are re-rendered each frame.

sprite-build-picker-native.png is a native grim -s 0.5 capture of the sprite build at rest. The theme cards, the Backgrounds row and the labels draw correctly.

The kanagawa theme shown there was applied durably at 08:11:43 through the theme socket, during one of the old-build runs. It was either an operator tap or a stray injected tap. It was left in place and is the baseline appearance of the install below.

Install

IdentityValue
Bundle/nix/store/60azv75vjpgcshjwh9kdhz12h4r9i8d0-k230-coherent-shell-boot-files
System/nix/store/rav09qp6dwsnbjd2jrbcs595g9ayn3xf-nixos-system-nixos-26.11.20260919.20b1ddd
Rust shell ELF/nix/store/b0yyyda8l7nqix1jb95kbmhh9s5mqnj0-k230-shell-rust-riscv64-unknown-linux-gnu-0.1.0/bin/k230-shell-rust
Kernel, Image, initrd.uimgunchanged from the baseline
Baselinedefault-backgrounds install cwfx0amr… (../default-backgrounds-2026-10-12/)

The build ran with flock /tmp/k230-nix-build.lock nix build .#kernelMainlineDrmShellBootFiles --out-link ~/.local/state/tdisplay-k230/retained-builds/row-paint-2026-10-12/candidate2 --print-out-paths --max-jobs 1 --cores 4 at 4d17b3c5 and exited 0.

The /run drop-in was removed, and shell-ui was restarted on the installed k2z9z61k… before the preflight.

The coherent installer then ran with the default-backgrounds recipes. Only the paths, the baseline, and the saved kanagawa appearance in expected-runtime.json differ (see the *-used.py files). Every step passed:

  1. Preflight: boot a563b9fb-…, 14:37:47 (preflight.json).
  2. Stage: (stage.log, transfer.json, staged-state.json, host-inspection.json).
  3. Candidate boot: (candidate-boot.json). The runtime check ran on boot 777f5a20-… at 14:42:40 (candidate-runtime.json).
  4. Qualification: (deployment-authorization.json).
  5. Install and ordinary autoboot: (ordinary-boot.json). The runtime check ran on boot 49fb3850-… at 14:45:55 (ordinary-runtime.json). The current system and profile are both rav09qp6…, the four shell services are active, and the saved appearance is unchanged.

The operator tried the build through the /run drop-in, before this install. No finger observation was made on the installed boot.

Operator report

After using the sprite build on the panel (temporarily swapped in through the /run drop-in), the operator wrote: “it’s good to go land it”.

This is a real-finger acceptance of the theme-row feel for landing. It does not separately state the four curve properties that task 18.4 names, and it does not cover the matched comparison of tasks 11.3 and 13.