From 48f7ff5f4d72ca7f560b66cab9418cf263a0d995 Mon Sep 17 00:00:00 2001 From: Mike Welsh Date: Wed, 18 May 2022 12:52:43 -0700 Subject: [PATCH] core: Add `Bitmap::to_rgba` --- core/src/backend/render.rs | 13 +++++++++++++ render/canvas/src/lib.rs | 39 ++++++++------------------------------ render/wgpu/src/lib.rs | 22 +++------------------ 3 files changed, 24 insertions(+), 50 deletions(-) diff --git a/core/src/backend/render.rs b/core/src/backend/render.rs index dcc43bba7..9c1da478a 100644 --- a/core/src/backend/render.rs +++ b/core/src/backend/render.rs @@ -247,6 +247,19 @@ impl Bitmap { } } + pub fn to_rgba(mut self) -> Self { + // Converts this bitmap to RGBA, if it is not already. + if self.format == BitmapFormat::Rgb { + self.data = self + .data + .chunks_exact(3) + .flat_map(|rgb| [rgb[0], rgb[1], rgb[2], 255]) + .collect(); + self.format = BitmapFormat::Rgba; + } + self + } + #[inline] pub fn width(&self) -> u32 { self.width diff --git a/render/canvas/src/lib.rs b/render/canvas/src/lib.rs index 1c5a375d4..cd6ce522e 100644 --- a/render/canvas/src/lib.rs +++ b/render/canvas/src/lib.rs @@ -374,38 +374,15 @@ impl WebCanvasRenderBackend { /// Puts the contents of the given Bitmap into an ImageData on the browser side, /// doing the RGB to RGBA expansion if needed. - fn swf_bitmap_to_js_imagedata(bitmap: &mut Bitmap) -> ImageData { - match &bitmap.format() { - BitmapFormat::Rgb => { - let mut rgba_data = - Vec::with_capacity(bitmap.width() as usize * bitmap.height() as usize * 4); - for rgb in bitmap.data().chunks_exact(3) { - rgba_data.extend_from_slice(rgb); - rgba_data.push(255); - } - *bitmap = Bitmap::from_data( - bitmap.width(), - bitmap.height(), - BitmapFormat::Rgba, - rgba_data, - ); - let image_data = - ImageData::new_with_u8_clamped_array(Clamped(bitmap.data()), bitmap.width()) - .unwrap(); - image_data - } - BitmapFormat::Rgba => { - ImageData::new_with_u8_clamped_array(Clamped(bitmap.data()), bitmap.width()) - .unwrap() - } - } + fn swf_bitmap_to_js_imagedata(bitmap: Bitmap) -> ImageData { + let bitmap = bitmap.to_rgba(); + assert!(bitmap.format() == BitmapFormat::Rgba); + ImageData::new_with_u8_clamped_array(Clamped(bitmap.data()), bitmap.width()).unwrap() } - fn register_bitmap_raw(&mut self, mut bitmap: Bitmap) -> Result { + fn register_bitmap_raw(&mut self, bitmap: Bitmap) -> Result { let (width, height) = (bitmap.width(), bitmap.height()); - - let image = Self::swf_bitmap_to_js_imagedata(&mut bitmap); - + let image = Self::swf_bitmap_to_js_imagedata(bitmap); let handle = BitmapHandle(self.bitmaps.len()); self.bitmaps.push(BitmapData { image: BitmapDataStorage::from_image_data(image), @@ -493,8 +470,8 @@ impl RenderBackend for WebCanvasRenderBackend { &mut self, swf_tag: &swf::DefineBitsLossless, ) -> Result { - let mut bitmap = ruffle_core::backend::render::decode_define_bits_lossless(swf_tag)?; - let image = Self::swf_bitmap_to_js_imagedata(&mut bitmap); + let bitmap = ruffle_core::backend::render::decode_define_bits_lossless(swf_tag)?; + let image = Self::swf_bitmap_to_js_imagedata(bitmap); let handle = BitmapHandle(self.bitmaps.len()); self.bitmaps.push(BitmapData { image: BitmapDataStorage::from_image_data(image), diff --git a/render/wgpu/src/lib.rs b/render/wgpu/src/lib.rs index d0cf874e4..3d87114b9 100644 --- a/render/wgpu/src/lib.rs +++ b/render/wgpu/src/lib.rs @@ -4,7 +4,7 @@ use ruffle_core::backend::render::{ }; use ruffle_core::shape_utils::DistilledShape; use ruffle_core::swf; -use std::{borrow::Cow, num::NonZeroU32}; +use std::num::NonZeroU32; use bytemuck::{Pod, Zeroable}; @@ -734,29 +734,13 @@ impl WgpuRenderBackend { } fn register_bitmap(&mut self, bitmap: Bitmap, debug_str: &str) -> BitmapInfo { + let bitmap = bitmap.to_rgba(); let extent = wgpu::Extent3d { width: bitmap.width(), height: bitmap.height(), depth_or_array_layers: 1, }; - let data: Cow<[u8]> = match &bitmap.format() { - BitmapFormat::Rgba => Cow::Borrowed(bitmap.data()), - BitmapFormat::Rgb => { - // Expand to RGBA. - let data = bitmap.data(); - let mut as_rgba = - Vec::with_capacity(extent.width as usize * extent.height as usize * 4); - for i in (0..data.len()).step_by(3) { - as_rgba.push(data[i]); - as_rgba.push(data[i + 1]); - as_rgba.push(data[i + 2]); - as_rgba.push(255); - } - Cow::Owned(as_rgba) - } - }; - let texture_label = create_debug_label!("{} Texture", debug_str); let texture = self .descriptors @@ -778,7 +762,7 @@ impl WgpuRenderBackend { origin: Default::default(), aspect: wgpu::TextureAspect::All, }, - &data, + bitmap.data(), wgpu::ImageDataLayout { offset: 0, bytes_per_row: NonZeroU32::new(4 * extent.width),