# llimphi-cpu > El rasterizador sin GPU de [llimphi](../README.md). 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`](../../../03_ukupacha/wawa/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 ```bash 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.