docs: egui port decision + egtest harness + winit-android redraw bug

This commit is contained in:
Greg Pomerantz 2026-10-31 00:20:09 -04:00
parent df4e1bd6f8
commit f2a7b32a75

View File

@ -797,6 +797,59 @@ 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.11 egui port decision + egtest harness (2026-10-31)
**Verdict on Slint:** stock crates.io build janky (user), vendored build
same/worse (user), minimal sltest (300 rows, no textures) janky (user),
adb-measured drops (0.05-0.83%) are a FLOOR — the user's finger says
"much more than 1 hitch per 8 s". **The base Slint-on-Mali render path is
the problem. User decision: port to egui** (different toolkit AND a
different renderer family: glow/OpenGL-ES3 vs Skia-on-wgpu).
**egtest** (`/tmp/egtest`, standalone, same discipline as sltest) — the
CONTROL experiment: the exact sltest scene (8,580 rows × 150 px, 148 px
color band + 2 px white separator) in egui 0.31.
- egui_glow/egui-winit 0.31.1, glow 0.16, winit 0.30, android-activity
0.6, `egl` 0.2.7 safe wrapper. APK 1.98 MB. `wow.gmp.egtest`.
- Virtualized list: only visible rows ± 4 painted per frame via the
painter (immediate mode = free virtualization). Momentum fling
(0.94 decay, 8 px/frame min, seed = last drag delta × 1.5).
- FR log (sltest pattern, non-blocking logger, per-line flush):
`/sdcard/Android/data/wow.gmp.egtest/files/fr.log`.
- Build: `cd /tmp/egtest && ADB_SERIAL=... ./scripts/build.sh [aarch64|x86_64] [install|no-install]`.
- Crates.io naming gotcha: `egui_glow` (underscore) vs `egui-winit`
(dash) — the index is inconsistent; winit's android feature is
`android-native-activity`; cargo-apk2 needs the activity section in
Cargo.toml (NativeActivity + lib_name) and `config_changes` as a
pipe string of aapt2 flag NAMES (no `keyboardNavigation` — it's
`navigation`; hex/decimal bitmasks rejected).
**Two real phone bugs found + fixed (they will bite the final port too):**
1. **winit 0.30 android: `RedrawRequested` is never dispatched on the
phone.** `MainEvent::Resume` never arrives → `EventLoopInner.running`
stays false → the RedrawRequested dispatch (inside `if self.running`)
is suppressed; `about_to_wait` is not. Emulator delivers Resume
fine — phone (pre-rotated display) does not. **Fix: drive frames from
`about_to_wait`** — render there + `ControlFlow::WaitUntil(now+8333µs)`
(app-owned pacing, same architecture as the Slint frame driver).
Phone result: ~698 frames / 10 s (≈100 Hz) rendering the scene on
Mali+ES3 with 1-2 ms render cost.
2. `Window::request_redraw()` via ALooper_wake was unreliable here too —
the WaitUntil pacing removes the dependency entirely.
**Current state (handoff):** egtest is INSTALLED on the phone but the
phone's WM is in a degraded state (NotificationShade stuck in focus,
`dumpsys window` broken — "Broken pipe", load avg ~6 from the user's
apps). The app was last seen rendering into a GONE window (WM never
granted visibility — plausibly a cascade of the stuck-shade state, not
an app bug). **NEEDS THE USER**: glance at the phone (close the shade /
check for a stuck system UI), then launch **Egtest** from the launcher
and scroll it hard. Question to answer: *is egtest smooth where sltest
(janky) rendered the identical scene?* FR log is live for drop analysis
afterwards (`grep FR fr.log`). If smooth → port the gallery app layer
(db/scan/turbojpeg/LRU/GPU-upload, all renderer-agnostic) to an egui
grid + the about_to_wait frame driver + EGL setup from egtest.
### 8.8 Jank-hunt round 2 + the keep-alive incident (2026-10-28)
Follow-up on "still seeing jank" (post-GPU-texture). Instrumentation: