The reported 'fast scroll → stop → long shimmer → small move → everything pops' survived the first fix (scroll-handler re-submission) and the second (central-queue prepend): re-submission only happened in on_scroll, and the workers' FIFO mpsc still held stale transit work ahead of fresh batches. Root causes and the full redesign: - on_scroll now ONLY records the viewport (zero work). The 10 Hz tick is the sole authority AND sole submitter: CONSUME (paint viewport results, capped), EVICT (far pixels, MAX_PAINTED=120), FILL (viewport, center-first), PRUNE (queued jobs outside the retention band). - Invariant restored unconditionally each tick and debug_asserted: every viewport cell is PAINTED, IN-FLIGHT, or FAILED. A visible cell is empty only while its decode is genuinely in flight — never until the next scroll event. - Worker queues: Mutex<VecDeque>+Condvar (mpsc is FIFO-only). The dispatcher drains the central queue as priority-ordered bursts and PREPENDS them, so fresh viewport work always jumps ahead of stale transit work. Per-worker cap (96) drops the oldest tail with a 'skipped' result (UI clears the in-flight marker; re-entry re-submits — disk-cache hit, never a re-decode). A burst (<= viewport ~45) always survives the cap. Stress-verified on the emulator (debug build) before phone deployment: - fast up/down x5 (the repro): fully covered 0-119 ms after stop - cold landings: 1.0-1.2 s = pure decode throughput (p rises monotonically while stale jobs wait behind, harmlessly) - chaos x6 + 25 s idle soak: covered before every stop; max oldest in-flight job 217 ms (pre-fix: 8,055 ms); max queue depth 45; 0 invariant violations in ~1,450 ticks; 0 panics; idle -> 0 queued Phone (release aarch64, 8,577 photos): 99.98% cache hits in stress scroll, 0 panics/ANRs. Tests: 15 pass incl. fresh_batch_preempts_stale_worker_queue (new) and the existing scroll_back_cache_hit_not_starved; 5k engine test uses an uncapped queue (usize::MAX cap param). |
||
|---|---|---|
| scripts | ||
| src | ||
| .gitignore | ||
| build.rs | ||
| Cargo.lock | ||
| Cargo.toml | ||
| HANDOFF.md | ||
| LICENSE | ||
| README.md | ||
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).