core: Allow `BitmapData` to hold an AVM2 side.

This commit is contained in:
David Wendt 2021-09-02 20:22:17 -04:00 committed by Mike Welsh
parent 10b98f72f5
commit 54740d6093
5 changed files with 48 additions and 15 deletions

View File

@ -16,7 +16,7 @@ pub struct BitmapDataObject<'gc>(GcCell<'gc, BitmapDataData<'gc>>);
pub struct BitmapDataData<'gc> {
/// The underlying script object.
base: ScriptObject<'gc>,
data: GcCell<'gc, BitmapData>,
data: GcCell<'gc, BitmapData<'gc>>,
disposed: bool,
}
@ -32,7 +32,7 @@ impl fmt::Debug for BitmapDataObject<'_> {
impl<'gc> BitmapDataObject<'gc> {
add_field_accessors!(
[disposed, bool, get => disposed],
[data, GcCell<'gc, BitmapData>, set => set_bitmap_data, get => bitmap_data],
[data, GcCell<'gc, BitmapData<'gc>>, set => set_bitmap_data, get => bitmap_data],
);
pub fn empty_object(gc_context: MutationContext<'gc, '_>, proto: Option<Object<'gc>>) -> Self {

View File

@ -1243,16 +1243,20 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
fn set_sound_instance(self, _mc: MutationContext<'gc, '_>, _sound: SoundInstanceHandle) {}
/// Unwrap this object's bitmap data
fn as_bitmap_data(&self) -> Option<GcCell<'gc, BitmapData>> {
fn as_bitmap_data(&self) -> Option<GcCell<'gc, BitmapData<'gc>>> {
None
}
/// Initialize the bitmap data in this object, if it's capable of
/// supporting said data
/// supporting said data.
///
/// This should only be called to initialize the association between an AVM
/// object and it's associated bitmap data. This association should not be
/// reinitialized later.
fn init_bitmap_data(
&self,
_mc: MutationContext<'gc, '_>,
_new_bitmap: GcCell<'gc, BitmapData>,
_new_bitmap: GcCell<'gc, BitmapData<'gc>>,
) {
}
}

View File

@ -43,13 +43,13 @@ pub struct BitmapDataObjectData<'gc> {
/// Base script object
base: ScriptObjectData<'gc>,
bitmap_data: Option<GcCell<'gc, BitmapData>>,
bitmap_data: Option<GcCell<'gc, BitmapData<'gc>>>,
}
impl<'gc> BitmapDataObject<'gc> {
pub fn from_bitmap_data(
activation: &mut Activation<'_, 'gc, '_>,
bitmap_data: GcCell<'gc, BitmapData>,
bitmap_data: GcCell<'gc, BitmapData<'gc>>,
class: Object<'gc>,
) -> Result<Object<'gc>, Error> {
let proto = class
@ -67,6 +67,10 @@ impl<'gc> BitmapDataObject<'gc> {
bitmap_data: Some(bitmap_data),
},
));
bitmap_data
.write(activation.context.gc_context)
.init_object2(instance.into());
instance.install_instance_traits(activation, class)?;
class.call_native_init(Some(instance.into()), &[], activation, Some(class))?;
@ -101,13 +105,17 @@ impl<'gc> TObject<'gc> for BitmapDataObject<'gc> {
}
/// Unwrap this object's bitmap data
fn as_bitmap_data(&self) -> Option<GcCell<'gc, BitmapData>> {
fn as_bitmap_data(&self) -> Option<GcCell<'gc, BitmapData<'gc>>> {
self.0.read().bitmap_data
}
/// Initialize the bitmap data in this object, if it's capable of
/// supporting said data
fn init_bitmap_data(&self, mc: MutationContext<'gc, '_>, new_bitmap: GcCell<'gc, BitmapData>) {
fn init_bitmap_data(
&self,
mc: MutationContext<'gc, '_>,
new_bitmap: GcCell<'gc, BitmapData<'gc>>,
) {
self.0.write(mc).bitmap_data = Some(new_bitmap)
}
}

View File

@ -1,5 +1,6 @@
use gc_arena::Collect;
use crate::avm2::{Object as Avm2Object, Value as Avm2Value};
use crate::backend::render::{BitmapHandle, RenderBackend};
use crate::bitmap::color_transform_params::ColorTransformParams;
use crate::bitmap::turbulence::Turbulence;
@ -130,7 +131,7 @@ bitflags! {
#[derive(Clone, Collect, Default, Debug)]
#[collect(no_drop)]
pub struct BitmapData {
pub struct BitmapData<'gc> {
/// The pixels in the bitmap, stored as a array of pre-multiplied ARGB colour values
pub pixels: Vec<Color>,
dirty: bool,
@ -138,10 +139,20 @@ pub struct BitmapData {
height: u32,
transparency: bool,
/// The bitmap handle for this data.
///
/// This is lazily initialized; a value of `None` indicates that
/// initialization has not yet happened.
bitmap_handle: Option<BitmapHandle>,
/// The AVM2 side of this `BitmapData`.
///
/// AVM1 cannot retrieve `BitmapData` back from the display object tree, so
/// this does not need to hold an AVM1 object.
avm2_object: Option<Avm2Object<'gc>>,
}
impl BitmapData {
impl<'gc> BitmapData<'gc> {
pub fn init_pixels(&mut self, width: u32, height: u32, transparency: bool, fill_color: i32) {
self.width = width;
self.height = height;
@ -842,4 +853,14 @@ impl BitmapData {
src_y += dy;
}
}
pub fn object2(&self) -> Avm2Value<'gc> {
self.avm2_object
.map(|o| o.into())
.unwrap_or(Avm2Value::Undefined)
}
pub fn init_object2(&mut self, object: Avm2Object<'gc>) {
self.avm2_object = Some(object)
}
}

View File

@ -31,7 +31,7 @@ pub struct BitmapData<'gc> {
static_data: Gc<'gc, BitmapStatic>,
/// The current bitmap data object.
bitmap_data: Option<GcCell<'gc, crate::bitmap::bitmap_data::BitmapData>>,
bitmap_data: Option<GcCell<'gc, crate::bitmap::bitmap_data::BitmapData<'gc>>>,
/// The current bitmap handle.
///
@ -59,7 +59,7 @@ impl<'gc> Bitmap<'gc> {
bitmap_handle: BitmapHandle,
width: u16,
height: u16,
bitmap_data: Option<GcCell<'gc, crate::bitmap::bitmap_data::BitmapData>>,
bitmap_data: Option<GcCell<'gc, crate::bitmap::bitmap_data::BitmapData<'gc>>>,
smoothing: bool,
) -> Self {
let bitmap_handle = bitmap_data
@ -112,7 +112,7 @@ impl<'gc> Bitmap<'gc> {
}
/// Retrieve the bitmap data associated with this `Bitmap`.
pub fn bitmap_data(self) -> Option<GcCell<'gc, crate::bitmap::bitmap_data::BitmapData>> {
pub fn bitmap_data(self) -> Option<GcCell<'gc, crate::bitmap::bitmap_data::BitmapData<'gc>>> {
self.0.read().bitmap_data
}
@ -127,7 +127,7 @@ impl<'gc> Bitmap<'gc> {
pub fn set_bitmap_data(
self,
context: &mut UpdateContext<'_, 'gc, '_>,
bitmap_data: GcCell<'gc, crate::bitmap::bitmap_data::BitmapData>,
bitmap_data: GcCell<'gc, crate::bitmap::bitmap_data::BitmapData<'gc>>,
) {
let bitmap_handle = bitmap_data
.write(context.gc_context)