Write a shared constant once, and stop a scroll placing its own content

Two findings from a sweep over the WGSL prelude and the position widgets,
scoped against upstream/main at ca2b4b2.

`module_source` already builds each shader's preamble from iris_core's own
constants, so the move-chain work's second copy of `MOVE_NONE` and
`CHAIN_LIMIT` -- under "keep in step with iris_core::CHAIN_LIMIT" -- asked a
reader by hand for what the mechanism beside it exists to do. Both are
injected now, with `MASK_NONE` beside them replacing a bare literal, and the
shader declares none of them.

`Scroll`'s `content_len` is never less than its box, so `slack` and the
`anchor` computed from it were always zero whatever the alignment: the
framework centres short content by placing the answer in the whole box, and
the comment credited arithmetic that could not have done it. The same belief
guarded the fits-in-the-box contract with `align == NEG`, so at the default
alignment -- the middle -- every box change redrew the scroll, measured as 1
widget against 0 at TOP_LEFT. `align` now has no reader at all.

`UiSpan::translated` and `UiRegion::translated` are reachable only from each
other and from nothing else.

Format, clippy with and without layout-diagnostics, and the 131-test suite
are clean. The cold dump over 400 depth-5 trees is byte-identical to
1096c31, and all three seed scans pass: 400 at depth 5 in 69.07s, 1,000 at
depth 6 in 169.29s, 2,000 at depth 4 in 300.75s.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-20 02:09:41 -04:00
1 parent 1096c3167a
commit b7b8d09e40
8 files changed
+63 -64

No files matched your search

+13 -4
View File
@@ -23,13 +23,22 @@ pub use primitive::*;
const PRELUDE: &str = include_str!("./shader/prelude.wgsl");
fn module_source(wgsl: &str) -> String {
// The steps come from the same constants the CPU counts in, rather than
// a second copy of them written into the shader: a grid the two disagree
// about puts every coordinate somewhere else.
// Every number both sides count in, written once here rather than a
// second time in the shader: a grid the two disagree about puts every
// coordinate somewhere else, and a sentinel they disagree about makes one
// of them walk a chain from a slot the other says is not there.
format!(
"const PX_STEP: f32 = 1.0 / {}.0;\nconst REL_STEP: f32 = 1.0 / {}.0;\n{PRELUDE}\n{wgsl}",
"const PX_STEP: f32 = 1.0 / {}.0;\n\
const REL_STEP: f32 = 1.0 / {}.0;\n\
const MASK_NONE: u32 = {}u;\n\
const MOVE_NONE: u32 = {}u;\n\
const CHAIN_LIMIT: u32 = {}u;\n\
{PRELUDE}\n{wgsl}",
1u32 << crate::PX_SHIFT,
1u32 << crate::REL_SHIFT,
MaskIdx::NONE.idx(),
MoveIdx::NONE.idx(),
crate::CHAIN_LIMIT,
)
}