1# llimphi-wawa
2
3> La cáscara de [llimphi](../README.md) sobre el framebuffer del kernel.
4
5Cierra el ciclo `View<Msg> → mount → layout → paint → volcar` **sin winit, sin
6GPU y sin `std`**. Es el gemelo de `llimphi-ui` para wawa: mismo compositor,
7misma composición, otra piel. W3.c de
8[`PLAN-LLIMPHI.md`](../../../03_ukupacha/wawa/PLAN-LLIMPHI.md).
9
10Deliberadamente delgada: no reimplementa una línea del compositor. El árbol, el
11layout de taffy, el paint y el hit-test son el **mismo código** que corre en
12Linux, compilado con otras features.
13
14## Uso
15
16```rust
17let mut cascara = Cascara::new(ancho, alto);
18
19// Por fotograma:
20let montado = cascara.fotograma(mi_vista);
21cascara.volcar(framebuffer, stride_bytes, Formato::Bgra8);
22
23// Al llegar un click del kernel:
24if let Some(msg) = cascara.click(&montado, x, y) {
25 modelo = App::update(modelo, msg);
26}
27```
28
29## Lo que NO hace, a propósito
30
31- **No tiene bucle propio.** Quien manda es el reactor cooperativo del kernel;
32 la cáscara ofrece `fotograma()` y `click()` para que los invoque cuando
33 corresponda. Un bucle acá pelearía con el de afuera.
34- **No sabe la hora.** El instante del fotograma entra por argumento (el kernel
35 lo saca de su PIT), la misma disciplina que impone
36 `llimphi_compositor::Instant`, que no tiene `now()`.
37- **No toca el hardware.** Recibe un `&mut [u8]` y su stride. Quién mapeó esa
38 memoria —GOP del firmware, scanout de virtio-gpu— es asunto del kernel.
39
40## El otro camino: escenas que llegan por el cable (W4)
41
42`fotograma()` recibe un `View<Msg>` y lo monta acá. Pero una app `.wasm` compone
43**del otro lado de la frontera** y manda el resultado ya compuesto, como
44[`llimphi-wire-escena`](../llimphi-wire-escena/LEEME.md). Para eso está el gemelo:
45
46```rust
47let recibida: EscenaWire = postcard::from_bytes(&bytes)?;
48let st = cascara.fotograma_wire(&recibida);
49// st.textos = cuántas cadenas se shapearon de ESTE lado — el punto de W4.1
50```
51
52Del `pintar` para abajo son el mismo código: el kernel no necesita dos
53rasterizadores porque no hay dos clases de dibujo.
54
55Tres cosas que conviene saber de este camino:
56
57- **El `Typesetter` es el de la cáscara**, no uno nuevo. El texto llega sin
58 shapear y se resuelve acá, así que el caché tiene que sobrevivir entre
59 fotogramas — uno nuevo por fotograma haría que cada uno fuera «frío» (3,4 fps
60 en vez de 53, según W4.1).
61- **No confía en el cable.** La escena viene de una app enjaulada: índices de
62 estilo fuera de rango e imágenes sin blob se cuentan en
63 `EstadisticasReproduccion` y se siguen. Un `unwrap` ahí sería un pánico en
64 Ring 0 disparable desde userspace.
65- **No hay hit-test, y es correcto.** El árbol de nodos se quedó del otro lado de
66 la frontera; quien sabe qué hay bajo el puntero es la app. El input viaja de
67 vuelta como coordenada.
68
69## Deps
70
71- `llimphi-compositor` (feature `cpu`) · `llimphi-cpu` · `llimphi-text` ·
72 `llimphi-layout` · `llimphi-wire-escena`
73
74Feature `std`: correr la cáscara en el anfitrión, para tests. El default es
75`libm` — el perfil bare-metal para el que este crate existe.
LEEME.md
llimphi-wawa
La cáscara de llimphi sobre el framebuffer del kernel.
Cierra el ciclo View<Msg> → mount → layout → paint → volcar sin winit, sin
GPU y sin std. Es el gemelo de llimphi-ui para wawa: mismo compositor,
misma composición, otra piel. W3.c de
PLAN-LLIMPHI.md.
Deliberadamente delgada: no reimplementa una línea del compositor. El árbol, el
layout de taffy, el paint y el hit-test son el mismo código que corre en
Linux, compilado con otras features.
Uso
let mut cascara = Cascara::new(ancho, alto);
// Por fotograma:
let montado = cascara.fotograma(mi_vista);
cascara.volcar(framebuffer, stride_bytes, Formato::Bgra8);
// Al llegar un click del kernel:
if let Some(msg) = cascara.click(&montado, x, y) {
modelo = App::update(modelo, msg);
}
Lo que NO hace, a propósito
- No tiene bucle propio. Quien manda es el reactor cooperativo del kernel;
la cáscara ofrece
fotograma() y click() para que los invoque cuando
corresponda. Un bucle acá pelearía con el de afuera.
- No sabe la hora. El instante del fotograma entra por argumento (el kernel
lo saca de su PIT), la misma disciplina que impone
llimphi_compositor::Instant, que no tiene now().
- No toca el hardware. Recibe un
&mut [u8] y su stride. Quién mapeó esa
memoria —GOP del firmware, scanout de virtio-gpu— es asunto del kernel.
El otro camino: escenas que llegan por el cable (W4)
fotograma() recibe un View<Msg> y lo monta acá. Pero una app .wasm compone
del otro lado de la frontera y manda el resultado ya compuesto, como
llimphi-wire-escena. Para eso está el gemelo:
let recibida: EscenaWire = postcard::from_bytes(&bytes)?;
let st = cascara.fotograma_wire(&recibida);
// st.textos = cuántas cadenas se shapearon de ESTE lado — el punto de W4.1
Del pintar para abajo son el mismo código: el kernel no necesita dos
rasterizadores porque no hay dos clases de dibujo.
Tres cosas que conviene saber de este camino:
- El
Typesetter es el de la cáscara, no uno nuevo. El texto llega sin
shapear y se resuelve acá, así que el caché tiene que sobrevivir entre
fotogramas — uno nuevo por fotograma haría que cada uno fuera «frío» (3,4 fps
en vez de 53, según W4.1).
- No confía en el cable. La escena viene de una app enjaulada: índices de
estilo fuera de rango e imágenes sin blob se cuentan en
EstadisticasReproduccion y se siguen. Un unwrap ahí sería un pánico en
Ring 0 disparable desde userspace.
- No hay hit-test, y es correcto. El árbol de nodos se quedó del otro lado de
la frontera; quien sabe qué hay bajo el puntero es la app. El input viaja de
vuelta como coordenada.
Deps
llimphi-compositor (feature cpu) · llimphi-cpu · llimphi-text ·
llimphi-layout · llimphi-wire-escena
Feature std: correr la cáscara en el anfitrión, para tests. El default es
libm — el perfil bare-metal para el que este crate existe.