1# llimphi-cpu
2
3> El rasterizador sin GPU de [llimphi](../README.md).
4
5Graba las órdenes de dibujo en una `Escena` —los mismos ocho métodos de
6`vello::Scene` que usa `llimphi-compositor`, con idéntica firma— y las rinde con
7`vello_cpu` a un `Pixmap`, que se vuelca a cualquier framebuffer con su stride y
8su orden de canales.
9
10`no_std + alloc` de nacimiento: el consumidor final es el kernel bare-metal de
11wawa, donde no hay wgpu, ni winit, ni `std`. Es W1 de
12[`PLAN-LLIMPHI.md`](../../../03_ukupacha/wawa/PLAN-LLIMPHI.md).
13
14## Por qué existe
15
16`vello::Scene` es un **buffer codificado** para que la GPU lo consuma de un
17saque; `vello_cpu::RenderContext` es **imperativo y con estado**. No se
18enchufan. `Escena` cierra la brecha grabando cada llamada como una `Orden`, y
19`Pintor` las reproduce fijando el estado que cada una declara.
20
21Grabar no es un rodeo: es lo que hace posible `append` —componer una escena hija
22dentro de la madre— sin el cual el compositor no puede reciclar los subárboles
23que cacheó.
24
25## Piezas
26
27- `escena` — la grabadora. `Escena`, `Orden`, `Forma`.
28- `pintor` — reproduce la escena contra `vello_cpu` y deja un `Pixmap`.
29- `lienzo` — vuelca el `Pixmap` al framebuffer (`stride`, BGRA/RGBA).
30
31## Lo que NO hace
32
33**Texto.** El shaping vive en `llimphi-text`, todavía atado a `std` y a las
34fuentes del sistema — es W2 del plan, la fase más cara, y mezclarla acá
35empantanaría las dos.
36
37## Deps
38
39- `vello_cpu` (`default-features = false`, `u8_pipeline`)
40- `fearless_simd` (`force_support_fallback`)
41
42## Los dos perfiles — y por qué no son intercambiables
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` importa `peniko::kurbo::common::FloatFuncs`, y kurbo **sólo
52define ese trait cuando su feature `std` está apagada**. O sea: el perfil de
53este crate tiene que coincidir con el de kurbo en el mismo build. Como `vello`
54declara `peniko` con `default-features = true`, cualquier build donde vello y
55vello_cpu convivan tiene kurbo **con** std — y ahí pedir `libm` falla con
56«no `FloatFuncs` in `common`».
57
58Por eso `std` es el default (es el único perfil coherente en el workspace) y
59`libm` se pide explícitamente para wawa, donde no hay vello que unifique nada.
60Con `libm` el nivel SIMD es el escalar: `Level::new()` usa
61`is_x86_feature_detected!`, que no existe sin sistema operativo. Que alcance no
62es consuelo — el spike de W0 lo midió en 909-5.000 fps a 480x400.
LEEME.md
llimphi-cpu
El rasterizador sin GPU de llimphi.
Graba las órdenes de dibujo en una Escena —los mismos ocho métodos de
vello::Scene que usa llimphi-compositor, con idéntica firma— y las rinde con
vello_cpu a un Pixmap, que se vuelca a cualquier framebuffer con su stride y
su orden de canales.
no_std + alloc de nacimiento: el consumidor final es el kernel bare-metal de
wawa, donde no hay wgpu, ni winit, ni std. Es W1 de
PLAN-LLIMPHI.md.
Por qué existe
vello::Scene es un buffer codificado para que la GPU lo consuma de un
saque; vello_cpu::RenderContext es imperativo y con estado. No se
enchufan. Escena cierra la brecha grabando cada llamada como una Orden, y
Pintor las reproduce fijando el estado que cada una declara.
Grabar no es un rodeo: es lo que hace posible append —componer una escena hija
dentro de la madre— sin el cual el compositor no puede reciclar los subárboles
que cacheó.
Piezas
escena — la grabadora. Escena, Orden, Forma.
pintor — reproduce la escena contra vello_cpu y deja un Pixmap.
lienzo — vuelca el Pixmap al framebuffer (stride, BGRA/RGBA).
Lo que NO hace
Texto. El shaping vive en llimphi-text, todavía atado a std y a las
fuentes del sistema — es W2 del plan, la fase más cara, y mezclarla acá
empantanaría las dos.
Deps
vello_cpu (default-features = false, u8_pipeline)
fearless_simd (force_support_fallback)
Los dos perfiles — y por qué no son intercambiables
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 importa peniko::kurbo::common::FloatFuncs, y kurbo sólo
define ese trait cuando su feature std está apagada. O sea: el perfil de
este crate tiene que coincidir con el de kurbo en el mismo build. Como vello
declara peniko con default-features = true, cualquier build donde vello y
vello_cpu convivan tiene kurbo con std — y ahí pedir libm falla con
«no FloatFuncs in common».
Por eso std es el default (es el único perfil coherente en el workspace) y
libm se pide explícitamente para wawa, donde no hay vello que unifique nada.
Con libm el nivel SIMD es el escalar: Level::new() usa
is_x86_feature_detected!, que no existe sin sistema operativo. Que alcance no
es consuelo — el spike de W0 lo midió en 909-5.000 fps a 480x400.