# llimphi-cpu > The GPU-less rasterizer of [llimphi](../README.md). 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`](../../../03_ukupacha/wawa/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 ```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` 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.