diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-04-19 07:42:52 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-04-19 07:42:52 +0200 |
| commit | 729d10592f4e802f91c555c309ff3ba4b119f843 (patch) | |
| tree | a547a6d1ba90ca9cc03f406e0160df0af987644d /rust/wasm/src | |
| parent | 9da365bc01fc54f6d3f0ca9c3212eee4c0cee7cd (diff) | |
| download | opencut-729d10592f4e802f91c555c309ff3ba4b119f843.tar.gz | |
fix: WebGL frame rendering and opencut-wasm 0.2.8
Diffstat (limited to 'rust/wasm/src')
| -rw-r--r-- | rust/wasm/src/compositor.rs | 50 | ||||
| -rw-r--r-- | rust/wasm/src/gpu.rs | 20 |
2 files changed, 53 insertions, 17 deletions
diff --git a/rust/wasm/src/compositor.rs b/rust/wasm/src/compositor.rs index 55756a21..126c7468 100644 --- a/rust/wasm/src/compositor.rs +++ b/rust/wasm/src/compositor.rs @@ -131,22 +131,41 @@ pub fn render_frame(options: JsValue) -> Result<(), JsValue> { )); }; - let surface = gpu_runtime - .context - .instance() - .create_surface(wgpu::SurfaceTarget::Canvas(runtime.canvas.clone())) - .map_err(|error| JsValue::from_str(&error.to_string()))?; + if gpu_runtime.context.supports_surface_rendering() { + let surface = gpu_runtime + .context + .instance() + .create_surface(wgpu::SurfaceTarget::Canvas(runtime.canvas.clone())) + .map_err(|error| JsValue::from_str(&error.to_string()))?; - runtime - .compositor - .render_frame( - &gpu_runtime.context, - RenderFrameOptions { - frame: &frame, - surface: &surface, - }, - ) - .map_err(|error| JsValue::from_str(&error.to_string())) + runtime + .compositor + .render_frame( + &gpu_runtime.context, + RenderFrameOptions { + frame: &frame, + surface: &surface, + }, + ) + .map_err(|error| JsValue::from_str(&error.to_string())) + } else { + // WebGL cannot surface-render to an arbitrary canvas element. + // Composite to a texture, then blit to the canvas via the 2D context. + let texture = runtime + .compositor + .render_frame_to_texture(&gpu_runtime.context, &frame) + .map_err(|error| JsValue::from_str(&error.to_string()))?; + + gpu_runtime + .context + .render_texture_via_gl_canvas( + &texture, + &runtime.canvas, + frame.width, + frame.height, + ) + .map_err(|error| JsValue::from_str(&error.to_string())) + } }) }) } @@ -171,4 +190,3 @@ fn parse_upload_texture_options(value: JsValue) -> Result<UploadTextureOptions, height: read_u32_property(&object, "height")?, }) } - diff --git a/rust/wasm/src/gpu.rs b/rust/wasm/src/gpu.rs index 4e65978c..52c051f0 100644 --- a/rust/wasm/src/gpu.rs +++ b/rust/wasm/src/gpu.rs @@ -19,9 +19,27 @@ thread_local! { static GPU_RUNTIME: RefCell<Option<GpuRuntime>> = const { RefCell::new(None) }; } +fn set_panic_hook() { + static SET_HOOK: std::sync::Once = std::sync::Once::new(); + SET_HOOK.call_once(|| { + std::panic::set_hook(Box::new(|info| { + // Store the full panic message in window.__wasmPanic so the JS catch block + // can surface it instead of the opaque "Unreachable" WASM trap message. + if let Some(window) = web_sys::window() { + let _ = Reflect::set( + &window, + &JsValue::from_str("__wasmPanic"), + &JsValue::from_str(&info.to_string()), + ); + } + console_error_panic_hook::hook(info); + })); + }); +} + #[wasm_bindgen(js_name = initializeGpu)] pub async fn initialize_gpu() -> Result<(), JsValue> { - console_error_panic_hook::set_once(); + set_panic_hook(); if GPU_RUNTIME.with(|runtime| runtime.borrow().is_some()) { return Ok(()); |
