Go to file
Greg Pomerantz 01c15795ff 2ms poll cap during active scroll + record_check.py (display-side referee)
2ms cap (vendor backend): the residual 8/1266 phone slip-frames all
correlated with polls that ran 5.5-10.7ms despite the 6ms cap
(ALooper_pollOnce(6) returns 2-5ms LATE on this device — the delay is
inside kernel/epoll; vsw=nvol=0 on every slip iteration, so the UI
thread was never descheduled mid-iteration). A 2ms cap bounds the
damage of a lost/late wake: the next poll picks up the pending edge
within 2ms → render start edge+2-3ms → present inside the slot.
Emulator A/B (2 vs 6ms): no difference (5-8 drops/capture both ways,
vs 47-147 for the pre-evfd build) — the evfd wake-fd fix dominates;
the shorter cap is kept.

tools/record_check.py: the DISPLAY-side referee. jank_capture judges
the app's self-report; this records the actual display output with
`adb shell screenrecord` (30 Mbps) during scripted (or hand) drags and
measures inter-frame gaps in the mp4:
  * median refresh period is computed from ACTIVE-WINDOW gaps only —
    rest periods emit idle frames at irregular 20-100ms intervals that
    would pollute the reference (found during validation)
  * active windows come from real wall-clock drag times (1.5s pad)
  * verdict: CLEAN (0 gaps >1.8x med), SUSPECT (1.25-1.8x), JANK
  * selftest: 4 cases incl. drop-in/outside-active-window + real
    ffmpeg 120fps mp4 through the ffprobe pipeline
Validated end-to-end on the emulator (record → drags → pull → analyze).
When the phone is free: one `record_check.py record --app wow.gmp.sltest
--drags 4,2,4` run gives the visual-certain answer the user asked for —
did the glass actually show every frame?
2026-10-30 16:40:09 -04:00
docs/BUGS 120Hz: jank_eval referee + slot-based wake guard + MISS ledger 2026-10-30 13:29:50 -04:00
scripts Fix 120Hz scroll jank end-to-end: render-ahead present + full-cache eviction off the UI thread 2026-10-30 02:49:23 -04:00
shim Fix 120Hz scroll jank end-to-end: render-ahead present + full-cache eviction off the UI thread 2026-10-30 02:49:23 -04:00
src 120Hz: jank_eval referee + slot-based wake guard + MISS ledger 2026-10-30 13:29:50 -04:00
tools 2ms poll cap during active scroll + record_check.py (display-side referee) 2026-10-30 16:40:09 -04:00
vendor 2ms poll cap during active scroll + record_check.py (display-side referee) 2026-10-30 16:40:09 -04:00
.gitignore Fix 120Hz scroll jank end-to-end: render-ahead present + full-cache eviction off the UI thread 2026-10-30 02:49:23 -04:00
build.rs M0: Slint gallery scaffold + development hand-off 2026-10-27 12:22:59 -04:00
Cargo.lock Fix 120Hz scroll jank end-to-end: render-ahead present + full-cache eviction off the UI thread 2026-10-30 02:49:23 -04:00
Cargo.toml Fix thumbnail pop-in: hold-queue for paint-cap overflow + append-only scan streaming + window-liveness watchdog 2026-10-30 09:04:01 -04:00
HANDOFF.md handoff: section 8.10 — the zero-jank perf tooling (jank_eval + jank_capture) 2026-10-30 14:46:37 -04:00
LICENSE Initial commit 2026-10-27 12:13:22 -04:00
README.md M1: metadata scan + sqlite DB + placeholder list 2026-10-27 13:28:33 -04:00

gallery

A high-performance image gallery for Android (primary), Linux and macOS — Rust + Slint 1.18.

Status: M1 (metadata scan + DB) done. See HANDOFF.md — the development hand-off with the full plan: architecture, thumbnail pipeline, milestones M1–M7, Slint gotchas, permission flow, and performance targets. Next: M2 (thumbnail engine).

Build

./scripts/build.sh debug     # debug x86_64 APK + install on emulator
./scripts/build.sh           # release x86_64 (emulator)
./scripts/build.sh aarch64   # release aarch64 (device)
cargo run                    # desktop (Linux needs libfontconfig1 + pkg-config)

Requires: Rust (rustup), cargo-apk2, Android SDK + NDK 27 (see HANDOFF.md §3 for exact paths/env).

License

GPL-3.0 (see LICENSE). Built on Slint, used under the Slint royalty-free license for proprietary apps (see HANDOFF.md §10.4).