diff --git a/CHANGELOG.md b/CHANGELOG.md index d427e7579c..613aca3bb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,12 @@ Add the `"wgsl"` feature, to enable WGSL shaders in `wgpu-core` and `wgpu`. Enab - Bother to free the `hal::Api::CommandBuffer` when a `wgpu_core::command::CommandEncoder` is dropped. By @jimblandy in [#3069](https://github.com/gfx-rs/wgpu/pull/3069). +#### WebGPU +- Use `log` instead of `println` in hello example by @JolifantoBambla in [#2858](https://github.com/gfx-rs/wgpu/pull/2858) + +### Examples +- Log adapter info in hello example on wasm target by @JolifantoBambla in [#2858](https://github.com/gfx-rs/wgpu/pull/2858) + ### Testing/Internal - Update the `minimum supported rust version` to 1.62 @@ -150,6 +156,9 @@ both `raw_window_handle::HasRawWindowHandle` and `raw_window_handle::HasRawDispl - Report vendor id for Mesa and Apple GPUs. By @i509VCB [#3036](https://github.com/gfx-rs/wgpu/pull/3036) - Report Apple M2 gpu as integrated. By @i509VCB [#3036](https://github.com/gfx-rs/wgpu/pull/3036) +#### WebGPU +- When called in a web worker, `Context::init()` now uses `web_sys::WorkerGlobalContext` to create a `wgpu::Instance` instead of trying to access the unavailable `web_sys::Window` by @JolifantoBambla in [#2858](https://github.com/gfx-rs/wgpu/pull/2858) + ### Changes #### General @@ -301,7 +310,6 @@ Added items to the public API - Update present_mode docs as most of them don't automatically fall back to Fifo anymore. by @Elabajaba in [#2855](https://github.com/gfx-rs/wgpu/pull/2855) #### Hal - - Document safety requirements for `Adapter::from_external` in gles hal by @i509VCB in [#2863](https://github.com/gfx-rs/wgpu/pull/2863) - Make `AdapterContext` a publicly accessible type in the gles hal by @i509VCB in [#2870](https://github.com/gfx-rs/wgpu/pull/2870) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 1d9909c434..2017ada192 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -286,7 +286,9 @@ web-sys = { version = "0.3.60", features = [ "OffscreenCanvas", "ImageBitmap", "ImageBitmapRenderingContext", - "Window" + "Window", + "WorkerGlobalScope", + "WorkerNavigator" ] } wasm-bindgen = "0.2.83" js-sys = "0.3.60" diff --git a/wgpu/examples/hello/main.rs b/wgpu/examples/hello/main.rs index 4f2c6dd914..f74c5d1f8e 100644 --- a/wgpu/examples/hello/main.rs +++ b/wgpu/examples/hello/main.rs @@ -5,9 +5,9 @@ async fn run() { let instance = wgpu::Instance::new(wgpu::Backends::all()); #[cfg(not(target_arch = "wasm32"))] { - println!("Available adapters:"); + log::info!("Available adapters:"); for a in instance.enumerate_adapters(wgpu::Backends::all()) { - println!(" {:?}", a.get_info()) + log::info!(" {:?}", a.get_info()) } } instance @@ -16,8 +16,7 @@ async fn run() { .unwrap() }; - #[cfg(not(target_arch = "wasm32"))] - println!("Selected adapter: {:?}", adapter.get_info()) + log::info!("Selected adapter: {:?}", adapter.get_info()) } fn main() { diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index f92b06e7a6..7544e57b9f 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1007,6 +1007,21 @@ impl Context { } } +// Represents the global object in the JavaScript context. +// It can be cast to from `web_sys::global` and exposes two getters `window` and `worker` of which only one is defined depending on the caller's context. +// When called from the UI thread only `window` is defined whereas `worker` is only defined within a web worker context. +// See: https://github.com/rustwasm/gloo/blob/2c9e776701ecb90c53e62dec1abd19c2b70e47c7/crates/timers/src/callback.rs#L8-L40 +#[wasm_bindgen] +extern "C" { + type Global; + + #[wasm_bindgen(method, getter, js_name = Window)] + fn window(this: &Global) -> JsValue; + + #[wasm_bindgen(method, getter, js_name = WorkerGlobalScope)] + fn worker(this: &Global) -> JsValue; +} + // The web doesn't provide any way to identify specific queue // submissions. But Clippy gets concerned if we pass around `()` as if // it were meaningful. @@ -1051,7 +1066,20 @@ impl crate::Context for Context { MakeSendFuture Option>; fn init(_backends: wgt::Backends) -> Self { - Context(web_sys::window().unwrap().navigator().gpu()) + let global: Global = js_sys::global().unchecked_into(); + let gpu = if !global.window().is_undefined() { + global.unchecked_into::().navigator().gpu() + } else if !global.worker().is_undefined() { + global + .unchecked_into::() + .navigator() + .gpu() + } else { + panic!( + "Accessing the GPU is only supported on the main thread or from a dedicated worker" + ); + }; + Context(gpu) } fn instance_create_surface(