tawasuyu

tawasuyu/llimphi

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

Rust 660Markdown 302TOML 157RON 312382 Sutichaykuna

⎇ main llimphi-wawa/tests/wire_vs_directo.rs Rust · 103 siq'ikuna · 4.0 KB Ñawpa willay Pi imata llamkarqan ch'uya

chore: refresco desde el monorepo — vello 0.9 / wgpu 29, 120 miembros d251eb32b · Sergio ·

1//! **Reproducir una escena que llegó por el cable, ¿da los mismos píxeles que
2//! componerla acá?**
3//!
4//! El IR de escena (W4) tiene round-trip **estructural** certificado:
5//! `llimphi-wire-escena/src/pruebas.rs` verifica que cada variante sobreviva la
6//! serialización, que el texto viaje sin shapear, que el degradé conserve sus
7//! paradas. Lo que **no** verificaba nadie es que reproducir esas órdenes
8//! **dibuje lo mismo**. Un reproductor que aplicara las transformaciones en
9//! otro orden, o que remapeara mal un estilo internado, pasaría todos los tests
10//! estructurales y pintaría otra cosa.
11//!
12//! Acá los dos caminos terminan en el **mismo** rasterizador (`vello_cpu`) y
13//! sobre el **mismo** árbol (`escena_patron.rs`), así que lo que se exige no es
14//! una tolerancia sino **igualdad bit a bit**: cualquier diferencia es un error
15//! del emisor o del reproductor, no del antialiasing.
16//!
17//! La escena de cable la produce `llimphi-jaula` (backend `wire`), que no puede
18//! vivir en este binario —los backends de `llimphi-text` son excluyentes—:
19//!
20//! ```bash
21//! ./scripts/check-llimphi-cpu-vs-gpu.sh
22//! ```
23//!
24//! Sin los `.wire` el test se saltea, con el comando para generarlos.
25
26use llimphi_cpu::lienzo::FormatoPixel;
27use llimphi_wawa::Cascara;
28
29include!("../../escena_patron.rs");
30
31fn volcado(c: &Cascara) -> Vec<u8> {
32    let mut px = vec![0u8; (ANCHO * ALTO * 4) as usize];
33    c.volcar(&mut px, (ANCHO * 4) as usize, FormatoPixel::Rgba8);
34    px
35}
36
37#[test]
38fn lo_que_llega_por_el_cable_se_pinta_igual_que_lo_compuesto_aca() {
39    let Ok(dir) = std::env::var("LLIMPHI_WIRE_DUMP") else {
40        eprintln!(
41            "salteado: faltan las escenas de cable. Generalas con\n  \
42             ./scripts/check-llimphi-cpu-vs-gpu.sh"
43        );
44        return;
45    };
46    let dir = std::path::PathBuf::from(dir);
47
48    let mut cascara = Cascara::new(ANCHO as u16, ALTO as u16);
49    let mut probados = 0;
50    for (nombre, vista) in patrones::<()>() {
51        // El patrón de texto no cruza el cable en esta prueba: medir una cadena
52        // es una pregunta que contesta este lado, y el emisor no puede
53        // responderla solo. Ver el encabezado de `emitir_patron.rs`.
54        let Ok(bytes) = std::fs::read(dir.join(format!("{nombre}.wire"))) else {
55            continue;
56        };
57
58        cascara.fotograma(vista);
59        let directo = volcado(&cascara);
60
61        let wire: llimphi_wire_escena::EscenaWire =
62            postcard::from_bytes(&bytes).expect("deserializar la escena de cable");
63        let st = cascara.fotograma_wire(&wire);
64        let por_cable = volcado(&cascara);
65
66        let distintos = directo
67            .chunks_exact(4)
68            .zip(por_cable.chunks_exact(4))
69            .filter(|(a, b)| a != b)
70            .count();
71        // Evidencia por texto (Regla 8): el número queda impreso corra o falle.
72        println!(
73            "{nombre:8} · {} bytes de cable · {} órdenes ({} salteadas) · {distintos} px distintos",
74            bytes.len(),
75            st.ejecutadas,
76            st.salteadas
77        );
78        assert_eq!(
79            distintos, 0,
80            "{nombre}: reproducir la escena del cable pintó algo distinto de \
81             componerla acá — mismo rasterizador, así que es el cable"
82        );
83        // Guarda del arnés: una escena vacía se reproduce «igual» a la nada y
84        // el test pasaría sin haber comparado un dibujo.
85        assert!(
86            st.ejecutadas > 0,
87            "{nombre}: la escena del cable llegó sin una sola orden"
88        );
89        // Y el reproductor tiene un contador propio para lo que no supo
90        // ejecutar. Cero píxeles distintos con órdenes salteadas sería la
91        // combinación más engañosa que hay: dos escenas igual de incompletas.
92        assert_eq!(
93            st.salteadas, 0,
94            "{nombre}: el reproductor salteó {} órdenes",
95            st.salteadas
96        );
97        probados += 1;
98    }
99    assert!(
100        probados >= 4,
101        "sólo {probados} patrones cruzaron el cable; el arnés no está probando"
102    );
103}