Record exact layout equality and measured reuse improvements
This commit is contained in:
1 parent
0080bcbcba
commit
8f1a5e0a46
2 files changed
+64
-44
No files matched your search
+60
-43
@@ -376,19 +376,12 @@ boundaries through `through`, or make the grid floor everywhere.
|
|||||||
|
|
||||||
### Where the residual comes from, and the snap
|
### Where the residual comes from, and the snap
|
||||||
|
|
||||||
Both remaining steps are a symbolic region re-expressed by division rather
|
The `e44dea3` baseline's two-step allowance came from inverse remapping and
|
||||||
than recomputed the way a cold draw computes it: `AxisRemap::Scale` divides
|
alignment composed by different routes. The frame/extent continuation below
|
||||||
to find a part's fraction of the old box, and `placed_box` scales a mixed
|
retains local widget frames as well as local primitive coordinates, recomposes
|
||||||
`Len` by the alignment. Neither touches the threaded pixel chain, so every
|
in the same order as a cold draw, and removes inverse remapping. Its oracle
|
||||||
layout decision already agrees warm against cold; what differs is the
|
requires exact pixel-region equality. That experiment is not yet the pinned
|
||||||
composed position the shader and hit testing see, by up to 0.002 px.
|
framework; the baseline's snap decision below still applies there.
|
||||||
|
|
||||||
Closing `Scale` exactly is possible: keep each primitive's region in its
|
|
||||||
widget's own coordinates and recompose on a move with `within`, eight
|
|
||||||
multiplies and no division against the current four divisions and twelve
|
|
||||||
multiplies, exact by construction, sixteen bytes more per primitive. Closing
|
|
||||||
the alignment one means resolving alignment in pixels, which costs the
|
|
||||||
retained resize path. Neither is worth a thousandth of a pixel on its own.
|
|
||||||
|
|
||||||
Where it does matter is `snap_floor` in `prelude.wgsl`, which adds half a
|
Where it does matter is `snap_floor` in `prelude.wgsl`, which adds half a
|
||||||
layout step before flooring: that absorbs float error and not a layout
|
layout step before flooring: that absorbs float error and not a layout
|
||||||
@@ -429,8 +422,8 @@ back.
|
|||||||
The original proposal was implemented by Claude as `5fcace1` on
|
The original proposal was implemented by Claude as `5fcace1` on
|
||||||
`wip/region-and-placement` in `/home/bob/repos/iris-pr18`. It kept the fraction
|
`wip/region-and-placement` in `/home/bob/repos/iris-pr18`. It kept the fraction
|
||||||
reference stable but failed five layout cases and three draw-count cases.
|
reference stable but failed five layout cases and three draw-count cases.
|
||||||
The correction is saved as `efb416b`, pushed to origin's
|
The first correction is `efb416b`; the exact-recomposition continuation is
|
||||||
`wip/region-and-placement`, in the isolated checkout
|
`2ed5503`, pushed to origin's `wip/region-and-placement`, in the isolated checkout
|
||||||
`/home/bob/repos/iris-layout-experiment`; **it is not on PR #18**. The original
|
`/home/bob/repos/iris-layout-experiment`; **it is not on PR #18**. The original
|
||||||
checkout is unchanged. Keep the experiment's build directory separate: Cargo
|
checkout is unchanged. Keep the experiment's build directory separate: Cargo
|
||||||
can accept a different worktree's artifacts as fresh when a target directory
|
can accept a different worktree's artifacts as fresh when a target directory
|
||||||
@@ -475,34 +468,62 @@ placeholder zero answer became reusable once it was drawn during placement.
|
|||||||
and `adding_text_to_a_reverse_row_keeps_its_shared_height` reproduces the
|
and `adding_text_to_a_reverse_row_keeps_its_shared_height` reproduces the
|
||||||
zero-height failure with a small tree.
|
zero-height failure with a small tree.
|
||||||
|
|
||||||
Ordinary verification currently passes: formatting, workspace clippy with
|
**Exact recomposition and reuse.** The continuation replaces `given_len` with
|
||||||
`layout-diagnostics`, all workspace tests (96 suite tests), and the fast
|
`given_region`: each widget retains its original frame in its parent's
|
||||||
generated cases. New regressions also inspect primitive coordinates for mixed
|
coordinates. Moving a retained subtree replays those same local compositions,
|
||||||
frame/extent drawings, including a region node, and a content change after
|
and stops at region nodes. `RegionRemap`, `AxisRemap`, and inverse division
|
||||||
moving an inherited extent. A `tabs` resize from 1920x1200 to 900x1200 matches
|
are gone. Fixed-pixel frames can now change size without forcing otherwise
|
||||||
a cold 900x1200 screenshot with zero differing pixels. The release oracle
|
valid descendants to draw again. This adds 16 bytes per active widget; local
|
||||||
passes 2000 seeds at depth 4 and 1000 seeds at depth 6 over all fifteen cases.
|
primitive coordinates were already retained by `efb416b`.
|
||||||
The shrinker passes 400 seeds at depth 5, and the debug oracle passes 120
|
|
||||||
seeds at depth 4 with assertions enabled.
|
The shared oracle now compares pixel regions with ordinary equality; there
|
||||||
|
is no `AGREE_STEPS` allowance. Text publishes the range of its retained line
|
||||||
|
breaks rather than narrowing that range to every later
|
||||||
|
requested width. A layout with only explicit line breaks or no breaks holds
|
||||||
|
at arbitrarily wider widths. New tests compare actual primitive and mask
|
||||||
|
geometry and assert reuse for fixed-frame resizing and widening unwrapped
|
||||||
|
text (including explicit newlines and empty content).
|
||||||
|
|
||||||
|
Ordinary verification passes: formatting, workspace clippy with
|
||||||
|
`layout-diagnostics`, workspace tests, and the fast generated cases. The
|
||||||
|
suite contains 98 tests. A `tabs` resize from 1920x1200
|
||||||
|
to 900x1200 matches a cold 900x1200 screenshot with zero differing pixels.
|
||||||
|
With exact equality, the final release oracle passes 2000 seeds at depth 4
|
||||||
|
and 1000 seeds at depth 6, the shrinker passes 400 seeds at depth 5, and the
|
||||||
|
debug oracle passes 120 seeds at depth 4 with assertions enabled. Every scan
|
||||||
|
runs all fifteen scenarios. The fixed-frame reuse regression was also run
|
||||||
|
against `efb416b`: it fails there with two child draws instead of one.
|
||||||
|
|
||||||
**Do not land this as a performance improvement.** The old stretching and
|
**Do not land this as a performance improvement.** The old stretching and
|
||||||
wrapper reuse tests pass, and one numeric-size test improves from three draws
|
wrapper reuse tests pass, and one numeric-size test improves from three draws
|
||||||
to two. Cold work also improves against the broken `5fcace1` prototype: 604 to
|
to two. The continuation reduces widget draws from `efb416b` by 6.9% cold,
|
||||||
535 widget draws and 15,296 to 10,384 primitive writes on seed 1, depth 8.
|
9.0% with many dirty widgets, 7.6% for a size change, and 8.7% for resize.
|
||||||
But against the last working `e44dea3`, the same rig does substantially more
|
Against the last working `e44dea3`, it still does substantially more nested
|
||||||
nested layout work:
|
layout work (seed 1, depth 8):
|
||||||
|
|
||||||
| phase | widget draws before | prototype | primitive writes before | prototype |
|
| phase | widget draws before | prototype | primitive writes before | prototype |
|
||||||
| --- | ---: | ---: | ---: | ---: |
|
| --- | ---: | ---: | ---: | ---: |
|
||||||
| cold | 369 | 535 | 9635 | 10384 |
|
| cold | 369 | 498 | 9635 | 9704 |
|
||||||
| repaint | 1 | 1 | 1 | 1 |
|
| repaint | 1 | 1 | 1 | 1 |
|
||||||
| many | 157 | 310 | 4721 | 6970 |
|
| many | 157 | 282 | 4721 | 6398 |
|
||||||
| size | 16 | 275 | 106 | 5980 |
|
| size | 16 | 254 | 106 | 5725 |
|
||||||
| scroll | 2 | 2 | 0 | 0 |
|
| scroll | 2 | 2 | 0 | 0 |
|
||||||
| resize | 13 | 328.5 | 0 | 6721.5 |
|
| resize | 13 | 300 | 0 | 6255 |
|
||||||
|
|
||||||
These are instrumented work counts, not elapsed-time speedups (50 frames per
|
These are instrumented work counts, not elapsed-time speedups (50 frames per
|
||||||
phase except cold, which is one; 578 generated widgets, 191 finally active).
|
phase except cold, which is one; 578 generated widgets, 191 finally active).
|
||||||
|
Uninstrumented release binaries, run directly with `perf stat -r 3 -e
|
||||||
|
instructions:u`, also improve over `efb416b`: 2000 size-change frames fall
|
||||||
|
from 14.3923B to 13.8914B instructions (3.5%); 2000 resize frames fall from
|
||||||
|
16.9756B to 16.1331B (5.0%). These whole-process totals include fixture setup;
|
||||||
|
reported run-to-run variation is at most 0.24%. The many-dirty workload falls
|
||||||
|
from 16.7962B to 16.0030B instructions (4.7%, 2000 frames). Repaint and scroll
|
||||||
|
keep their draw counts but incur small CPU increases: 0.8849B to 0.8913B
|
||||||
|
(+0.7%) and 2.4332B to 2.4479B (+0.6%) over 100,000 frames each. These are
|
||||||
|
CPU-work measurements, not phone frame times. Keeping measurement validity separate from final drawing validity
|
||||||
|
and deferring to an already dirty parent were also tried; neither improved
|
||||||
|
this rig's draw counts, so those changes were removed.
|
||||||
|
|
||||||
Raw placement reads in containers and repeated offer/placement evaluations
|
Raw placement reads in containers and repeated offer/placement evaluations
|
||||||
remain conservative. Retaining local coordinates also costs memory per
|
remain conservative. Retaining local coordinates also costs memory per
|
||||||
primitive. The experiment demonstrates selective reuse with one `Widget::draw`
|
primitive. The experiment demonstrates selective reuse with one `Widget::draw`
|
||||||
@@ -591,17 +612,13 @@ cold reach every length by the same expression.
|
|||||||
|
|
||||||
### What the fuzzers tolerate
|
### What the fuzzers tolerate
|
||||||
|
|
||||||
`AGREE_STEPS` in `tests/scenario/mod.rs` is **2**, and both steps are
|
The frame/extent continuation removes `AGREE_STEPS`: warm and cold pixel
|
||||||
positions. One is a box centred in a fraction of its parent against the
|
regions must compare exactly. This is distinct from the equal-share test:
|
||||||
same box centred in its own pixels, 0.001 px on a handful of seeds. The
|
when a row's grid-step count is not divisible by the number of children,
|
||||||
other is `AxisRemap::Scale` re-expressing a part as a fraction of a box that
|
individual share widths can differ while every rerun of that layout must
|
||||||
changed length; one step fails the 400-seed shrinker on `resize-size`,
|
still agree exactly. The PR #18 baseline still allows two position steps;
|
||||||
seeds 384 and 162, by 0.002 px while passing the 100-seed oracle. Two of the
|
its earlier failure at one step (`resize-size`, seeds 384 and 162 at depth 5)
|
||||||
earlier sources were fixed rather than tolerated (`bdab558`): `Scroll` wrote
|
is a useful regression target for the experimental recomposition.
|
||||||
a box it had been given back out as its own length in pixels, and `Span`
|
|
||||||
placed each child a step from where the last ended rather than as the fixed
|
|
||||||
parts before it plus one rounded share. See "Where the residual comes from"
|
|
||||||
above for what closing the rest would cost.
|
|
||||||
|
|
||||||
## Retained-layout invariants
|
## Retained-layout invariants
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -871,7 +871,10 @@ replace that reference. A measurement also records the available extent, so
|
|||||||
reusing it checks both inputs. Retained primitive and mask coordinates name
|
reusing it checks both inputs. Retained primitive and mask coordinates name
|
||||||
whether they follow the frame or the extent. Numeric extent reads constrain
|
whether they follow the frame or the extent. Numeric extent reads constrain
|
||||||
layout validity; merely drawing in an extent does not require another widget
|
layout validity; merely drawing in an extent does not require another widget
|
||||||
evaluation when it moves. `Widget::draw` remains the only layout body. The
|
evaluation when it moves. Widgets also retain their original local frames,
|
||||||
|
so reuse composes positions in the same order as a fresh draw instead of
|
||||||
|
recovering fractions by division. The experimental oracle requires exact
|
||||||
|
pixel-region equality. `Widget::draw` remains the only layout body. The
|
||||||
prototype has significant container-update costs and is not yet adopted into
|
prototype has significant container-update costs and is not yet adopted into
|
||||||
the pinned framework.
|
the pinned framework.
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user