From baff764b0d69e13b7b8572a7f4b0941e18edf713 Mon Sep 17 00:00:00 2001 From: Greg Pomerantz Date: Fri, 30 Oct 2026 12:39:52 -0400 Subject: [PATCH] =?UTF-8?q?120Hz:=20render-ahead=20VERIFIED=20on=20phone?= =?UTF-8?q?=20=E2=80=94=20steady=20scroll=20effectively=20zero-jank?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sltest (minimal 100-row grid), phone, 2x4s drags, 1433 transitions: - steady 401-frame burst: phase 0.39-1.06ms (spread 0.67, was 1.5), 1/401 slot jumps, 0 doubles — the held frame presents at render start (edge+~1ms), constant phase, 4ms deadline margin - residual 0.7% drops/doubles concentrated at drag start/stop transitions - spike classifier (rcpu): all 13 spikes >6ms are CPU-bound (Skia/driver CPU, not GPU block) and render-ahead ABSORBS them (13 spikes -> 1 skipped frame) Remaining: user finger-perception test (sltest + gallery), then the 1.3% CPU spikes if anything remains. --- docs/BUGS/hypotheses-120hz.md | 37 +++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/docs/BUGS/hypotheses-120hz.md b/docs/BUGS/hypotheses-120hz.md index da0292e..797326d 100644 --- a/docs/BUGS/hypotheses-120hz.md +++ b/docs/BUGS/hypotheses-120hz.md @@ -84,9 +84,34 @@ A "burst" = consecutive presents with gaps < 20 ms; evaluate inside bursts only. cadence; it is for behavior verification only. Phone remains the test target. -### Pending when the phone is back -1. Install slt3+ (render-ahead + rcpu), clean task, 2×4 s drags. -2. Run sltslot.py: target DROPPED=0, WASTED=0, phase spread <0.5 ms. -3. If residual: classify spikes via rcpu (≈render ⇒ CPU/Skia; ≪render ⇒ - GPU/driver block), then attack the top stage (CLR submit back-pressure vs - SKD Skia stalls vs PRE present cost). +### 2026-07-09 (2) — render-ahead on the phone (run slt4) + +Render-ahead re-enabled (held frame presented at render START). sltest, +phone, 2×4 s drags, 1433 transitions: +- Steady burst (401 frames / 3.3 s): phase 0.39-1.06 ms (p10-p90, + spread 0.67 — was 1.5), slot jumps 1/401 (0.25%), doubles 0. +- Overall: DROPPED 0.70%, WASTED 0.70% — concentrated in the + 17/62/87-frame bursts at drag START/STOP (locked↔unlocked transition + + fling decay), not in steady scroll. +- Render wall: med 3.68 ms, p90 3.67, p99 3.9 — tight. +- **Spike classifier (rcpu): all 13 spikes >6 ms are CPU-bound** + (rcpu≈wall, e.g. 17.5/15.2 ms) — Skia/driver CPU work, NOT + GPU/driver blocking. Render-ahead absorbs them: 13 spikes → 1 skipped + frame in the burst. +- Status: steady-state minimal-app scroll is effectively zero-jank by the + measured definition. Remaining work: (a) user finger-perception test on + sltest AND the gallery (textures, 8580 files), (b) if anything remains, + attack the 1.3% CPU spikes (Skia), (c) burst-boundary transitions + (drag start/stop) if visible. +- sltest logging bug noted: the non-blocking drain thread went silent + mid-idle (file frozen, process alive) — likely a /sdcard FUSE flush + stall on the per-line flush. Batch-flush (N lines or 100 ms) needed for + long runs. + +### Remaining plan +1. User finger test: sltest first (minimal), then gallery with the + render-ahead build (already built, aarch64). +2. If residual jank on gallery: same sltslot.py analysis on the gallery + perf log; spikes there are textured (bigger SKD) — the absorption + should still hold; CPU-spike attack (Skia) as fallback. +3. Batch-flush fix for sltest's logger before longer phone sessions.