`draw` had three branches, one per shader, which is the dynamic dispatch this
was asking for. A primitive now brings a `PrimitiveRender`: it states the
layout its shader reads, uploads whatever it owns, and records its own draws.
`GlyphRender` owns the atlas and binds it once for a list; `ImageRender` owns
the images and binds one per instance; the default owns nothing and draws them
all in one call. The renderer sets the pipeline, the shared group, the list's
data and the vertex buffer, and knows nothing else about what it is drawing.
Measured before committing to it, since dispatch per list is the cost. Wall
time on this machine swings 2x between runs of one binary, so the comparison
is instructions retired, which is stable to 0.1%: at 256 layers drawing 8
rects, 8 glyphs and 2 images each, 7.4074e9 against 7.4145e9, and at 1024
layers 27.467e9 against 27.498e9. Both are 0.1%, which is 6 instructions per
list drawn -- one indirect call. Recording a list into the pass costs wgpu
about 5,400.
`tests/draw_cost.rs` is that measurement, kept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replace the cosmic-text path with Parley layout and Swash rasterization, backed by shared glyph-atlas pages. Shaping, editing, rasterization, and glyph rendering move together because they share the text buffer and rendered-glyph types; splitting them further would require a temporary renderer that is immediately removed.
This is reconstructed rather than replayed from the extraction history. It also fixes issues found during review:
- texture binding changes remain set when an atlas patch follows a new page
- pressing an empty field places a caret and accepts input
- selection motion delegates collapse behavior to Parley
- character deletion follows logical clusters rather than visual neighbors
- the unused root-level Swash dependency is omitted
Four public-behavior integration tests live in `tests/text_edit.rs`: empty-field input, multibyte IME preedit replacement, UTF-8-safe backspace, and selection replacement. The old twelve-test inline block and implementation-restating cases are omitted.
Every added source comment was manually reviewed. Comments that narrated implementation or history were removed; retained comments document cache/rasterization keys, GPU upload constraints, focus representation, bidi geometry, or IME semantics.
Known limitation: atlas pages currently grow without eviction. Each page is 4 MiB on CPU and GPU. An arbitrary cap would leave cached rendered-text UVs pointing at reused glyph slots, so bounding this safely needs a later generation/invalidation change.
This changes public text types and signatures. GPU glyph rendering is covered by compilation rather than a live-surface test.
Verified with:
- `cargo fmt --all --check`
- `cargo clippy --workspace --all-targets -- -D warnings`
- `cargo test --workspace` (four integration tests pass)
Cargo still reports inherited future-incompatibility notices for existing wgpu/winit dependencies; there are no current clippy warnings.
---------
Co-authored-by: iris <2+iris@noreply.localhost>
Reviewed-on: iris/iris#10
Reviewed-by: iris <2+iris@noreply.localhost>
Co-authored-by: AIris <4+iris-ai@noreply.localhost>