Record the two reuse defects the random trees found, their fixes, and the one-pixel tabs difference left for Iris to call
This commit is contained in:
1 parent
19b9ca7413
commit
e442481a30
1 file changed
+43
-25
@@ -9,7 +9,7 @@ Canonical `main` is **`ca2b4b2`** (#17, the headless rig). Sixteen slices are
|
|||||||
in; #16's size work and #17's rig both merged on 2026-09-14.
|
in; #16's size work and #17's rig both merged on 2026-09-14.
|
||||||
|
|
||||||
**#18 `split/18-position-chain`** is open, worktree `/home/bob/repos/iris-pr18`,
|
**#18 `split/18-position-chain`** is open, worktree `/home/bob/repos/iris-pr18`,
|
||||||
head `86a7e8d`, eight commits. LAYOUT.md §2's O(1) subtree movement, the
|
head `2272634`, ten commits. LAYOUT.md §2's O(1) subtree movement, the
|
||||||
`Remap` retirement, and then the three changes the owner chose on 2026-09-14:
|
`Remap` retirement, and then the three changes the owner chose on 2026-09-14:
|
||||||
the slot carries a box, slots are opt-in, and a widget's region is held in the
|
the slot carries a box, slots are opt-in, and a widget's region is held in the
|
||||||
coordinates of the slot it draws in.
|
coordinates of the slot it draws in.
|
||||||
@@ -46,28 +46,50 @@ coordinates of the slot it draws in.
|
|||||||
2026-09-14: stretch has an opposite and scale does not, and the answer is
|
2026-09-14: stretch has an opposite and scale does not, and the answer is
|
||||||
per axis so the axis is already established where it is read.
|
per axis so the axis is already established where it is read.
|
||||||
|
|
||||||
**The open defect, and it is older than this branch.** `tests/generated.rs`
|
**The divergence the random trees found, and what it was.** A warm tree did
|
||||||
grows a seeded random tree and checks that laying it out again lands where
|
not always land where a cold build does -- 30 of 90 cases, against 7 on
|
||||||
growing it cold does. It does not always. Every case seen is a **wrapping text
|
`db1751f`. Two causes, both fixed in `b0f9f04`, and both about deciding
|
||||||
on a span's own axis**: the span measures the child in the whole box, the
|
whether a drawing is still valid:
|
||||||
child shapes to that width and reports the width it used, the span places it
|
|
||||||
in exactly that width, which is a length change, so it shapes again and its
|
|
||||||
longest line is shorter than the box it was just given. Where it settles
|
|
||||||
depends on how many passes it has had, and a warm tree has had a different
|
|
||||||
number from a cold one -- so layout is not a function of the state, which it
|
|
||||||
has to be. A span whose axis is not the wrap axis is stable, which is every
|
|
||||||
real column of text, and why nothing had run into it.
|
|
||||||
|
|
||||||
seeds 1-30, three checks each db1751f (before) 86a7e8d (now)
|
- **A region is a fraction of a slot's box, so an unchanged region is not an
|
||||||
diverging 7 of 90 30 of 90
|
unchanged box.** `try_reuse` compared regions, and a child drawn at
|
||||||
|
`UiRegion::FULL` of a slot whose box had just halved compared equal to
|
||||||
|
itself and was reused without being descended into, leaving a wrapping text
|
||||||
|
shaped for a width it no longer had. `ActiveData::px` now holds the pixel
|
||||||
|
size of the box the widget drew against and the comparison is against that
|
||||||
|
-- the question that was being asked all along, and right through a slot
|
||||||
|
change and an output resize alike.
|
||||||
|
- **A size the parent learnt by drawing the child is an answer for that box
|
||||||
|
only.** The walk skipped a child whose own box was a fixed width, correctly
|
||||||
|
-- but that width was what the child reported when the span drew it in the
|
||||||
|
span's box, and the span's box had changed. A child whose size the widget
|
||||||
|
read is now redrawn unless it declares an exact `size_hint` for the changed
|
||||||
|
axis, which is the one case the parent did not draw it to find out.
|
||||||
|
|
||||||
The same defect either way: a placed child reaches the second shaping more
|
90 of 90 now agree, and the ignored sweep agrees over 300 checks on 100
|
||||||
often now. It wants fixing where the two draws meet, LAYOUT.md §4, rather than
|
seeds. The cost of the second one: a size-reading container gives up its reuse
|
||||||
anywhere in the chain -- and **it should be fixed before #18 merges**, since
|
when its box changes length, which is every span, so `OnResize::Scale` earns
|
||||||
tripling how often a tree lands somewhere unrepeatable is not something to
|
its keep on moves and on subtrees whose sizes nobody read rather than on every
|
||||||
land even on a defect that was already there.
|
stretch. `replace_cost` still measures the case the chain was built for.
|
||||||
`a_wrapping_child_of_a_row_settles_somewhere_else_each_time` is the ignored
|
|
||||||
reproduction; the six seeds the live tests use are ones that agree.
|
**Render verification, done last as the owner asked.** `view`, `minimal` and
|
||||||
|
`text` are byte-identical to `upstream/main` at 1920x1200. **`tabs` is not**:
|
||||||
|
1,283 pixels of 2.3M (0.06%), two one-pixel-wide panel edges shifted by a
|
||||||
|
pixel, at x=1056 and x=1337. Composing a position through the chain on the GPU
|
||||||
|
associates the arithmetic differently from collapsing it on the CPU, so a
|
||||||
|
value that used to land exactly on an integer now falls the other side of the
|
||||||
|
shader's `floor`. The CPU and the GPU still agree with each other -- both walk
|
||||||
|
the chain bottom-up -- so hit testing matches what is drawn; what changed is
|
||||||
|
only the comparison against the old code. Matching it exactly would mean
|
||||||
|
composing root-down in the shader, which needs the chain collected into an
|
||||||
|
array first. **Worth the owner's call before merging**, since byte-identical
|
||||||
|
against `upstream/main` has been the bar for every slice so far.
|
||||||
|
|
||||||
|
A live resize does land where a cold start does, byte for byte, on `tabs` and
|
||||||
|
`text` -- the check that caught both of #16's defects. `run-headless.sh
|
||||||
|
--resize WxH@Hz` is that check now. Run one at a time: the rig reuses a single
|
||||||
|
compositor and a single output, so two at once resize each other's window and
|
||||||
|
screenshot the wrong thing.
|
||||||
|
|
||||||
**Rigs added.** `iris::random` grows the tree (spans in every direction,
|
**Rigs added.** `iris::random` grows the tree (spans in every direction,
|
||||||
stacks, rects with varying opacity, text wrapping and overflowing, a declared
|
stacks, rects with varying opacity, text wrapping and overflowing, a declared
|
||||||
@@ -76,10 +98,6 @@ size over half of it, stopping at a depth), `examples/random.rs` draws one --
|
|||||||
against cold under a size change, a resize, and both. It found the
|
against cold under a size change, a resize, and both. It found the
|
||||||
non-terminating marking above immediately.
|
non-terminating marking above immediately.
|
||||||
|
|
||||||
**Not verified yet:** the headless render shots and the live resize under
|
|
||||||
sway. The owner asked for those last, after the CPU side is right, and the CPU
|
|
||||||
side is not right until the divergence is.
|
|
||||||
|
|
||||||
### The plan after #18, agreed with the owner on 2026-09-14
|
### The plan after #18, agreed with the owner on 2026-09-14
|
||||||
|
|
||||||
Three changes, done together as one slice on top of #18, because each decides
|
Three changes, done together as one slice on top of #18, because each decides
|
||||||
|
|||||||
Reference in new issue
Block a user