handoff: section 8.10 — the zero-jank perf tooling (jank_eval + jank_capture)

This commit is contained in:
Greg Pomerantz 2026-10-30 14:46:37 -04:00
parent a68c8996c6
commit 5309269651

View File

@ -760,6 +760,43 @@ Instrumentation (`FR`, `STG`, `DECODE`) is gated behind the `--features perf`
Cargo feature so production builds have zero runtime overhead. Detailed bug notes
and analysis are preserved in `docs/BUGS/scroll-jank-120hz.md`.
### 8.10 Zero-jank campaign: the reliable perf tool (2026-10-30)
The zero-jank work needed a referee that cannot be argued with. Two tools:
- **`tools/jank_eval.py`** — the strict referee. Slot grid built from the
hardware VSYNC edges in the log (not the app's clock); a window is PASS
only with: no dropped slot, no same-slot double, no present past latch
(+5 ms edge phase), no >20 ms present gap, phase p10-p90 ≤ 0.5 ms.
7-case self-test (`--selftest`). Exit 0=PASS, 1=FAIL, 3=SUSPECT.
- **`tools/jank_capture.py`** — owns the whole capture pipeline so
provenance can never be wrong:
`python3 tools/jank_capture.py capture --app wow.gmp.sltest --drags 4,2,4 --tag <build> --tag-file <apk>`
records build identity → force-stops → **deletes the log** (the file can
then contain exactly ONE process) → cold-launches → verifies
ResumedActivity → scripted drags → pulls the complete log → reports
PROVENANCE + jank verdict + **MISS forensics** (each miss episode
classified: CHAIN-STALL / LOOP-STUCK / GUARD-REJECT / NO-WAKE-ITER,
with the ±33 ms all-thread context: UI loop, vsync thread, workers,
slow C calls, IO). Exit: 0=PASS, 1=FAIL/INVALID/SUSPECT.
`jank_capture.py report FILE` re-analyzes any captured log.
Both validated on the emulator (x86_64, 60 Hz SF): capture pipeline
×3 drag profiles, pause/resume mid-drag, determinism, multi-process
→ INVALID, explicit windows, period override, no-VSYNC → SUSPECT path,
small-log and PASS paths. Stress-testing found and fixed a circular
auto-window threshold (a janky app's low present rate hid it as
"inactive"), a BUCK multiplier bug, and a useless fallback period fit.
**Zero-jank status (phone, sltest):** phase locked (single wake source:
Choreographer; early waker disabled — it raced Choreographer and caused
±4 ms wander). Remaining issue: 20-40 ms chains of lost wakes (the
Choreographer callback chain breaks); every frame that RAN took 3.7 ms
(6 ms budget) — the CPU mystery is answered: no missing CPU work, the
jank is frames that never ran. Next phone run: `jank_capture.py capture
... --tag <build>`; the MISS forensics (sw/sn/eage/lastage fields)
will classify each break.
### 8.8 Jank-hunt round 2 + the keep-alive incident (2026-10-28)
Follow-up on "still seeing jank" (post-GPU-texture). Instrumentation: