From 986f98380d251f09f87f66334991669def674a6a Mon Sep 17 00:00:00 2001 From: iris-ai <4+iris-ai@noreply.localhost> Date: Mon, 14 Sep 2026 16:42:42 -0400 Subject: [PATCH] Document retained layout diagnostics --- docs/IRIS_EXTRACTION_HANDOFF.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/IRIS_EXTRACTION_HANDOFF.md b/docs/IRIS_EXTRACTION_HANDOFF.md index ffb3ff1..c2d5227 100644 --- a/docs/IRIS_EXTRACTION_HANDOFF.md +++ b/docs/IRIS_EXTRACTION_HANDOFF.md @@ -9,7 +9,7 @@ Canonical `main` is **`ca2b4b2`** (#17, the headless rig). Sixteen slices are in. **#18 `split/18-position-chain`** is open and finished apart from one decision: -worktree `/home/bob/repos/iris-pr18`, head `84f589e`, fifteen commits, +worktree `/home/bob/repos/iris-pr18`, head `480f0bc`, sixteen commits, workspace tests passing, fmt and clippy clean. It is LAYOUT.md ยง2's position chain, generalised to boxes. `/home/bob/repos/ai-app-2` is on `rustify`, worktree clean. @@ -166,6 +166,35 @@ instructions current versus 3.56B before #16 (3.87x), consistent with the resize wall-time gap. A follow-up rig should select one phase per invocation so the hardware counters are phase-specific rather than inferred from that total. +`480f0bc` retains that instrumentation behind the `layout-diagnostics` Cargo +feature; none of it is compiled into a normal Iris build. The ignored +`tests/layout_diagnostics.rs` rig selects `cold`, `repaint`, `size`, `scroll`, +or `resize` with `IRIS_PHASE`, plus seed, depth and frame count. Run it with the +feature for explanatory counters and inclusive phase timers, and without the +feature under `perf` for unperturbed CPU totals: + +```sh +IRIS_PHASE=resize IRIS_DEPTH=8 IRIS_FRAMES=100 \ + cargo test --release --features layout-diagnostics \ + --test layout_diagnostics -- --ignored --nocapture + +IRIS_PHASE=resize IRIS_DEPTH=8 IRIS_FRAMES=1000 \ + perf stat -e cycles:u,instructions:u cargo test --release \ + --test layout_diagnostics -- --ignored --nocapture +``` + +The first depth-8 resize run makes the amplification concrete. A 260-widget +tree has 215 active widgets, but a resize averages 1,395 widget draws, 913 +placement calls, 1,313 reads of drawn sizes and 34,844 primitive writes. Only +12 distinct text widgets render, yet they render and reshape 282 times per +frame with no shape-cache hits. Text rendering accounts for 11.6 of 13.2 ms, +including 9.9 ms shaping and 1.7 ms placing glyphs. The hottest two text +widgets each draw 96 times per frame at 22 distinct widths across two resize +frames, below nested `Span`, `Aligned`, `Scroll`, `Pad`, and `SetSize` +ancestors. This identifies repeated constraint discovery, rather than resize +marking (0.001 ms), as the next subject; it does not yet choose between +per-axis retained size validity and coalescing the resize dependency frontier. + The generated tree now includes `Aligned` with every meaningful per-axis alignment. That exposed two retained-layout ordering bugs which `84f589e` fixes. The regular cold-layout equivalence suite passes. The ignored 100-seed