From 61a664fec67b33a6d73ccd72a58bf18f8219edb5 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 23 Feb 2023 11:58:08 -0600 Subject: [PATCH] core: Produce an error when BitmapData.draw call is unsupported --- core/src/avm1/globals/bitmap_data.rs | 14 +++++++--- .../avm2/globals/flash/display/bitmap_data.rs | 20 ++++++++++---- core/src/bitmap/bitmap_data.rs | 26 ++++++++++++------- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/core/src/avm1/globals/bitmap_data.rs b/core/src/avm1/globals/bitmap_data.rs index 41469ac05..f9bad7860 100644 --- a/core/src/avm1/globals/bitmap_data.rs +++ b/core/src/avm1/globals/bitmap_data.rs @@ -6,8 +6,8 @@ use crate::avm1::globals::color_transform::ColorTransformObject; use crate::avm1::object::bitmap_data::BitmapDataObject; use crate::avm1::property_decl::{define_properties_on, Declaration}; use crate::avm1::{Activation, Error, Object, TObject, Value}; -use crate::bitmap::bitmap_data::IBitmapDrawable; use crate::bitmap::bitmap_data::{BitmapData, ChannelOptions, Color}; +use crate::bitmap::bitmap_data::{BitmapDataDrawError, IBitmapDrawable}; use crate::bitmap::is_size_valid; use crate::character::Character; use crate::display_object::TDisplayObject; @@ -551,7 +551,7 @@ pub fn draw<'gc>( .bitmap_data_wrapper() .overwrite_cpu_pixels_from_gpu(&mut activation.context); let mut write = bmd.write(activation.context.gc_context); - write.draw( + match write.draw( source, Transform { matrix, @@ -562,7 +562,15 @@ pub fn draw<'gc>( None, activation.context.stage.quality(), &mut activation.context, - ); + ) { + Ok(()) => {} + Err(BitmapDataDrawError::Unimplemented) => { + avm_error!( + activation, + "Render backend does not support BitmapData.draw" + ); + } + } return Ok(Value::Undefined); } } diff --git a/core/src/avm2/globals/flash/display/bitmap_data.rs b/core/src/avm2/globals/flash/display/bitmap_data.rs index 84d5b6781..5b187477c 100644 --- a/core/src/avm2/globals/flash/display/bitmap_data.rs +++ b/core/src/avm2/globals/flash/display/bitmap_data.rs @@ -7,8 +7,8 @@ use crate::avm2::object::{BitmapDataObject, ByteArrayObject, Object, TObject}; use crate::avm2::value::Value; use crate::avm2::Error; use crate::avm2_stub_method; -use crate::bitmap::bitmap_data::IBitmapDrawable; use crate::bitmap::bitmap_data::{BitmapData, ChannelOptions, Color}; +use crate::bitmap::bitmap_data::{BitmapDataDrawError, IBitmapDrawable}; use crate::bitmap::is_size_valid; use crate::character::Character; use crate::display_object::Bitmap; @@ -794,7 +794,7 @@ pub fn draw<'gc>( return Err(format!("BitmapData.draw: unexpected source {source:?}").into()); }; - bitmap_data.draw( + match bitmap_data.draw( source, transform, smoothing, @@ -802,7 +802,12 @@ pub fn draw<'gc>( clip_rect, activation.context.stage.quality(), &mut activation.context, - ); + ) { + Ok(()) => {} + Err(BitmapDataDrawError::Unimplemented) => { + return Err("Render backend does not support BitmapData.draw".into()); + } + } } Ok(Value::Undefined) } @@ -892,7 +897,7 @@ pub fn draw_with_quality<'gc>( activation.context.stage.quality() }; - bitmap_data.draw( + match bitmap_data.draw( source, transform, smoothing, @@ -900,7 +905,12 @@ pub fn draw_with_quality<'gc>( clip_rect, quality, &mut activation.context, - ); + ) { + Ok(()) => {} + Err(BitmapDataDrawError::Unimplemented) => { + return Err("Render backend does not support BitmapData.draw".into()); + } + } } Ok(Value::Undefined) } diff --git a/core/src/bitmap/bitmap_data.rs b/core/src/bitmap/bitmap_data.rs index 235e9c233..49ee9629e 100644 --- a/core/src/bitmap/bitmap_data.rs +++ b/core/src/bitmap/bitmap_data.rs @@ -47,6 +47,11 @@ impl LehmerRng { #[collect(no_drop)] pub struct Color(i32); +#[derive(Debug, Clone)] +pub enum BitmapDataDrawError { + Unimplemented, +} + impl Color { pub fn blue(&self) -> u8 { (self.0 & 0xFF) as u8 @@ -1353,7 +1358,7 @@ impl<'gc> BitmapData<'gc> { clip_rect: Option>, quality: StageQuality, context: &mut UpdateContext<'_, 'gc>, - ) { + ) -> Result<(), BitmapDataDrawError> { let bitmapdata_width = self.width(); let bitmapdata_height = self.height(); @@ -1436,16 +1441,17 @@ impl<'gc> BitmapData<'gc> { ); match image { - Some(sync_handle) => match self.dirty_state { - DirtyState::Clean => self.dirty_state = DirtyState::GpuModified(sync_handle), - DirtyState::CpuModified | DirtyState::GpuModified(_) => panic!( - "Called BitmapData.render while already dirty: {:?}", - self.dirty_state - ), - }, - None => { - tracing::warn!("BitmapData.draw: Not yet implemented") + Some(sync_handle) => { + match self.dirty_state { + DirtyState::Clean => self.dirty_state = DirtyState::GpuModified(sync_handle), + DirtyState::CpuModified | DirtyState::GpuModified(_) => panic!( + "Called BitmapData.render while already dirty: {:?}", + self.dirty_state + ), + } + Ok(()) } + None => Err(BitmapDataDrawError::Unimplemented), } } }