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:
1 parent
7b318e3271
commit
29d390da52
11 files changed
+268
-333
No files matched your search
+17
-20
@@ -2,8 +2,8 @@ use crate::{
|
||||
Axis, Len, RenderedText, Size, SizeCtx, StrongWidget, TextAttrs, TextBuffer, TextData,
|
||||
TextureHandle, UiRegion, UiRenderState, UiRsc, UiScalar, UiVec2, Widget, WidgetId,
|
||||
render::{
|
||||
GLYPH, GlyphPrimitive, Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst,
|
||||
PrimitiveKind, TEXTURE, TexturePrimitive,
|
||||
GlyphPrimitive, Mask, MaskIdx, Primitive, PrimitiveHandle, PrimitiveInst, PrimitiveKind,
|
||||
TexturePrimitive,
|
||||
},
|
||||
util::Vec2,
|
||||
};
|
||||
@@ -23,12 +23,14 @@ pub struct Painter<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Painter<'a> {
|
||||
fn primitive_at<P: Primitive>(
|
||||
&mut self,
|
||||
kind: PrimitiveKind<P>,
|
||||
primitive: P,
|
||||
region: UiRegion,
|
||||
) {
|
||||
fn primitive_at<P: Primitive>(&mut self, primitive: P, region: UiRegion) {
|
||||
let kind = self.rsc.ui_mut().primitives.kind::<P>();
|
||||
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.
|
||||
fn write<P: Primitive>(&mut self, kind: PrimitiveKind<P>, primitive: P, region: UiRegion) {
|
||||
let h = self.state.layers.write(
|
||||
self.layer,
|
||||
PrimitiveInst {
|
||||
@@ -51,17 +53,12 @@ impl<'a> Painter<'a> {
|
||||
}
|
||||
|
||||
/// Writes a primitive to be rendered
|
||||
pub fn primitive<P: Primitive>(&mut self, kind: PrimitiveKind<P>, primitive: P) {
|
||||
self.primitive_at(kind, primitive, self.region)
|
||||
pub fn primitive<P: Primitive>(&mut self, primitive: P) {
|
||||
self.primitive_at(primitive, self.region)
|
||||
}
|
||||
|
||||
pub fn primitive_within<P: Primitive>(
|
||||
&mut self,
|
||||
kind: PrimitiveKind<P>,
|
||||
primitive: P,
|
||||
region: UiRegion,
|
||||
) {
|
||||
self.primitive_at(kind, primitive, region.within(&self.region));
|
||||
pub fn primitive_within<P: Primitive>(&mut self, primitive: P, region: UiRegion) {
|
||||
self.primitive_at(primitive, region.within(&self.region));
|
||||
}
|
||||
|
||||
pub fn set_mask(&mut self, region: UiRegion) {
|
||||
@@ -104,7 +101,6 @@ impl<'a> Painter<'a> {
|
||||
pub fn texture_at(&mut self, handle: &TextureHandle, region: UiRegion) {
|
||||
self.textures.push(handle.clone());
|
||||
self.primitive_at(
|
||||
TEXTURE,
|
||||
TexturePrimitive {
|
||||
slot: handle.slot(),
|
||||
},
|
||||
@@ -123,6 +119,7 @@ impl<'a> Painter<'a> {
|
||||
}
|
||||
|
||||
pub fn glyphs(&mut self, text: &RenderedText, origin: UiRegion) {
|
||||
let kind = self.rsc.ui_mut().primitives.kind::<GlyphPrimitive>();
|
||||
for glyph in text.glyphs.iter() {
|
||||
let mut region = origin;
|
||||
region.x.end = region.x.start;
|
||||
@@ -130,8 +127,8 @@ impl<'a> Painter<'a> {
|
||||
let mut region = region.offset(UiVec2::abs(glyph.offset));
|
||||
region.x.end = region.x.start + UiScalar::abs(glyph.entry.width as f32);
|
||||
region.y.end = region.y.start + UiScalar::abs(glyph.entry.height as f32);
|
||||
self.primitive_at(
|
||||
GLYPH,
|
||||
self.write(
|
||||
kind,
|
||||
GlyphPrimitive {
|
||||
uv_min: glyph.entry.uv_min,
|
||||
uv_max: glyph.entry.uv_max,
|
||||
|
||||
Reference in new issue
Block a user