From b4db97f97bce2a74882addc8aa103f22cf17ec25 Mon Sep 17 00:00:00 2001 From: Valaphee The Meerkat <32491319+valaphee@users.noreply.github.com> Date: Tue, 20 Aug 2024 18:54:24 +0200 Subject: [PATCH] Add HTMLImageElement/ImageData as external source for copying images (#5668) * Add `HTMLImageElement` as external source for copying images * Typo --- CHANGELOG.md | 1 + wgpu-hal/src/gles/queue.rs | 56 ++++++++++++++++++++++++++++++++++++++ wgpu-types/Cargo.toml | 1 + wgpu-types/src/lib.rs | 10 +++++++ 4 files changed, 68 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5caf8235b..21ec6bde0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -230,6 +230,7 @@ By @teoxoy in [#5901](https://github.com/gfx-rs/wgpu/pull/5901) - `MemoryHints::MemoryUsage` favors memory usage over performance. This hint is typically useful for smaller applications or UI libraries. - `MemoryHints::Manual` allows the user to specify parameters for the underlying GPU memory allocator. These parameters are subject to change. - These hints may be ignored by some backends. Currently only the Vulkan and D3D12 backends take them into account. +- Add `HTMLImageElement` and `ImageData` as external source for copying images. By @Valaphee in [#5668](https://github.com/gfx-rs/wgpu/pull/5668) #### Naga diff --git a/wgpu-hal/src/gles/queue.rs b/wgpu-hal/src/gles/queue.rs index 398e37ffe..3752b0869 100644 --- a/wgpu-hal/src/gles/queue.rs +++ b/wgpu-hal/src/gles/queue.rs @@ -471,6 +471,21 @@ impl super::Queue { b, ); }, + wgt::ExternalImageSource::HTMLImageElement(ref i) => unsafe { + gl.tex_sub_image_3d_with_html_image_element( + dst_target, + copy.dst_base.mip_level as i32, + copy.dst_base.origin.x as i32, + copy.dst_base.origin.y as i32, + z_offset as i32, + copy.size.width as i32, + copy.size.height as i32, + copy.size.depth as i32, + format_desc.external, + format_desc.data_type, + i, + ); + }, wgt::ExternalImageSource::HTMLVideoElement(ref v) => unsafe { gl.tex_sub_image_3d_with_html_video_element( dst_target, @@ -486,6 +501,21 @@ impl super::Queue { v, ); }, + wgt::ExternalImageSource::ImageData(ref i) => unsafe { + gl.tex_sub_image_3d_with_image_data( + dst_target, + copy.dst_base.mip_level as i32, + copy.dst_base.origin.x as i32, + copy.dst_base.origin.y as i32, + z_offset as i32, + copy.size.width as i32, + copy.size.height as i32, + copy.size.depth as i32, + format_desc.external, + format_desc.data_type, + i, + ); + }, wgt::ExternalImageSource::HTMLCanvasElement(ref c) => unsafe { gl.tex_sub_image_3d_with_html_canvas_element( dst_target, @@ -520,6 +550,19 @@ impl super::Queue { b, ); }, + wgt::ExternalImageSource::HTMLImageElement(ref i) => unsafe { + gl.tex_sub_image_2d_with_html_image_and_width_and_height( + dst_target, + copy.dst_base.mip_level as i32, + copy.dst_base.origin.x as i32, + copy.dst_base.origin.y as i32, + copy.size.width as i32, + copy.size.height as i32, + format_desc.external, + format_desc.data_type, + i, + ) + }, wgt::ExternalImageSource::HTMLVideoElement(ref v) => unsafe { gl.tex_sub_image_2d_with_html_video_and_width_and_height( dst_target, @@ -533,6 +576,19 @@ impl super::Queue { v, ) }, + wgt::ExternalImageSource::ImageData(ref i) => unsafe { + gl.tex_sub_image_2d_with_image_data_and_width_and_height( + dst_target, + copy.dst_base.mip_level as i32, + copy.dst_base.origin.x as i32, + copy.dst_base.origin.y as i32, + copy.size.width as i32, + copy.size.height as i32, + format_desc.external, + format_desc.data_type, + i, + ); + }, wgt::ExternalImageSource::HTMLCanvasElement(ref c) => unsafe { gl.tex_sub_image_2d_with_html_canvas_and_width_and_height( dst_target, diff --git a/wgpu-types/Cargo.toml b/wgpu-types/Cargo.toml index 387e41a47..e79b30134 100644 --- a/wgpu-types/Cargo.toml +++ b/wgpu-types/Cargo.toml @@ -42,6 +42,7 @@ serde = { workspace = true, features = ["derive"], optional = true } js-sys.workspace = true web-sys = { workspace = true, features = [ "ImageBitmap", + "ImageData", "HtmlVideoElement", "HtmlCanvasElement", "OffscreenCanvas", diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 9bcb00342..4f15e68a1 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -6843,8 +6843,12 @@ pub struct ImageCopyExternalImage { pub enum ExternalImageSource { /// Copy from a previously-decoded image bitmap. ImageBitmap(web_sys::ImageBitmap), + /// Copy from an image element. + HTMLImageElement(web_sys::HtmlImageElement), /// Copy from a current frame of a video element. HTMLVideoElement(web_sys::HtmlVideoElement), + /// Copy from an image. + ImageData(web_sys::ImageData), /// Copy from a on-screen canvas. HTMLCanvasElement(web_sys::HtmlCanvasElement), /// Copy from a off-screen canvas. @@ -6859,7 +6863,9 @@ impl ExternalImageSource { pub fn width(&self) -> u32 { match self { ExternalImageSource::ImageBitmap(b) => b.width(), + ExternalImageSource::HTMLImageElement(i) => i.width(), ExternalImageSource::HTMLVideoElement(v) => v.video_width(), + ExternalImageSource::ImageData(i) => i.width(), ExternalImageSource::HTMLCanvasElement(c) => c.width(), ExternalImageSource::OffscreenCanvas(c) => c.width(), } @@ -6869,7 +6875,9 @@ impl ExternalImageSource { pub fn height(&self) -> u32 { match self { ExternalImageSource::ImageBitmap(b) => b.height(), + ExternalImageSource::HTMLImageElement(i) => i.height(), ExternalImageSource::HTMLVideoElement(v) => v.video_height(), + ExternalImageSource::ImageData(i) => i.height(), ExternalImageSource::HTMLCanvasElement(c) => c.height(), ExternalImageSource::OffscreenCanvas(c) => c.height(), } @@ -6883,7 +6891,9 @@ impl std::ops::Deref for ExternalImageSource { fn deref(&self) -> &Self::Target { match self { Self::ImageBitmap(b) => b, + Self::HTMLImageElement(i) => i, Self::HTMLVideoElement(v) => v, + Self::ImageData(i) => i, Self::HTMLCanvasElement(c) => c, Self::OffscreenCanvas(c) => c, }