Skip to content

Commit afa3282

Browse files
committed
Deal with flip_y and multiplication
1 parent f7fe90c commit afa3282

File tree

8 files changed

+65
-9
lines changed

8 files changed

+65
-9
lines changed

wgpu-core/src/device/queue.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
996996

997997
unsafe {
998998
encoder.transition_textures(transitions.map(|pending| pending.into_hal(dst)));
999-
encoder.copy_external_image_to_texture(&source.source, dst_raw, iter::once(regions));
999+
encoder.copy_external_image_to_texture(
1000+
source,
1001+
dst_raw,
1002+
destination.premultiplied_alpha,
1003+
iter::once(regions),
1004+
);
10001005
}
10011006

10021007
Ok(())

wgpu-hal/src/empty.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,9 @@ impl crate::CommandEncoder<Api> for Encoder {
267267
#[cfg(all(target_arch = "wasm32", not(feature = "emscripten")))]
268268
unsafe fn copy_external_image_to_texture<T>(
269269
&mut self,
270-
src: &wgt::ExternalImageSource,
270+
src: &wgt::ImageCopyExternalImage,
271271
dst: &Resource,
272+
dst_premultiplication: bool,
272273
regions: T,
273274
) where
274275
T: Iterator<Item = crate::TextureCopy>,

wgpu-hal/src/gles/command.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,9 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
312312
#[cfg(all(target_arch = "wasm32", not(feature = "emscripten")))]
313313
unsafe fn copy_external_image_to_texture<T>(
314314
&mut self,
315-
src: &wgt::ExternalImageSource,
315+
src: &wgt::ImageCopyExternalImage,
316316
dst: &super::Texture,
317+
dst_premultiplication: bool,
317318
regions: T,
318319
) where
319320
T: Iterator<Item = crate::TextureCopy>,
@@ -328,6 +329,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
328329
dst: dst_raw,
329330
dst_target,
330331
dst_format: dst.format,
332+
dst_premultiplication,
331333
copy,
332334
})
333335
}

wgpu-hal/src/gles/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -663,10 +663,11 @@ enum Command {
663663
},
664664
#[cfg(all(target_arch = "wasm32", not(feature = "emscripten")))]
665665
CopyExternalImageToTexture {
666-
src: wgt::ExternalImageSource,
666+
src: wgt::ImageCopyExternalImage,
667667
dst: glow::Texture,
668668
dst_target: BindTarget,
669669
dst_format: wgt::TextureFormat,
670+
dst_premultiplication: bool,
670671
copy: crate::TextureCopy,
671672
},
672673
CopyTextureToTexture {

wgpu-hal/src/gles/queue.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -381,12 +381,24 @@ impl super::Queue {
381381
dst,
382382
dst_target,
383383
dst_format,
384+
dst_premultiplication,
384385
ref copy,
385386
} => {
387+
const UNPACK_FLIP_Y_WEBGL: u32 = 0x9240;
388+
const UNPACK_PREMULTIPLY_ALPHA_WEBGL: u32 = 0x9241;
389+
390+
unsafe {
391+
gl.pixel_store_i32(UNPACK_FLIP_Y_WEBGL, src.flip_y as i32);
392+
gl.pixel_store_i32(
393+
UNPACK_PREMULTIPLY_ALPHA_WEBGL,
394+
dst_premultiplication as i32,
395+
);
396+
}
397+
386398
unsafe { gl.bind_texture(dst_target, Some(dst)) };
387399
let format_desc = self.shared.describe_texture_format(dst_format);
388400
if is_layered_target(dst_target) {
389-
match *src {
401+
match src.source {
390402
wgt::ExternalImageSource::ImageBitmap(ref b) => unsafe {
391403
gl.tex_sub_image_3d_with_image_bitmap(
392404
dst_target,
@@ -435,7 +447,7 @@ impl super::Queue {
435447
wgt::ExternalImageSource::OffscreenCanvas(_) => unreachable!(),
436448
}
437449
} else {
438-
match *src {
450+
match src.source {
439451
wgt::ExternalImageSource::ImageBitmap(ref b) => unsafe {
440452
gl.tex_sub_image_2d_with_image_bitmap_and_width_and_height(
441453
dst_target,
@@ -478,6 +490,11 @@ impl super::Queue {
478490
wgt::ExternalImageSource::OffscreenCanvas(_) => unreachable!(),
479491
}
480492
}
493+
494+
unsafe {
495+
gl.pixel_store_i32(UNPACK_FLIP_Y_WEBGL, 0);
496+
gl.pixel_store_i32(UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
497+
}
481498
}
482499
C::CopyTextureToTexture {
483500
src,

wgpu-hal/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,9 @@ pub trait CommandEncoder<A: Api>: Send + Sync + fmt::Debug {
405405
#[cfg(all(target_arch = "wasm32", not(feature = "emscripten")))]
406406
unsafe fn copy_external_image_to_texture<T>(
407407
&mut self,
408-
src: &wgt::ExternalImageSource,
408+
src: &wgt::ImageCopyExternalImage,
409409
dst: &A::Texture,
410+
dst_premultiplication: bool,
410411
regions: T,
411412
) where
412413
T: Iterator<Item = TextureCopy>;

wgpu/tests/3x3_colors.png

-18 Bytes
Loading

wgpu/tests/external_texture.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ async fn image_bitmap_import() {
4545
enum TestCase {
4646
// Import the image as normal
4747
Normal,
48+
// Sets the FlipY flag. Deals with global state on GLES, so run before other tests to ensure it's reset.
49+
FlipY,
50+
// Sets the premultiplied alpha flag. Deals with global state on GLES, so run before other tests to ensure it's reset.
51+
Premultiplied,
4852
// Set both the input offset and output offset to 1 in x, so the first column is omitted.
4953
TrimLeft,
5054
// Set the size to 2 in x, so the last column is omitted
@@ -62,6 +66,8 @@ async fn image_bitmap_import() {
6266
}
6367
let cases = [
6468
TestCase::Normal,
69+
TestCase::FlipY,
70+
TestCase::Premultiplied,
6571
TestCase::TrimLeft,
6672
TestCase::TrimRight,
6773
TestCase::SlideRight,
@@ -77,10 +83,14 @@ async fn image_bitmap_import() {
7783
let mut raw_image = raw_image.clone();
7884
// The origin used for the external copy on the source side.
7985
let mut src_origin = wgpu::Origin2d::ZERO;
86+
// If the source should be flipped in Y
87+
let mut src_flip_y = false;
8088
// The origin used for the external copy on the destination side.
8189
let mut dest_origin = wgpu::Origin3d::ZERO;
8290
// The layer the external image's data should end up in.
8391
let mut dest_data_layer = 0;
92+
// The layer the external image's data should end up in.
93+
let mut dest_premultiplied = false;
8494
// Size of the external copy
8595
let mut copy_size = wgpu::Extent3d {
8696
width: 3,
@@ -98,6 +108,25 @@ async fn image_bitmap_import() {
98108
let mut correct = true;
99109
match case {
100110
TestCase::Normal => {}
111+
TestCase::FlipY => {
112+
src_flip_y = true;
113+
for x in 0..3 {
114+
let top = raw_image[(x, 0)];
115+
let bottom = raw_image[(x, 2)];
116+
raw_image[(x, 0)] = bottom;
117+
raw_image[(x, 2)] = top;
118+
}
119+
}
120+
TestCase::Premultiplied => {
121+
dest_premultiplied = true;
122+
for pixel in raw_image.pixels_mut() {
123+
let mut float_pix = pixel.0.map(|v| v as f32 / 255.0);
124+
float_pix[0] *= float_pix[3];
125+
float_pix[1] *= float_pix[3];
126+
float_pix[2] *= float_pix[3];
127+
pixel.0 = float_pix.map(|v| (v * 255.0).round() as u8);
128+
}
129+
}
101130
TestCase::TrimLeft => {
102131
valid = ctx
103132
.adapter_downlevel_capabilities
@@ -173,15 +202,15 @@ async fn image_bitmap_import() {
173202
&wgpu::ImageCopyExternalImage {
174203
source: wgpu::ExternalImageSource::ImageBitmap(image_bitmap.clone()),
175204
origin: src_origin,
176-
flip_y: false,
205+
flip_y: src_flip_y,
177206
},
178207
wgpu::ImageCopyTextureTagged {
179208
texture: &texture,
180209
mip_level: 0,
181210
origin: dest_origin,
182211
aspect: wgpu::TextureAspect::All,
183212
color_space: wgpu::PredefinedColorSpace::Srgb,
184-
premultiplied_alpha: false,
213+
premultiplied_alpha: dest_premultiplied,
185214
},
186215
copy_size,
187216
);

0 commit comments

Comments
 (0)