Register a primitive only when it is drawn, and keep the prelude shared

Nothing seeds the registry any more, so a kind's id is decided by the first
draw and no order within a layer can be relied on even by accident. A ui that
draws no images now pays for no image pipeline, and a layer's list vector only
reaches the highest kind that layer draws.

The atlas and the sampler are still bound for every draw, but are declared by
the two shaders that read them rather than by the prelude, which is now only
what every primitive uses.

`TexturePrimitive` gets a `From<&TextureHandle>`; `Painter::texture_at` stays
because the share of the handle is what keeps the slot from being freed while
it is drawn, which a `Pod` primitive cannot hold.

Checked on the headless rig that the layers carry the ordering rather than the
ids: with a bare text drawn first, so glyph registers before rect, a stacked
label still draws over its background. Also re-ran an image alone in a layer,
now the only primitive a ui registers, and a four-layer atlas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-13 16:52:32 -04:00
1 parent 29d390da52
commit 01a9b8633d
6 files changed
+35 -40

No files matched your search

+5 -8
View File
@@ -28,8 +28,7 @@ impl<'a> Painter<'a> {
self.write(kind, primitive, region);
}
/// For a caller with many of one primitive to write, since looking the kind
/// up is per type rather than per instance.
/// Takes the kind, for a caller writing many of one primitive.
fn write<P: Primitive>(&mut self, kind: PrimitiveKind<P>, primitive: P, region: UiRegion) {
let h = self.state.layers.write(
self.layer,
@@ -98,14 +97,12 @@ impl<'a> Painter<'a> {
self.texture_at(handle, self.region);
}
/// A texture primitive, plus a share of the handle it names -- which a
/// `Pod` primitive cannot carry, and without which the slot could be
/// freed and reused while still drawn.
pub fn texture_at(&mut self, handle: &TextureHandle, region: UiRegion) {
self.textures.push(handle.clone());
self.primitive_at(
TexturePrimitive {
slot: handle.slot(),
},
region,
);
self.primitive_at(TexturePrimitive::from(handle), region);
}
pub fn render_text(