fix(android/hud): stop charging the compositor's wait to the stream #61

Merged
enricobuehler merged 1 commits from worktree-android-hud-os-floor into main 2026-08-05 20:31:48 +00:00
Owner

The Android HUD headlined capture→displayed with SurfaceFlinger's latch
and scanout inside it — pipeline depth no client can pace under. The usual
Android streaming overlays stop measuring at decode-complete, so users
comparing overlays read our honesty as latency: on a 60 Hz panel that floor
alone clears 30 ms, more than everything those overlays display put together.

Exclude it, the way the Apple clients have since the presentation rebuild
(8a40e467): shave the measured floor off the shown display and end-to-end at
every tier, and name what came off in Detailed as os present +N excluded (display pipeline minimum). The equation still tiles the headline, because
the display term is shaved by the same amount.

The floor is the latch p50 we already measure (release→OnFrameRendered),
not a modelled 2/refresh: it moves with the panel rate, tunnelled playback
and the vendor's low-latency mode, and it exists on every render path (the
release stamp is parked on all three), so it does not depend on the timeline
presenter being active. Unmeasured reads 0.0 and nothing is shaved — we
exclude only what we actually measured. With the floor out, the display
term is already just pace, so the (pace + latch) split now renders only
on a window where no latch sample paired, and the hardcoded 2-refresh
Apple-equivalence twin is gone with it.

Raw numbers are untouched in the 1 Hz pf.present logcat line, so HUD-off
A/Bs and cross-session comparisons still read unshaved values.

The Android HUD headlined `capture→displayed` with SurfaceFlinger's latch and scanout inside it — pipeline depth no client can pace under. The usual Android streaming overlays stop measuring at decode-complete, so users comparing overlays read our honesty as latency: on a 60 Hz panel that floor alone clears 30 ms, more than everything those overlays display put together. Exclude it, the way the Apple clients have since the presentation rebuild (8a40e467): shave the measured floor off the shown display and end-to-end at every tier, and name what came off in Detailed as `os present +N excluded (display pipeline minimum)`. The equation still tiles the headline, because the `display` term is shaved by the same amount. The floor is the `latch` p50 we already measure (release→OnFrameRendered), not a modelled 2/refresh: it moves with the panel rate, tunnelled playback and the vendor's low-latency mode, and it exists on every render path (the release stamp is parked on all three), so it does not depend on the timeline presenter being active. Unmeasured reads 0.0 and nothing is shaved — we exclude only what we actually measured. With the floor out, the `display` term is already just `pace`, so the `(pace + latch)` split now renders only on a window where no latch sample paired, and the hardcoded 2-refresh Apple-equivalence twin is gone with it. Raw numbers are untouched in the 1 Hz `pf.present` logcat line, so HUD-off A/Bs and cross-session comparisons still read unshaved values.
enricobuehler added 1 commit 2026-08-05 20:31:26 +00:00
fix(android/hud): stop charging the compositor's wait to the stream
ci / web (pull_request) Successful in 1m24s
ci / docs-site (pull_request) Successful in 3m21s
ci / rust-arm64 (pull_request) Successful in 3m30s
android / android (pull_request) Successful in 9m40s
ci / rust (pull_request) Successful in 16m25s
a11c672bea
The Android HUD headlined `capture→displayed` with SurfaceFlinger's latch
and scanout inside it — pipeline depth no client can pace under. The usual
Android streaming overlays stop measuring at decode-complete, so users
comparing overlays read our honesty as latency: on a 60 Hz panel that floor
alone clears 30 ms, more than everything those overlays display put together.

Exclude it, the way the Apple clients have since the presentation rebuild
(8a40e467): shave the measured floor off the shown display and end-to-end at
every tier, and name what came off in Detailed as `os present +N excluded
(display pipeline minimum)`. The equation still tiles the headline, because
the `display` term is shaved by the same amount.

The floor is the `latch` p50 we already measure (release→OnFrameRendered),
not a modelled 2/refresh: it moves with the panel rate, tunnelled playback
and the vendor's low-latency mode, and it exists on every render path (the
release stamp is parked on all three), so it does not depend on the timeline
presenter being active. Unmeasured reads 0.0 and nothing is shaved — we
exclude only what we actually measured. With the floor out, the `display`
term is already just `pace`, so the `(pace + latch)` split now renders only
on a window where no latch sample paired, and the hardcoded 2-refresh
Apple-equivalence twin is gone with it.

Raw numbers are untouched in the 1 Hz `pf.present` logcat line, so HUD-off
A/Bs and cross-session comparisons still read unshaved values.
enricobuehler merged commit 4b1ce6b905 into main 2026-08-05 20:31:48 +00:00
enricobuehler deleted branch worktree-android-hud-os-floor 2026-08-05 20:31:54 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unom/punktfunk#61