tawasuyu

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 238TOML 102Markdown 83Shell 24178 Definitions

⎇ 14d76bd4af13b219f0b162a54f09e784dea9aa8d llimphi-raster/src/lib.rs Rust · 120 lines · 4.1 KB History Who touched what raw

feat: llimphi standalone — framework UI soberano extraído del monorepo e65e9cc62 · Sergio ·

1//! llimphi-raster — Brocha Matemática.
2//!
3//! Traduce primitivas vectoriales (líneas, curvas de Bézier, texto) a
4//! píxeles via Compute Shaders. Backend: `vello`.
5//!
6//! Punto de entrada: [`Renderer`]. Recibe una [`vello::Scene`] y la pinta
7//! sobre un [`llimphi_hal::Frame`].
8
9use llimphi_hal::{Frame, Hal};
10pub use vello;
11pub use vello::kurbo;
12pub use vello::peniko;
13
14pub mod gpu;
15pub use gpu::{GpuBatch, GpuPipelines};
16
17/// Errores del rasterizador.
18#[derive(Debug)]
19pub enum RasterError {
20    Init(String),
21    Render(String),
22}
23
24impl std::fmt::Display for RasterError {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        match self {
27            Self::Init(s) => write!(f, "vello init: {s}"),
28            Self::Render(s) => write!(f, "vello render: {s}"),
29        }
30    }
31}
32
33impl std::error::Error for RasterError {}
34
35/// Rasterizador vectorial. Una instancia por surface (porque vello cachea
36/// resources contra un `surface_format` específico).
37pub struct Renderer {
38    inner: vello::Renderer,
39}
40
41impl Renderer {
42    /// Inicializa el rasterizador. Vello acepta cualquier textura compatible
43    /// (Rgba8Unorm / Bgra8Unorm) en `render`, así que no se fija un formato
44    /// en construcción.
45    ///
46    /// **`antialiasing_support`**: pedimos `area` solamente, no `all()`.
47    /// `area` es el único método que `render()` usa (`AaConfig::Area`
48    /// fijo). Pedir `all()` haría a vello compilar también pipelines
49    /// para `msaa8` y `msaa16` que nunca se invocan — en Mali-G57 eso
50    /// triplica el cold-start (medido: 3.7s vs ~1.2s). Si alguna app
51    /// futura necesita MSAA, agregamos un constructor explícito.
52    ///
53    /// **`num_init_threads: None`**: vello paraleliza la compilación
54    /// de shaders en `None` → todos los CPU cores. Mali-G57 viene en
55    /// SoCs octa-core ARM; con 1 thread tardamos 2.0s, con 8 esperamos
56    /// ~400-600ms. La compilación de shaders es 100% CPU (Rust →
57    /// SPIR-V), el GPU no participa, así que multi-thread escala
58    /// casi linealmente hasta saturar el queue del Naga compiler.
59    pub fn new(hal: &Hal) -> Result<Self, RasterError> {
60        let inner = vello::Renderer::new(
61            &hal.device,
62            vello::RendererOptions {
63                use_cpu: false,
64                antialiasing_support: vello::AaSupport {
65                    area: true,
66                    msaa8: false,
67                    msaa16: false,
68                },
69                num_init_threads: None,
70                pipeline_cache: None,
71            },
72        )
73        .map_err(|e| RasterError::Init(e.to_string()))?;
74        Ok(Self { inner })
75    }
76
77    /// Renderiza `scene` sobre `frame` limpiando con `base_color`. AA fija
78    /// en area-sampling (precisión Δ < 10⁻⁹ rad del SDD).
79    pub fn render(
80        &mut self,
81        hal: &Hal,
82        scene: &vello::Scene,
83        frame: &Frame,
84        base_color: peniko::Color,
85    ) -> Result<(), RasterError> {
86        let (width, height) = frame.size();
87        self.render_to_view(hal, scene, frame.view(), width, height, base_color)
88    }
89
90    /// Como [`render`](Self::render) pero contra una vista de textura
91    /// explícita (mismo formato/tamaño que la intermedia). Lo usa el
92    /// compositor de overlay de `llimphi-ui` para rasterizar la capa de
93    /// overlay sobre fondo transparente en su propia textura. Ojo:
94    /// `render_to_texture` **limpia** el target con `base_color` y escribe
95    /// todos los píxeles — no compone sobre contenido previo.
96    pub fn render_to_view(
97        &mut self,
98        hal: &Hal,
99        scene: &vello::Scene,
100        view: &llimphi_hal::wgpu::TextureView,
101        width: u32,
102        height: u32,
103        base_color: peniko::Color,
104    ) -> Result<(), RasterError> {
105        self.inner
106            .render_to_texture(
107                &hal.device,
108                &hal.queue,
109                scene,
110                view,
111                &vello::RenderParams {
112                    base_color,
113                    width,
114                    height,
115                    antialiasing_method: vello::AaConfig::Area,
116                },
117            )
118            .map_err(|e| RasterError::Render(e.to_string()))
119    }
120}