From 8f49f37221eeb8e2c1142016a19d117def5ff7a4 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sun, 17 Dec 2023 23:58:31 +0100 Subject: [PATCH 1/2] WebGL: add support for more `RawWindowHandle` variants --- wgpu-hal/src/gles/web.rs | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/wgpu-hal/src/gles/web.rs b/wgpu-hal/src/gles/web.rs index 49236bb94c..cdbe4543d1 100644 --- a/wgpu-hal/src/gles/web.rs +++ b/wgpu-hal/src/gles/web.rs @@ -1,6 +1,6 @@ use glow::HasContext; use parking_lot::{Mutex, RwLock}; -use wasm_bindgen::JsCast; +use wasm_bindgen::{JsCast, JsValue}; use super::TextureFormatDesc; @@ -55,7 +55,7 @@ impl Instance { fn create_surface_from_context( &self, canvas: Canvas, - context_result: Result, wasm_bindgen::JsValue>, + context_result: Result, JsValue>, ) -> Result { let context_object: js_sys::Object = match context_result { Ok(Some(context)) => context, @@ -147,22 +147,33 @@ impl crate::Instance for Instance { _display_handle: raw_window_handle::RawDisplayHandle, window_handle: raw_window_handle::RawWindowHandle, ) -> Result { - if let raw_window_handle::RawWindowHandle::Web(handle) = window_handle { - let canvas: web_sys::HtmlCanvasElement = web_sys::window() + let canvas: web_sys::HtmlCanvasElement = match window_handle { + raw_window_handle::RawWindowHandle::Web(handle) => web_sys::window() .and_then(|win| win.document()) .expect("Cannot get document") .query_selector(&format!("canvas[data-raw-handle=\"{}\"]", handle.id)) .expect("Cannot query for canvas") .expect("Canvas is not found") .dyn_into() - .expect("Failed to downcast to canvas type"); + .expect("Failed to downcast to canvas type"), + raw_window_handle::RawWindowHandle::WebCanvas(handle) => { + let value: &JsValue = unsafe { handle.obj.cast().as_ref() }; + value.clone().unchecked_into() + } + raw_window_handle::RawWindowHandle::WebOffscreenCanvas(handle) => { + let value: &JsValue = unsafe { handle.obj.cast().as_ref() }; + let canvas: web_sys::OffscreenCanvas = value.clone().unchecked_into(); - self.create_surface_from_canvas(canvas) - } else { - Err(crate::InstanceError::new(format!( - "window handle {window_handle:?} is not a web handle" - ))) - } + return self.create_surface_from_offscreen_canvas(canvas); + } + _ => { + return Err(crate::InstanceError::new(format!( + "window handle {window_handle:?} is not a web handle" + ))) + } + }; + + self.create_surface_from_canvas(canvas) } unsafe fn destroy_surface(&self, surface: Surface) { From c4c1a8256b343c347d97ccbb6b6ecbccad0e3df8 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Mon, 18 Dec 2023 01:15:05 +0100 Subject: [PATCH 2/2] WebGPU: add support for more `RawWindowHandle` variants --- wgpu/src/backend/web.rs | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 82b31c6f6a..04069f224b 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1098,20 +1098,32 @@ impl crate::context::Context for Context { _display_handle: raw_window_handle::RawDisplayHandle, window_handle: raw_window_handle::RawWindowHandle, ) -> Result<(Self::SurfaceId, Self::SurfaceData), crate::CreateSurfaceError> { - let canvas_attribute = match window_handle { - raw_window_handle::RawWindowHandle::Web(web_handle) => web_handle.id, + let canvas_element: web_sys::HtmlCanvasElement = match window_handle { + raw_window_handle::RawWindowHandle::Web(handle) => { + let canvas_node: wasm_bindgen::JsValue = web_sys::window() + .and_then(|win| win.document()) + .and_then(|doc| { + doc.query_selector_all(&format!("[data-raw-handle=\"{}\"]", handle.id)) + .ok() + }) + .and_then(|nodes| nodes.get(0)) + .expect("expected to find single canvas") + .into(); + canvas_node.into() + } + raw_window_handle::RawWindowHandle::WebCanvas(handle) => { + let value: &JsValue = unsafe { handle.obj.cast().as_ref() }; + value.clone().unchecked_into() + } + raw_window_handle::RawWindowHandle::WebOffscreenCanvas(handle) => { + let value: &JsValue = unsafe { handle.obj.cast().as_ref() }; + let canvas: web_sys::OffscreenCanvas = value.clone().unchecked_into(); + + return self.instance_create_surface_from_offscreen_canvas(canvas); + } _ => panic!("expected valid handle for canvas"), }; - let canvas_node: wasm_bindgen::JsValue = web_sys::window() - .and_then(|win| win.document()) - .and_then(|doc| { - doc.query_selector_all(&format!("[data-raw-handle=\"{canvas_attribute}\"]")) - .ok() - }) - .and_then(|nodes| nodes.get(0)) - .expect("expected to find single canvas") - .into(); - let canvas_element: web_sys::HtmlCanvasElement = canvas_node.into(); + self.instance_create_surface_from_canvas(canvas_element) }