wgpu_types/texture/
external_image.rs

1#[allow(unused_imports, reason = "conditionally used, including in docs")]
2use crate::{DownlevelFlags, Origin2d};
3
4/// View of an external texture that can be used to copy to a texture.
5///
6/// Corresponds to [WebGPU `GPUCopyExternalImageSourceInfo`](
7/// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopyexternalimage).
8#[cfg(all(target_family = "wasm", feature = "web"))]
9#[derive(Clone, Debug)]
10pub struct CopyExternalImageSourceInfo {
11    /// The texture to be copied from. The copy source data is captured at the moment
12    /// the copy is issued.
13    pub source: ExternalImageSource,
14    /// The base texel used for copying from the external image. Together
15    /// with the `copy_size` argument to copy functions, defines the
16    /// sub-region of the image to copy.
17    ///
18    /// Relative to the top left of the image.
19    ///
20    /// Must be [`Origin2d::ZERO`] if [`DownlevelFlags::UNRESTRICTED_EXTERNAL_TEXTURE_COPIES`] is not supported.
21    pub origin: Origin2d,
22    /// If the Y coordinate of the image should be flipped. Even if this is
23    /// true, `origin` is still relative to the top left.
24    pub flip_y: bool,
25}
26
27/// Source of an external texture copy.
28///
29/// Corresponds to the [implicit union type on WebGPU `GPUCopyExternalImageSourceInfo.source`](
30/// https://gpuweb.github.io/gpuweb/#dom-gpuimagecopyexternalimage-source).
31#[cfg(all(target_family = "wasm", feature = "web"))]
32#[derive(Clone, Debug)]
33pub enum ExternalImageSource {
34    /// Copy from a previously-decoded image bitmap.
35    ImageBitmap(web_sys::ImageBitmap),
36    /// Copy from an image element.
37    HTMLImageElement(web_sys::HtmlImageElement),
38    /// Copy from a current frame of a video element.
39    HTMLVideoElement(web_sys::HtmlVideoElement),
40    /// Copy from an image.
41    ImageData(web_sys::ImageData),
42    /// Copy from a on-screen canvas.
43    HTMLCanvasElement(web_sys::HtmlCanvasElement),
44    /// Copy from a off-screen canvas.
45    OffscreenCanvas(web_sys::OffscreenCanvas),
46    /// Copy from a video frame.
47    VideoFrame(web_sys::VideoFrame),
48}
49
50#[cfg(all(target_family = "wasm", feature = "web"))]
51impl ExternalImageSource {
52    /// Gets the pixel, not css, width of the source.
53    pub fn width(&self) -> u32 {
54        match self {
55            ExternalImageSource::ImageBitmap(b) => b.width(),
56            ExternalImageSource::HTMLImageElement(i) => i.width(),
57            ExternalImageSource::HTMLVideoElement(v) => v.video_width(),
58            ExternalImageSource::ImageData(i) => i.width(),
59            ExternalImageSource::HTMLCanvasElement(c) => c.width(),
60            ExternalImageSource::OffscreenCanvas(c) => c.width(),
61            ExternalImageSource::VideoFrame(v) => v.display_width(),
62        }
63    }
64
65    /// Gets the pixel, not css, height of the source.
66    pub fn height(&self) -> u32 {
67        match self {
68            ExternalImageSource::ImageBitmap(b) => b.height(),
69            ExternalImageSource::HTMLImageElement(i) => i.height(),
70            ExternalImageSource::HTMLVideoElement(v) => v.video_height(),
71            ExternalImageSource::ImageData(i) => i.height(),
72            ExternalImageSource::HTMLCanvasElement(c) => c.height(),
73            ExternalImageSource::OffscreenCanvas(c) => c.height(),
74            ExternalImageSource::VideoFrame(v) => v.display_height(),
75        }
76    }
77}
78
79#[cfg(all(target_family = "wasm", feature = "web"))]
80impl core::ops::Deref for ExternalImageSource {
81    type Target = js_sys::Object;
82
83    fn deref(&self) -> &Self::Target {
84        match self {
85            Self::ImageBitmap(b) => b,
86            Self::HTMLImageElement(i) => i,
87            Self::HTMLVideoElement(v) => v,
88            Self::ImageData(i) => i,
89            Self::HTMLCanvasElement(c) => c,
90            Self::OffscreenCanvas(c) => c,
91            Self::VideoFrame(v) => v,
92        }
93    }
94}
95
96#[cfg(all(
97    target_family = "wasm",
98    feature = "web",
99    feature = "fragile-send-sync-non-atomic-wasm",
100    not(target_feature = "atomics")
101))]
102unsafe impl Send for ExternalImageSource {}
103#[cfg(all(
104    target_family = "wasm",
105    feature = "web",
106    feature = "fragile-send-sync-non-atomic-wasm",
107    not(target_feature = "atomics")
108))]
109unsafe impl Sync for ExternalImageSource {}
110
111/// Color spaces supported on the web.
112///
113/// Corresponds to [HTML Canvas `PredefinedColorSpace`](
114/// https://html.spec.whatwg.org/multipage/canvas.html#predefinedcolorspace).
115#[derive(Copy, Clone, Debug, PartialEq, Eq)]
116#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
117#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
118pub enum PredefinedColorSpace {
119    /// sRGB color space
120    Srgb,
121    /// Display-P3 color space
122    DisplayP3,
123}
124
125/// View of a texture which can be used to copy to a texture, including
126/// color space and alpha premultiplication information.
127///
128/// Corresponds to [WebGPU `GPUCopyExternalImageDestInfo`](
129/// https://gpuweb.github.io/gpuweb/#dictdef-gpuimagecopytexturetagged).
130#[derive(Copy, Clone, Debug)]
131#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
132pub struct CopyExternalImageDestInfo<T> {
133    /// The texture to be copied to/from.
134    pub texture: T,
135    /// The target mip level of the texture.
136    pub mip_level: u32,
137    /// The base texel of the texture in the selected `mip_level`.
138    pub origin: crate::Origin3d,
139    /// The copy aspect.
140    pub aspect: crate::TextureAspect,
141    /// The color space of this texture.
142    pub color_space: PredefinedColorSpace,
143    /// The premultiplication of this texture
144    pub premultiplied_alpha: bool,
145}
146
147impl<T> CopyExternalImageDestInfo<T> {
148    /// Removes the colorspace information from the type.
149    pub fn to_untagged(self) -> crate::TexelCopyTextureInfo<T> {
150        crate::TexelCopyTextureInfo {
151            texture: self.texture,
152            mip_level: self.mip_level,
153            origin: self.origin,
154            aspect: self.aspect,
155        }
156    }
157}