tawasuyu/llimphi
Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.
chore: refresco desde el monorepo — vello 0.9 / wgpu 29, 120 miembros
1// =============================================================================
2// llimphi-hybrid :: la tercera técnica de rasterización
3// -----------------------------------------------------------------------------
4// Llimphi tiene ya dos rasterizadores y ninguno sirve en el teléfono:
5//
6// llimphi-raster vello sobre wgpu — COMPUTE SHADERS. El camino de siempre.
7// llimphi-cpu vello_cpu — sin GPU del todo. El camino de wawa bare-metal.
8//
9// Este es el tercero, y nació de una medición, no de un gusto. El diagnóstico
10// de `02_ruway/llimphi/android/DIAGNOSTICO.md` probó, cambiando UNA variable
11// por vez sobre el mismo Redmi Note 13 Pro (Mali-G57 MC2, driver
12// `libGLES_mali.so v1.r54p1-09bet0`):
13//
14// rasterizador backend resultado
15// ninguno (clear) Vulkan anda · 176 MB GL
16// vello (compute) Vulkan DEVICE LOST al primer frame · 437 MB GL
17// vello (compute) GLES SIGABRT en «Vello shader init»
18// vello_hybrid Vulkan SIGSEGV en cmpbe_v2_compile_multiple_shaders
19// vello_hybrid GLES ✅ 119 fps · 0,0% negro · 205 MB GL
20//
21// O sea: el compilador de shaders de ese driver no digiere el compute de vello
22// por NINGÚN camino, y sólo digiere los pipelines de render de vello_hybrid por
23// GLES. Una sola celda de esa matriz llega a la pantalla, y ésta es la pieza
24// que la usa.
25//
26// ## Lo que este crate NO reinventa
27//
28// La mitad difícil ya estaba escrita. `vello::Scene` es un buffer CODIFICADO y
29// `vello_hybrid::Scene` es imperativa y con estado — la misma brecha que
30// `llimphi-cpu` cerró para vello_cpu, con la misma forma de solución. Así que
31// acá se reusa su [`Escena`](llimphi_cpu::Escena) grabadora tal cual, y lo
32// único propio es el reproductor.
33//
34// Que se pueda reusar no es suerte: `vello_cpu::RenderContext` y
35// `vello_hybrid::Scene` son la MISMA API, método por método —`set_paint`,
36// `set_transform`, `fill_path`, `push_layer` con la misma firma de cinco
37// `Option`—, porque las dos son fachadas del mismo `vello_common`. De ahí que
38// este pintor sea casi renglón por renglón el de `llimphi-cpu`.
39//
40// ## Las dos cosas que sí cambian, y por qué
41//
42// **Las imágenes.** vello_cpu muestrea un `Pixmap` en RAM; hybrid quiere la
43// imagen ya subida a un atlas de texturas y referida por `ImageId` (los propios
44// autores marcan el pixmap como fuera de alcance en `scene.rs`). Eso parte el
45// trabajo en dos pasadas —subir, después reproducir—, porque subir necesita
46// `device`/`queue`/`encoder` y reproducir no. Ver [`Pintor::pintar`].
47//
48// **La máscara de luminancia.** vello_hybrid directamente no soporta máscaras
49// —`unimplemented!()` en `scene.rs:921`—, así que hay que rodearla. El rodeo
50// resulta exacto: la máscara siempre nace de una FORMA, y la luminancia de una
51// forma blanca sobre negro es idéntica a la cobertura de un recorte por esa
52// misma forma. Ver [`Pintor::pintar`] y el comentario del método.
53//
54// ## Lo que falta cubrir
55//
56// El texto (`Orden::Glifos`) está implementado pero **sin test**: probarlo
57// headless exigiría una fuente, y el puente que produce esas órdenes vive en
58// `llimphi-text`. Se verifica de punta a punta en el teléfono (F2), que es
59// donde de todos modos hay que mirarlo. Las otras seis órdenes sí tienen test
60// con conteo exacto de píxeles contra GPU real.
61// =============================================================================
62
63mod pintor;
64
65#[cfg(test)]
66mod pruebas;
67
68pub use pintor::{limites_seguros, Pintor, RenderError};
69
70// Se reexporta el sustrato por el mismo motivo que lo hace `llimphi-cpu`: para
71// que quien use este crate no declare `vello_hybrid` ni `wgpu` por su cuenta y
72// termine con DOS versiones y un «expected Device, found Device». Acá el riesgo
73// vale aunque hoy el workspace entero comparta wgpu 29: un consumidor que
74// declare `wgpu` suelto puede derivar de esa versión sin que nadie lo note.
75pub use vello_hybrid;
76pub use wgpu;
77
78// Y la grabadora, para que el consumidor no tenga que saber que vive en otro
79// crate: desde afuera, grabar y reproducir son una sola pieza.
80pub use llimphi_cpu::{escena, Escena, Forma, Glifo, Orden};