GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
examples/probe_web.rs (2.2K)
1 //! The renderer probe's scene through the WebGPU renderer, in a browser —
2 //! see `examples/probe/scene.rs`. Built for wasm32 as a cdylib and bound with
3 //! wasm-bindgen; a page calls `probe(canvas, fonts)` and gets the frame back
4 //! as RGBA8 bytes, the canvas's own pixels read back from the GPU.
5 //!
6 //! On a native target this example is empty.
7
8 #[cfg(target_arch = "wasm32")]
9 #[path = "probe/scene.rs"]
10 mod scene;
11
12 #[cfg(target_arch = "wasm32")]
13 mod web {
14 use super::scene::{ProbeApp, H, W};
15 use cce_ui::backend::frame::build_frame;
16 use cce_ui::engine::{AppSender, Application, LogicalSize};
17 use cce_ui::web::WebRenderer;
18 use wasm_bindgen::prelude::*;
19
20 /// Render the probe scene into `canvas` with the fonts in `fonts` (each a
21 /// font file's bytes) and return the frame as RGBA8.
22 #[wasm_bindgen]
23 pub async fn probe(canvas: web_sys::HtmlCanvasElement, fonts: js_sys::Array) -> Result<js_sys::Uint8Array, JsValue> {
24 std::panic::set_hook(Box::new(|info| web_sys::console::error_1(&info.to_string().into())));
25
26 let mut db = cce_ui::cosmic_text::fontdb::Database::new();
27 for font in fonts.iter() {
28 db.load_font_data(js_sys::Uint8Array::new(&font).to_vec());
29 }
30 let mut fs = cce_ui::cosmic_text::FontSystem::new_with_locale_and_db("en-US".into(), db);
31 let mut swash = cce_ui::cosmic_text::SwashCache::new();
32
33 let mut renderer = WebRenderer::new(canvas).await?;
34 renderer.resize(W, H);
35 cce_ui::scale::set_scale_factor(1.0);
36 let (tx, _rx) = std::sync::mpsc::channel();
37 let mut app = ProbeApp::create(AppSender::from(tx));
38
39 let mut owed = true;
40 let mut items = Vec::new();
41 let size = LogicalSize::new(W as f32, H as f32);
42 let frame = build_frame(&mut app, &mut fs, size, 1.0, &mut owed, &mut items);
43 if frame.dl_text {
44 let spans = frame.text_spans(&items);
45 renderer.prepare_text(&mut fs, &mut swash, &spans);
46 }
47 renderer.capture_next_frame();
48 renderer.draw_frame_2d(frame.frame2d())?;
49 let capture = renderer.take_capture().await?.ok_or("no frame was captured")?;
50 Ok(js_sys::Uint8Array::from(&capture.rgba[..]))
51 }
52 }