iris: record the streamed-row redraw as an open item

arena_churn says a streamed frame uploads 72.7% of the instance arena
and that this is the floor, against 3.3% for a fling over the same
content -- so the rows are being redrawn where a scroll would write one
move_offsets delta. The upload half landed in 3c7d3db; this is the
layout half, with the measurement, the control that makes it convincing,
and where to look first.
This commit is contained in:
iris committed 2026-09-09 11:34:30 -04:00
1 parent 3c7d3db370
commit a428cba41a
1 file changed
+35
+35
View File
@@ -12,6 +12,41 @@ and six phone-report sections went on 2026-09-08 for that reason.
## Fix ## Fix
- [ ] **A row moving because the list grew should be one `move_offsets`
write, and today it is a redraw.** Found 2026-09-09 by
`scripts/rigs/ui-profile`'s `arena_churn` and left for whoever picks
this up next; the upload half of it is done and this is the layout
half.
The measurement. Over the bench fixture's 401 streamed deltas, the
instance arena uploads **72.7%** of itself per frame, and that number
*is* the floor -- those entries genuinely differ, so no amount of
better dirty-tracking touches it. The control that says it is wrong is
the fling phase on the same screen and the same content: it moves the
same primitives every frame and uploads **3.3%**, because a scroll
reaches `UiRenderState::mov` and writes one `move_offsets` delta for
the subtree (LAYOUT.md section 2) instead of rewriting every
primitive's absolute region.
What is different about the streaming path. The list is pinned to the
newest end, so a growing reply pushes every row above it up by the
amount the last row grew. That is a translation of an already-drawn
subtree -- exactly what `move_offsets` is for -- but it arrives as a
new offered region per row, and `draw_inner`'s fast path only takes
`mov` when `active.region.size() == region.size()`. Worth checking
first: whether `LazySpan::place` is offering each row a region whose
*size* differs (it computes `edges(height)` fresh each frame, so an
identical height should compare equal -- unless a float differs in the
last bit, which the `// TODO: epsilon?` beside that comparison already
suspects), or whether something upstream marks the rows dirty so the
fast path is skipped entirely.
Done looks like: `arena_churn`'s `what_a_streamed_reply_uploads` shows
stream instances in the same range as the fling's, and its `whole`
column stops being the interesting one. The rig prints floor,
uploaded and whole per array precisely so this is checkable rather
than argued.
- [ ] **Where the scroll *pin* lives.** The rest of "scrolling moves out - [ ] **Where the scroll *pin* lives.** The rest of "scrolling moves out
of the list" landed on 2026-09-08 -- `List` is `LazySpan`, the physics of the list" landed on 2026-09-08 -- `List` is `LazySpan`, the physics
and the gesture live in one `ScrollController`, `.scrollable()` is the and the gesture live in one `ScrollController`, `.scrollable()` is the