core: Add `Bitmap::to_rgba`

This commit is contained in:
Mike Welsh 2022-05-18 12:52:43 -07:00
parent e710f3fa0e
commit 48f7ff5f4d
3 changed files with 24 additions and 50 deletions

View File

@ -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

View File

@ -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<BitmapInfo, Error> {
fn register_bitmap_raw(&mut self, bitmap: Bitmap) -> Result<BitmapInfo, Error> {
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<BitmapInfo, Error> {
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),

View File

@ -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<T: RenderTarget> WgpuRenderBackend<T> {
}
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<T: RenderTarget> WgpuRenderBackend<T> {
origin: Default::default(),
aspect: wgpu::TextureAspect::All,
},
&data,
bitmap.data(),
wgpu::ImageDataLayout {
offset: 0,
bytes_per_row: NonZeroU32::new(4 * extent.width),