Document per-axis retained layout

This commit is contained in:
iris-ai committed 2026-09-14 17:49:42 -04:00
1 parent 974d6c7a52
commit ecce4448f0
2 files changed
+43 -14

No files matched your search

+30 -5
View File
@@ -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 `82fa6c1`, seventeen commits,
worktree `/home/bob/repos/iris-pr18`, head `b1b3eca`, eighteen 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.
@@ -217,9 +217,24 @@ hottest texts draw 32 times. Instrumented layout is about 5.5 ms instead of
60.79B instructions total (60.8M/frame), and 23.85B cycles. This is about 58%
fewer instructions than the roughly 138M/frame #18 path before coalescing,
but still about 1.8x the old 3.14 ms resize median. The remaining multiplier
is within one constraint traversal, so per-axis retained size validity is now
the useful next question. Re-sending the existing output size also no longer
starts a resize.
is within one constraint traversal. Re-sending the existing output size also
no longer starts a resize.
`b1b3eca` records pixel reads and retained size inputs per axis. `Text` says it
reads only its offered width, while `Scroll` says it reads only its scrolling
axis. `Span`, `Aligned`, and `Scroll` ask for an exact hint or a retained child
length valid under the box they are about to offer, and draw to measure only
when neither exists. On the same depth-8 load, resize now averages 449 widget
draws, 296 placement calls, 485 drawn-size reads, 12,164 primitive writes, and
107 text shapes. Cached uninstrumented 1,000-frame runs measured 4.955.24 ms
medians, 55.4B instructions total (55.4M/frame), and 21.521.6B cycles: about
9% fewer instructions than `82fa6c1`, but still about 1.6x the old 3.14 ms
median.
Pixel comparisons now use a 0.05 physical-pixel tolerance. The comparison is
against the last actual layout, not the preceding resize event or retained
move, so repeated subpixel changes accumulate and eventually redraw. The
generated cold-layout oracle uses the same visual tolerance per coordinate.
The generated tree now includes `Aligned` with every meaningful per-axis
alignment. That exposed two retained-layout ordering bugs which `84f589e`
@@ -227,7 +242,9 @@ fixes. The regular cold-layout equivalence suite and the ignored 100-seed
sweep pass. The latter previously stopped at seed 60 on `140.0` versus
`139.99996948242188`: exactly two `f32` ULPs from an equivalent composition
order, not a visible layout difference. The oracle now keeps draw presence
exact and allows at most four ULPs per pixel coordinate.
exact and allows at most 0.05 physical pixels per coordinate. Seed 98 is also
part of the ordinary suite because it catches stale retained size beneath an
aligned size-changing chain.
The branches are invariants rather than widget exceptions:
@@ -255,6 +272,14 @@ stale-size failure. Re-measuring the scroll subtree costs 11 draws rather than
1, but remains two orders of magnitude below the old 1,313 and follows the
actual dependency invariant.
A frame-local cache of several size answers under different constraint boxes
was also discarded. It reached about 3.5 ms in the instrumented resize rig,
but seed 98 showed that a valid answer is not enough: the child's one active
drawing may still realize another constraint, and a parent can then lay out
from an answer its final child placement does not realize. A correct version
needs an answer-plus-realization or verification protocol; adding dirtiness
conditions to the cache does not fix that invariant.
Do not restore the archive's old `DrawMode::Measure`. It skipped primitive and
retained-state writes while still walking widgets and shaping text, and once
improved a streamed-frame benchmark from 1.39 to 1.22 ms p50. Retained