Skip to content

Optional web-specific deps for wasm32 #7565

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ jobs:
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} --tests --features glsl,spirv
cargo doc --target ${{ matrix.target }} ${{ matrix.extra-flags }} --no-deps --features glsl,spirv

# check with no features
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} --no-default-features
# check with only the web feature
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} --no-default-features --features=web

# all features
cargo clippy --target ${{ matrix.target }} ${{ matrix.extra-flags }} --tests --all-features
Expand Down Expand Up @@ -481,7 +481,7 @@ jobs:
- name: Execute tests
run: |
cd wgpu
wasm-pack test --headless --chrome --no-default-features --features wgsl,webgl --workspace
wasm-pack test --headless --chrome --no-default-features --features wgsl,webgl,web --workspace

gpu-test:
# runtime is normally 5-15 minutes
Expand Down
4 changes: 4 additions & 0 deletions examples/standalone/custom_backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ edition = "2021"
rust-version = "1.84"
publish = false

[features]
default = ["web"]
web = ["wgpu/web"]

[dependencies]
wgpu = { version = "25.0.0", features = [
"custom",
Expand Down
2 changes: 1 addition & 1 deletion examples/standalone/custom_backend/src/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ impl QueueInterface for CustomQueue {
unimplemented!()
}

#[cfg(target_arch = "wasm32")]
#[cfg(all(target_arch = "wasm32", feature = "web"))]
fn copy_external_image_to_texture(
&self,
_source: &wgpu::CopyExternalImageSourceInfo,
Expand Down
48 changes: 48 additions & 0 deletions tests/tests/wgpu-dependency/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,54 @@ fn wasm32_with_webgl_depends_on_glow() {
});
}

#[test]
fn wasm32_with_only_custom_backend_does_not_depend_on_web_specifics() {
check_feature_dependency(Requirement {
human_readable_name: "wasm32 with only the `custom` backend does not depend on web-specific bindings [`wasm-bindgen`, `js-sys`, `web-sys`]",
target: "wasm32-unknown-unknown",
packages: &["wgpu"],
features: &["custom"],
default_features: false,
search_terms: &[Search::Negative("wasm-bindgen"), Search::Negative("js-sys"), Search::Negative("web-sys")],
});
}

#[test]
fn wasm32_with_webgpu_backend_does_depend_on_web_specifics() {
check_feature_dependency(Requirement {
human_readable_name: "wasm32 with the `webgpu` backend depends on web-specific bindings [`wasm-bindgen`, `js-sys`, `web-sys`]",
target: "wasm32-unknown-unknown",
packages: &["wgpu"],
features: &["webgpu"],
default_features: false,
search_terms: &[Search::Positive("wasm-bindgen"), Search::Positive("js-sys"), Search::Positive("web-sys")],
});
}

#[test]
fn wasm32_with_webgl_backend_does_depend_on_web_specifics() {
check_feature_dependency(Requirement {
human_readable_name: "wasm32 with the `webgl` backend depends on web-specific bindings [`wasm-bindgen`, `js-sys`, `web-sys`]",
target: "wasm32-unknown-unknown",
packages: &["wgpu"],
features: &["webgl"],
default_features: false,
search_terms: &[Search::Positive("wasm-bindgen"), Search::Positive("js-sys"), Search::Positive("web-sys")],
});
}

#[test]
fn windows_with_webgpu_webgl_backend_does_not_depend_on_web_specifics() {
check_feature_dependency(Requirement {
human_readable_name: "windows with the `webgpu` and `webgl` backends enabled does not depend on web-specific bindings [`wasm-bindgen`, `js-sys`, `web-sys`]",
target: "x86_64-pc-windows-msvc",
packages: &["wgpu"],
features: &["webgpu", "webgl"],
default_features: false,
search_terms: &[Search::Negative("wasm-bindgen"), Search::Negative("js-sys"), Search::Negative("web-sys")],
});
}

#[test]
fn windows_with_webgl_does_not_depend_on_glow() {
check_feature_dependency(Requirement {
Expand Down
2 changes: 1 addition & 1 deletion wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ gles = [
]

## WebGL backend, only available on Emscripten
webgl = ["wgpu-core-deps-wasm/webgl"]
webgl = ["wgpu-core-deps-wasm/webgl", "wgpu-types/web"]
## OpenGL backend, on macOS only
angle = ["wgpu-core-deps-apple/angle"]
## Vulkan portability backend, only available on macOS
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ gles = [
"dep:profiling",
"dep:wasm-bindgen",
"dep:web-sys",
"wgpu-types/web",
"windows/Win32_Graphics_OpenGL",
"windows/Win32_Graphics_Gdi",
"windows/Win32_System_LibraryLoader",
Expand Down
8 changes: 5 additions & 3 deletions wgpu-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,16 @@ alloc_instead_of_core = "warn"

[features]
default = ["std"]
std = ["js-sys/std", "web-sys/std", "thiserror/std"]
std = ["js-sys?/std", "web-sys?/std", "thiserror/std"]
strict_asserts = []
fragile-send-sync-non-atomic-wasm = []
serde = ["dep:serde", "bitflags/serde"]
# Enables some internal instrumentation for debugging purposes.
counters = []
# Enables variants of `Trace` other than `Trace::Off`
trace = ["std"]
# Enable web-specific dependencies for wasm.
web = ["dep:js-sys", "dep:web-sys"]

[dependencies]
bitflags = { workspace = true, features = ["serde"] }
Expand All @@ -57,8 +59,8 @@ serde = { workspace = true, default-features = false, features = [
], optional = true }

[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = { workspace = true, default-features = false }
web-sys = { workspace = true, default-features = false, features = [
js-sys = { workspace = true, optional = true, default-features = false }
web-sys = { workspace = true, optional = true, default-features = false, features = [
"ImageBitmap",
"ImageData",
"HtmlImageElement",
Expand Down
12 changes: 7 additions & 5 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6838,7 +6838,7 @@ pub type ImageCopyTexture<T> = TexelCopyTextureInfo<T>;
///
/// Corresponds to [WebGPU `GPUCopyExternalImageSourceInfo`](
/// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopyexternalimage).
#[cfg(target_arch = "wasm32")]
#[cfg(all(target_arch = "wasm32", feature = "web"))]
#[derive(Clone, Debug)]
pub struct CopyExternalImageSourceInfo {
/// The texture to be copied from. The copy source data is captured at the moment
Expand All @@ -6862,14 +6862,14 @@ pub struct CopyExternalImageSourceInfo {
since = "24.0.0",
note = "This has been renamed to `CopyExternalImageSourceInfo`, and will be removed in 25.0.0."
)]
#[cfg(target_arch = "wasm32")]
#[cfg(all(target_arch = "wasm32", feature = "web"))]
pub type ImageCopyExternalImage = CopyExternalImageSourceInfo;

/// Source of an external texture copy.
///
/// Corresponds to the [implicit union type on WebGPU `GPUCopyExternalImageSourceInfo.source`](
/// https://gpuweb.github.io/gpuweb/#dom-gpuimagecopyexternalimage-source).
#[cfg(target_arch = "wasm32")]
#[cfg(all(target_arch = "wasm32", feature = "web"))]
#[derive(Clone, Debug)]
pub enum ExternalImageSource {
/// Copy from a previously-decoded image bitmap.
Expand All @@ -6891,7 +6891,7 @@ pub enum ExternalImageSource {
VideoFrame(web_sys::VideoFrame),
}

#[cfg(target_arch = "wasm32")]
#[cfg(all(target_arch = "wasm32", feature = "web"))]
impl ExternalImageSource {
/// Gets the pixel, not css, width of the source.
pub fn width(&self) -> u32 {
Expand Down Expand Up @@ -6922,7 +6922,7 @@ impl ExternalImageSource {
}
}

#[cfg(target_arch = "wasm32")]
#[cfg(all(target_arch = "wasm32", feature = "web"))]
impl core::ops::Deref for ExternalImageSource {
type Target = js_sys::Object;

Expand All @@ -6942,12 +6942,14 @@ impl core::ops::Deref for ExternalImageSource {

#[cfg(all(
target_arch = "wasm32",
feature = "web",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
unsafe impl Send for ExternalImageSource {}
#[cfg(all(
target_arch = "wasm32",
feature = "web",
feature = "fragile-send-sync-non-atomic-wasm",
not(target_feature = "atomics")
))]
Expand Down
16 changes: 12 additions & 4 deletions wgpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ gles = ["wgpu-core?/gles"]

## Enables the WebGPU backend on WebAssembly.
webgpu = [
"web",
"naga?/wgsl-out",
"dep:wasm-bindgen-futures",
"web-sys/Document",
Expand All @@ -68,7 +69,7 @@ angle = ["wgpu-core?/angle"]
vulkan-portability = ["wgpu-core?/vulkan-portability"]

## Enables the GLES backend on WebAssembly only.
webgl = ["wgpu-core/webgl", "dep:wgpu-hal", "dep:smallvec"]
webgl = ["web", "wgpu-core/webgl", "dep:wgpu-hal", "dep:smallvec"]

## Enables the noop backend for testing.
##
Expand Down Expand Up @@ -148,6 +149,13 @@ fragile-send-sync-non-atomic-wasm = [
"wgpu-types/fragile-send-sync-non-atomic-wasm",
]

## Use web-specific libraries on WASM
##
## Those libraties (wasm-bindgen, web-sys, js-sys) can only be used when there is a JavaScript
## context around the WASM VM, e.g., when the WASM binary is used in a browser.
web = ["dep:wasm-bindgen", "dep:js-sys", "dep:web-sys", "wgpu-types/web"]


#########################
# Standard Dependencies #
#########################
Expand Down Expand Up @@ -192,9 +200,9 @@ smallvec.workspace = true
###############
[target.'cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))'.dependencies]
# Needed for all backends
js-sys = { workspace = true, features = ["default"] }
wasm-bindgen.workspace = true
web-sys = { workspace = true, features = [
js-sys = { workspace = true, optional = true, features = ["default"] }
wasm-bindgen = { workspace = true, optional = true }
web-sys = { workspace = true, optional = true, features = [
"HtmlCanvasElement",
"OffscreenCanvas",
] }
Expand Down
1 change: 1 addition & 0 deletions wgpu/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ fn main() {
cfg_aliases::cfg_aliases! {
native: { not(target_arch = "wasm32") },
Emscripten: { all(target_arch = "wasm32", target_os = "emscripten") },
web: { all(target_arch = "wasm32", not(Emscripten), feature = "web") },

send_sync: { any(
native,
Expand Down
4 changes: 2 additions & 2 deletions wgpu/src/api/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ impl Instance {
surface
}?,

#[cfg(any(webgpu, webgl))]
#[cfg(web)]
SurfaceTarget::Canvas(canvas) => {
handle_source = None;

Expand All @@ -322,7 +322,7 @@ impl Instance {
}?
}

#[cfg(any(webgpu, webgl))]
#[cfg(web)]
SurfaceTarget::OffscreenCanvas(canvas) => {
handle_source = None;

Expand Down
2 changes: 1 addition & 1 deletion wgpu/src/api/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ impl Queue {
}

/// Schedule a copy of data from `image` into `texture`.
#[cfg(any(webgpu, webgl))]
#[cfg(web)]
pub fn copy_external_image_to_texture(
&self,
source: &wgt::CopyExternalImageSourceInfo,
Expand Down
4 changes: 2 additions & 2 deletions wgpu/src/api/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ pub enum SurfaceTarget<'window> {
///
/// - On WebGL2: surface creation will return an error if the browser does not support WebGL2,
/// or declines to provide GPU access (such as due to a resource shortage).
#[cfg(any(webgpu, webgl))]
#[cfg(web)]
Canvas(web_sys::HtmlCanvasElement),

/// Surface from a `web_sys::OffscreenCanvas`.
Expand All @@ -255,7 +255,7 @@ pub enum SurfaceTarget<'window> {
///
/// - On WebGL2: surface creation will return an error if the browser does not support WebGL2,
/// or declines to provide GPU access (such as due to a resource shortage).
#[cfg(any(webgpu, webgl))]
#[cfg(web)]
OffscreenCanvas(web_sys::OffscreenCanvas),
}

Expand Down
2 changes: 1 addition & 1 deletion wgpu/src/backend/wgpu_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1845,7 +1845,7 @@ impl dispatch::QueueInterface for CoreQueue {

// This method needs to exist if either webgpu or webgl is enabled,
// but we only actually have an implementation if webgl is enabled.
#[cfg(any(webgpu, webgl))]
#[cfg(web)]
#[cfg_attr(not(webgl), expect(unused_variables))]
fn copy_external_image_to_texture(
&self,
Expand Down
2 changes: 1 addition & 1 deletion wgpu/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ pub trait QueueInterface: CommonTraits {
data_layout: crate::TexelCopyBufferLayout,
size: crate::Extent3d,
);
#[cfg(any(webgpu, webgl))]
#[cfg(web)]
fn copy_external_image_to_texture(
&self,
source: &crate::CopyExternalImageSourceInfo,
Expand Down
6 changes: 3 additions & 3 deletions wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ pub use wgt::{
pub use wgt::{ImageCopyBuffer, ImageCopyTexture, ImageCopyTextureTagged, ImageDataLayout};
// wasm-only types, we try to keep as many types non-platform
// specific, but these need to depend on web-sys.
#[cfg(any(webgpu, webgl))]
#[cfg(web)]
#[expect(deprecated)]
pub use wgt::ImageCopyExternalImage;
#[cfg(any(webgpu, webgl))]
#[cfg(web)]
pub use wgt::{CopyExternalImageSourceInfo, ExternalImageSource};

/// Re-export of our `naga` dependency.
Expand All @@ -119,7 +119,7 @@ pub use raw_window_handle as rwh;

/// Re-export of our `web-sys` dependency.
///
#[cfg(any(webgl, webgpu))]
#[cfg(web)]
pub use web_sys;

#[doc(hidden)]
Expand Down
Loading