diff --git a/RUST.md b/RUST.md index eb47386..cbdf3eb 100644 --- a/RUST.md +++ b/RUST.md @@ -14,8 +14,50 @@ this clone is where things get tried before anything is committed to **in-house framework to be built up** for this, with Masonry as the yardstick it is measured against. -Decisions get a date and a reason here, the way `PLAN.md` does. Nothing in -this file has been tried yet unless a section says it has. +Decisions get a date and a reason here, the way `PLAN.md` does. A section +describes something that has been tried only where it says so, with a date. + +## Keep this file current as you work + +**This file is the handoff, and it is meant to let a session be cleared.** +Write each result into it *as you get it*, not at the end: the box ticked +or the reason it could not be, the measurement with its number, the +decision with its date and what it rejected, and anything that cost time to +find out. Then a session that has filled its context can be cleared and the +next one can pick up from this file alone, which is much cheaper than +carrying a long conversation or re-deriving what was already measured. + +Two things that follow. Write for somebody who was not here — name the +command, the file and the number rather than "the fix" or "the earlier +run". And write the failures and the dead ends too: "Venus is blocked by +the emulator, not by Mesa" and "the present mode was not the cause" are +worth as much as the successes, because they are what stops the next +session spending an afternoon on them again. + +## Where things stand (2026-09-04) + +- **Done**: E0 (toolchain), E1 (Masonry on android-view, which found the + keyboard gap), I0a, I0b (iris builds on a pinned nightly and runs), I1 + (parley + glyph atlas). +- **Next**: **I2** — iris on android-view. E1 says the first thing to + answer there is why the editor gets keystrokes but no autocorrect or + suggestions, since that is the constraint the framework decision turns + on. **E2** (a transcript in Masonry) can go in parallel in another + session. +- **Not started**: `client-core`, which is item 1 of the recommendation + below and does not depend on the framework choice. Nothing has been + built for it, and it is not one of the numbered boxes — worth picking up + in a session that wants work independent of the emulator. +- **The app itself is untouched.** Everything so far is in `iris/` and in + the rigs; nothing under `app/` or `server/` has changed. +- **Changed outside this repo**, both in `emulator-tools` and both pushed: + `avd_serial` now validates its cache by asking the device its AVD name + rather than by checking the serial is still attached (a recycled port + silently pointed this checkout at another session's emulator), and + `EMU_GPU=software` was added as an opt-in that keeps a run off the host + GPU and gives the guest a software Vulkan device. The default is + unchanged, because `-gpu host` was measured and the Compose benchmarks + depend on it. ## What has to be reproduced @@ -317,7 +359,8 @@ Desktop runs on winit. Vello needs a compute-capable GPU or falls back to [cat16/iris](https://github.com/cat16/iris), read 2026-09-04 from the one public commit (2026-01-31, "portfolio copy"; ~8,700 lines in `core`, `macro` and the crate itself). Retained-mode widgets stored outside the -render tree, `wgpu` 28 directly, `winit` 0.30, `cosmic-text` 0.16, a +render tree, `wgpu` 28 directly, `winit` 0.30, `cosmic-text` 0.16 (parley +since I1), a relative-anchor-plus-offset layout with `rest()` and `rel()` lengths, a postfix builder API (`rect(..).radius(30).on(CursorSense::click(), ..) .sized(..).align(..)`), events handled where the widget is declared, and @@ -325,10 +368,17 @@ a single-threaded context passed explicitly — all of which reads like this codebase's own rules. There is text editing (`widget/text/edit.rs`), images, masks, spans and stacks; the TODO names text resizing as per-frame slow and scaling as unsolved. It requires **nightly** (fourteen -`#![feature]` gates, among them `const_trait_impl`, `unboxed_closures`, -`portable_simd`, `associated_type_defaults`). Desktop only; no Android -surface, no IME, no accessibility tree, no virtualised list, no rich-text -selection. +`#![feature]` gates as vendored, among them `const_trait_impl`, +`unboxed_closures`, `portable_simd`, `associated_type_defaults`; eleven +after I0b and I1 — see those steps for the current list). Desktop only; no +Android surface, no IME, no accessibility tree, no virtualised list, no +rich-text selection. + +**That list is the work, and some of it is done.** As of 2026-09-04 it +builds on a pinned nightly, runs on this machine's GPU, has parley and a +glyph atlas, and `iris-core` cross-compiles to Android. What it still +lacks from the list above is the Android surface, the IME bridge, the +accessibility tree and the virtualised list — I2, I3 and I4. **iris is not a candidate to be tested as it stands. It is the in-house library** (Iris, 2026-09-04): "essentially a good start to a rewrite from @@ -340,16 +390,16 @@ it needs are the same ones Masonry gets from android-view, Parley and AccessKit, and there is no reason iris cannot sit on those same foundations rather than reinvent them — the surface, the keyboard bridge and the accessibility tree are platform plumbing, not a framework's -identity. Whether the text stack stays cosmic-text or moves to Parley is -the first real design decision in that work (see I1 below). +identity. The text stack was the first real design decision in that work, +and it is settled: **Parley, with a glyph atlas** (I1, 2026-09-04). Two things to carry into that work honestly. Nightly is the opposite of "holds up long term": a build that breaks on a toolchain update, on the -machine Dev Updater builds on, unattended. Pin a dated nightly in -`rust-toolchain.toml` immediately, and keep a list of which `#![feature]` -gates are load-bearing so they can be retired as they stabilise or are -designed around. And a one-person framework carries every gap itself, -which is what Iris said she is willing to do. +machine Dev Updater builds on, unattended. **Done in I0b** — +`iris/rust-toolchain.toml` pins `nightly-2026-09-03` — and the gate list +lives with I0b and I1, to be retired as they stabilise or are designed +around; it is down from fourteen to eleven. And a one-person framework +carries every gap itself, which is what Iris said she is willing to do. "From scratch" therefore means iris, not a fourth thing. Masonry stays in the plan as the **yardstick and the fallback**: building its demo and its @@ -377,10 +427,18 @@ uses is to optimise dependencies while leaving the app crate at `opt-level [profile.dev.package."*"] opt-level = 2 -E1 measures this rather than remembering it: cold and incremental build -time, APK size, resident memory at rest and while streaming, and the -frame cost of one 800-event page — for the Masonry demo as shipped, then -with the profile above. Vello proper needs compute shaders and carries a +**Measured 2026-09-04, and it is not the widget layer.** iris's own +graph (wgpu + winit + cosmic-text at the time) built cold in **43s** with +a 2.1 GB `target/`, and **1m46s** with a 1.5 GB `target/` under the +profile above — so the knob costs build time and saves disk here, and +plain debug was never the problem. Masonry's graph is the one with Vello, +Parley, Fontique and Skrifa in it, and E1 gives the number that matters +for it: **`libmain.so` is 181 MB in debug and 11 MB in release.** That +size is also a correctness issue rather than only a weight one — a debug +build labels its Vulkan objects, and the emulator's driver segfaults in +`SetDebugUtilsObjectNameEXT` when it does. Runtime cost of the profile +knob is still unmeasured; resident memory and the frame cost of an +800-event page want E2. Vello proper needs compute shaders and carries a large shader set; `vello_hybrid` is lighter and Masonry can now render through either (or Vello CPU) via its `imaging` abstraction, so "keep it light" has a knob inside the same stack. @@ -737,18 +795,28 @@ re-derived: 2. Work on the **`rustify`** branch of this clone (`ai-app-2`), not on `main` and not in `ai-app`. Nothing on this branch is production until Iris says so. Commit and push as you go. -3. Take the next unchecked box above, in order: E0 first, then E1, then - the iris track from I0. E-steps and I-steps can proceed in parallel in - separate sessions once E1 has proved android-view on this emulator. +3. Take the next unchecked box above, in order. E1 has proved android-view + on this emulator, so the E-steps and the I-steps can now proceed in + parallel in separate sessions; see "Where things stand" at the top for + which is next. 4. Every step ends with its measurement written into this file beside the box, and the box ticked or the reason it could not be written in its - place. A step that is blocked says by what, not "later". + place. A step that is blocked says by what, not "later". Write it as you + go rather than at the end — see "Keep this file current as you work". 5. Run the existing rigs rather than inventing new ones: `ui-sandbox.sh` for a server with fixtures, `transcript-bench.sh` for the scroll baseline, `ui-trace` for anything positional, `emu up` for the - emulator. The Vulkan section below says how to get a Vulkan path in the - emulator when a `wgpu` backend needs one. -6. Decisions belong here with a date and what was rejected, the way + emulator, and `iris/run-headless.sh EXAMPLE --shot PNG` for an iris + example on this displayless machine. The Vulkan section below says how + to get a Vulkan path in the emulator when a `wgpu` backend needs one. +6. **Bound anything heavy at the moment you start it.** An emulator or a + long build gets a deadline — `timeout`, or a watchdog scoped to the pid + you just started — rather than a plan to stop it later. Scope it to + that pid: a watchdog written as `sleep N; emu down` fired into a later + experiment here and made a working Vulkan build look like a crash. And + stop the emulator when the work needing it is done rather than between + tasks. +7. Decisions belong here with a date and what was rejected, the way `PLAN.md` does it. Do not put design into commit messages alone. ### Vulkan in the emulator (measured 2026-09-04)