caelunshun / dume

A 2D rendering canvas for wgpu
8 stars 1 forks source link

Run in WebAssembly #1

Closed Zentendo closed 3 years ago

Zentendo commented 3 years ago

@caelunshun Hi, I'm very interested in this library for a nice canvas-like 2D rendering API for wgpu, and would like to use it for the web target (WebGL 2 / WebGPU) for wgpu in WASM.

What currently needs to be done to run this library in WebAssembly?

The example runs fine with cargo run --example testbed on the experimental branch.

However, I'm getting these errors when running the compiled WASM in the browser:

Uncaught (in promise) RuntimeError: unreachable
    at __rust_start_panic (:4000/testbed_bg.wasm)
    at rust_panic (:4000/testbed_bg.wasm)
    at std::panicking::rust_panic_with_hook::ha223473efd20893e (:4000/testbed_bg.wasm)
    at std::panicking::begin_panic_handler::{{closure}}::h0eb6605d81329fe7 (:4000/testbed_bg.wasm)
    at std::sys_common::backtrace::__rust_end_short_backtrace::h8c7d312a147e1df9 (:4000/testbed_bg.wasm)
    at rust_begin_unwind (:4000/testbed_bg.wasm)
    at core::panicking::panic_fmt::hca0bee0b11468063 (:4000/testbed_bg.wasm)
    at core::panicking::panic::hb05521048dcb55f3 (:4000/testbed_bg.wasm)
    at testbed::main::h1175dc00f190c0ea (:4000/testbed_bg.wasm)
    at std::sys_common::backtrace::__rust_begin_short_backtrace::h848964148b218d05 (:4000/testbed_bg.wasm)

I've tried changing the Cargo.toml to this:

[package]
name = "dume"
version = "0.1.0"
authors = ["caelunshun <caelunshun@gmail.com>"]
edition = "2021"

[dependencies]
ahash = "0.7"
anyhow = "1"
bytemuck = { version = "1", features = [ "derive" ] }
flume = "0.10"
glam = { version = "0.17", features = [ "bytemuck" ] }
guillotiere = "0.6"
log = "0.4"
lru = "0.7"
lyon = "0.17"
once_cell = "1"
palette = "0.6"
parking_lot = "0.11"
rectangle-pack = "0.4"
serde = { version = "1", features = [ "derive" ] }
slotmap = "1"
smallvec = "1"
smartstring = { version = "0.2", features = [ "serde" ] }
swash = "0.1"
thiserror = "1"
unicode-bidi = "0.3"
wgpu = { version = "0.11", features = ["webgl"] }
web-sys = "0.3.55"
winit = { version = "0.25.0", features = ["web-sys"] }

[dev-dependencies]
image = { version = "0.23", default-features = false, features = [ "jpeg" ] }
pollster = "0.2"
simple_logger = "1"

[profile.dev]
opt-level = 3

And then running:

cargo build --target wasm32-unknown-unknown 
wasm-bindgen --out-dir static --target web --no-typescript target/wasm32-unknown-unknown/debug/examples/testbed.wasm
basic-http-server ./static/
caelunshun commented 3 years ago

Hi!

The first issue that comes to mind is how the example code blocks on wgpu futures: it uses the pollster crate, which doesn't seem to be compatible with WASM. The wgpu examples use wasm-bindgen-futures instead when running on WASM (code).

I'll implement and test this change in a few hours when I have time.

Another problem on WASM will be loading images from disk—right now the example code expects them to be stored in the assets directory. In the browser, though, we can't access files, so they have to be loaded from a URL.

caelunshun commented 3 years ago

It took a bit longer than expected, but I got the experimental branch working on WASM now.

Besides the aforementioned problems, it turns out WebGL doesn't support storage buffers, which I was using to pass colors to the path shader. So I changed the shader to load color data from a 1D texture emulating a storage buffer.

Let me know how it works!