Files
llimphi/llimphi-hal/examples/canvas_clear.rs
T
Sergio d251eb32b6 chore: refresco desde el monorepo — vello 0.9 / wgpu 29, 120 miembros
El repo publico se habia quedado en julio: el README anunciaba vello 0.7 +
wgpu 27 (dos bumps atras) y faltaban los crates del ultimo mes.

- refresco con scripts/actualizar-standalone.py --llimphi (cargo check OK)
- llegan llimphi-cpu, llimphi-hybrid, llimphi-glifos y llimphi-wire-escena:
  los cuatro caminos a pixeles con un solo compositor
- MANUAL.md / SDD.md / LEEME.md sincronizados con el monorepo
- README: versiones al dia, install por crates.io (cargo add llimphi),
  seccion "beyond the 2D widget kit" y el indice de crates que apuntaba
  al propio README ahora apunta a MANUAL.md §19
2026-08-06 17:26:11 +00:00

102 lines
3.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! El `clear_screen` del navegador: pinta un `<canvas>` de gris plomo con
//! [`CanvasSurface`], el HAL de wasm32.
//!
//! Es el gemelo web de `clear_screen.rs` y cumple la misma función que aquel:
//! ser el consumidor mínimo del HAL, para que un cambio de API rompa acá y no
//! meses después en una app. Ejercita el camino entero —canvas del DOM →
//! `Hal::for_canvas` → `resize_to_css` → `acquire` → render pass → `present`—
//! sin depender del event loop de `llimphi-ui`, que todavía no cruzó a web.
//!
//! Verificación (no linkea, no necesita navegador ni wasm-bindgen-cli):
//!
//! ```sh
//! cargo check -p llimphi-hal --target wasm32-unknown-unknown --examples
//! ```
//!
//! Para correrlo de verdad hace falta empaquetarlo con `wasm-bindgen-cli` y
//! servir un HTML con un `<canvas id="llimphi">`. No hay script de eso todavía
//! — ver `PORTING.md` §wasm32.
// En cualquier target nativo este example no aplica: la `CanvasSurface` sólo
// existe en wasm32. Un `main` vacío deja que `--examples` lo compile en el
// smoke test del workspace sin ensuciar la salida.
#[cfg(not(target_arch = "wasm32"))]
fn main() {
eprintln!(
"llimphi · canvas_clear — este example es sólo para wasm32-unknown-unknown \
(usa CanvasSurface). En escritorio el equivalente es `clear_screen`."
);
}
#[cfg(target_arch = "wasm32")]
fn main() {
wasm_bindgen_futures::spawn_local(async {
if let Err(e) = correr().await {
web_sys::console::error_1(&format!("llimphi · canvas_clear: {e}").into());
}
});
}
#[cfg(target_arch = "wasm32")]
const LEAD_GRAY: llimphi_hal::wgpu::Color = llimphi_hal::wgpu::Color {
r: 0.235,
g: 0.239,
b: 0.247,
a: 1.0,
};
#[cfg(target_arch = "wasm32")]
async fn correr() -> Result<(), String> {
use llimphi_hal::{wgpu, Hal, Surface};
use wasm_bindgen::JsCast;
let canvas: web_sys::HtmlCanvasElement = web_sys::window()
.ok_or("sin `window`")?
.document()
.ok_or("sin `document`")?
.get_element_by_id("llimphi")
.ok_or("no hay ningún elemento con id=\"llimphi\"")?
.dyn_into()
.map_err(|_| "el elemento #llimphi no es un <canvas>")?;
// Surface-first, igual que en Android: el adapter se pide contra ESTA
// surface. `for_canvas` es async porque en el main thread del navegador no
// se puede bloquear.
let (hal, mut surface) = Hal::for_canvas(canvas).await.map_err(|e| e.to_string())?;
// El backing store del canvas por `devicePixelRatio`. Sin esto el canvas se
// ve borroso en HiDPI (el navegador escala un buffer chico).
let (w, h) = surface.resize_to_css();
web_sys::console::log_1(&format!("llimphi · canvas_clear — surface {w}×{h} px físicos").into());
let frame = surface.acquire().map_err(|e| e.to_string())?;
let mut encoder = hal
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("canvas_clear-encoder"),
});
{
let _pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("canvas_clear-pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
// La intermedia, no el swapchain: es el mismo contrato que en
// escritorio (vello pinta acá y `present` blittea).
view: frame.view(),
resolve_target: None,
depth_slice: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(LEAD_GRAY),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
}
hal.queue.submit(std::iter::once(encoder.finish()));
surface.present(frame, &hal);
Ok(())
}