Document coalesced resize layout

This commit is contained in:
iris-ai committed 2026-09-14 17:06:41 -04:00
1 parent 986f98380d
commit 974d6c7a52
2 files changed
+59 -39

No files matched your search

+13 -21
View File
@@ -102,27 +102,19 @@ narrowings apply, and both are real, measured properties of the code as it
stands rather than new machinery:
**(a) A window resize does not, by itself, require touching most widgets.**
`shader.wgsl:105-106` recomputes every primitive's pixel position from
`window.dim` and the primitive's stored `rel`/`abs` pair *every frame,
already, on the GPU*. A widget laid out purely in `rel`/`abs` terms (no
call to `px_size()`, `output_size()`, or anything else that reads a
concrete pixel count) is therefore already correct after a resize with zero
CPU work — the shader did it. `UiRenderState::needs_redraw_all`
(`render_state.rs:229-231`) currently ignores this and redraws the entire
tree on every `resized`, which was the safe default while sizing and
drawing were two passes; it should be narrowed to only the widgets that
*do* read a concrete pixel value. Track this the same way `needs_redraw`
already tracks per-widget dirtiness (`Widgets::needs_redraw`,
`core/src/widget/widgets.rs:9`): a widget's `draw` call marks itself
pixel-dependent by calling through `Painter` methods that read
`output_size`/`px_size` (both already funnel through `Painter`, so the
marking is one line at each), and `resize()` (`render_state.rs:32-35`)
walks only that set instead of unconditionally setting `resized = true`
for a full `redraw_all`. This turns "every resize redraws everything" into
"every resize redraws what depends on pixels" — a real behavior change
beyond what was asked, so verify it against the I0b `pre_present_notify`
resize regression (that fix depended on `redraw_all`'s completeness)
before narrowing this.
`shader.wgsl` recomputes every primitive's pixel position from `window.dim`
and the primitive's stored `rel`/`abs` pair every frame, already, on the GPU.
A widget laid out purely in `rel`/`abs` terms is therefore already correct
after a resize with zero CPU work. Calls to `Painter::px_size` and
`Painter::output_size` mark the active widget as reading concrete pixels;
only those widgets become dirty when the output actually changes.
All pixel-dependent leaves are marked before layout begins, along with every
chain of parents that read their sizes. Resize then settles the shallowest
shared readers first, under the new output, so overlapping dependency paths
are drawn once. Ordinary content changes use the opposite order: deepest
dirty widgets first, with a changed returned size propagated one reader edge
at a time. Re-reporting the current output size is a no-op.
**(b) A widget's `available` (its parent's offered region) can change
without the widget's *content* changing — this is what