Take a primitive's kind from its type, and keep images out of the rest

A `Primitive` now carries its own WGSL, and `PrimitiveRegistry` keys ids by
`TypeId`, so `Painter::primitive` takes only the value and the `RECT`,
`GLYPH` and `TEXTURE` constants are gone. Registering is what a first draw
does; the built-ins are seeded up front so first-draw order cannot decide
anything about them.

What a primitive samples is no longer something every registration states.
The glyph atlas and the one sampler moved into the shared group, which is
where a mask texture would go too, so a rect's pipeline has no texture in
its layout at all. Only a primitive whose type sets `TEXTURE` gets an image
group, and that is also what records the slot at write time -- so nothing
reads a `u32` back out of the instance payload.

Verified on the headless rig: the tabs example, two images added at runtime,
an image alone in a layer, and text spanning a four-layer atlas after the
array grew twice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-13 16:14:53 -04:00
1 parent 7b318e3271
commit 29d390da52
11 files changed
+268 -333

No files matched your search

+6 -9
View File
@@ -29,15 +29,12 @@ impl Rect {
impl Widget for Rect {
fn draw(&mut self, painter: &mut Painter) {
painter.primitive(
RECT,
RectPrimitive {
color: self.color,
radius: self.radius,
thickness: self.thickness,
inner_radius: self.inner_radius,
},
);
painter.primitive(RectPrimitive {
color: self.color,
radius: self.radius,
thickness: self.thickness,
inner_radius: self.inner_radius,
});
}
fn desired_width(&mut self, _: &mut SizeCtx) -> Len {
-2
View File
@@ -73,7 +73,6 @@ impl Widget for TextEdit {
let size = vec2(rect.width() as f32, rect.height() as f32);
let top_left = vec2(rect.x0 as f32, rect.y0 as f32);
painter.primitive_within(
RECT,
RectPrimitive::color(Color::SKY),
size.align(Align::TOP_LEFT).offset(top_left).within(&region),
);
@@ -83,7 +82,6 @@ impl Widget for TextEdit {
let size = vec2(caret.width() as f32, caret.height() as f32);
let top_left = vec2(caret.x0 as f32, caret.y0 as f32);
painter.primitive_within(
RECT,
RectPrimitive::color(Color::WHITE),
size.align(Align::TOP_LEFT).offset(top_left).within(&region),
);