1# llimphi-cpu
2
3> The GPU-less rasterizer of [llimphi](../README.md).
4
5Records draw calls into a `Escena` —the same eight `vello::Scene` methods that
6`llimphi-compositor` uses, with identical signatures— and renders them with
7`vello_cpu` into a `Pixmap`, which is then blitted to any framebuffer honoring
8its stride and channel order.
9
10`no_std + alloc` by birth: the end consumer is wawa's bare-metal kernel, where
11there is no wgpu, no winit, and no `std`. This is W1 of
12[`PLAN-LLIMPHI.md`](../../../03_ukupacha/wawa/PLAN-LLIMPHI.md).
13
14## Why it exists
15
16`vello::Scene` is an **encoded buffer** for the GPU to devour in one go;
17`vello_cpu::RenderContext` is **imperative and stateful**. They don't plug into
18each other. `Escena` bridges the gap by recording each call as an `Orden`, and
19`Pintor` replays them, setting the state each one declares.
20
21Recording is not a detour: it is what makes `append` possible —composing a child
22scene inside the parent— without which the compositor cannot reuse the subtrees
23it cached.
24
25## Parts
26
27- `escena` — the recorder. `Escena`, `Orden`, `Forma`.
28- `pintor` — replays the scene against `vello_cpu`, yielding a `Pixmap`.
29- `lienzo` — blits the `Pixmap` to the framebuffer (`stride`, BGRA/RGBA).
30
31## What it does NOT do
32
33**Text.** Shaping lives in `llimphi-text`, still tied to `std` and to system
34fonts — that is W2 of the plan, the most expensive phase, and mixing it in here
35would bog down both.
36
37## Deps
38
39- `vello_cpu` (`default-features = false`, `u8_pipeline`)
40- `fearless_simd` (`force_support_fallback`)
41
42## The two profiles — and why they are not interchangeable
43
44```bash
45cargo test -p llimphi-cpu # std (default), Linux
46cargo check -p llimphi-cpu --target x86_64-wawa \
47 --no-default-features --features libm \
48 -Z build-std=core,alloc # bare-metal, wawa
49```
50
51`vello_common` imports `peniko::kurbo::common::FloatFuncs`, and kurbo **only
52defines that trait when its `std` feature is off**. So this crate's profile must
53match kurbo's in the same build. Since `vello` declares `peniko` with
54`default-features = true`, any build where vello and vello_cpu coexist has kurbo
55**with** std — and asking for `libm` there fails with "no `FloatFuncs` in
56`common`".
57
58Hence `std` is the default (the only coherent profile across the workspace), and
59`libm` is requested explicitly for wawa, where no vello unifies anything. Under
60`libm` the SIMD level is scalar: `Level::new()` uses `is_x86_feature_detected!`,
61which does not exist without an OS. That it suffices is not a consolation — the
62W0 spike measured it at 909-5,000 fps at 480x400.
README.md
llimphi-cpu
The GPU-less rasterizer of llimphi.
Records draw calls into a Escena —the same eight vello::Scene methods that
llimphi-compositor uses, with identical signatures— and renders them with
vello_cpu into a Pixmap, which is then blitted to any framebuffer honoring
its stride and channel order.
no_std + alloc by birth: the end consumer is wawa's bare-metal kernel, where
there is no wgpu, no winit, and no std. This is W1 of
PLAN-LLIMPHI.md.
Why it exists
vello::Scene is an encoded buffer for the GPU to devour in one go;
vello_cpu::RenderContext is imperative and stateful. They don't plug into
each other. Escena bridges the gap by recording each call as an Orden, and
Pintor replays them, setting the state each one declares.
Recording is not a detour: it is what makes append possible —composing a child
scene inside the parent— without which the compositor cannot reuse the subtrees
it cached.
Parts
escena — the recorder. Escena, Orden, Forma.
pintor — replays the scene against vello_cpu, yielding a Pixmap.
lienzo — blits the Pixmap to the framebuffer (stride, BGRA/RGBA).
What it does NOT do
Text. Shaping lives in llimphi-text, still tied to std and to system
fonts — that is W2 of the plan, the most expensive phase, and mixing it in here
would bog down both.
Deps
vello_cpu (default-features = false, u8_pipeline)
fearless_simd (force_support_fallback)
The two profiles — and why they are not interchangeable
cargo test -p llimphi-cpu # std (default), Linux
cargo check -p llimphi-cpu --target x86_64-wawa \
--no-default-features --features libm \
-Z build-std=core,alloc # bare-metal, wawa
vello_common imports peniko::kurbo::common::FloatFuncs, and kurbo only
defines that trait when its std feature is off. So this crate's profile must
match kurbo's in the same build. Since vello declares peniko with
default-features = true, any build where vello and vello_cpu coexist has kurbo
with std — and asking for libm there fails with "no FloatFuncs in
common".
Hence std is the default (the only coherent profile across the workspace), and
libm is requested explicitly for wawa, where no vello unifies anything. Under
libm the SIMD level is scalar: Level::new() uses is_x86_feature_detected!,
which does not exist without an OS. That it suffices is not a consolation — the
W0 spike measured it at 909-5,000 fps at 480x400.