diff --git a/core/src/avm2/filters.rs b/core/src/avm2/filters.rs index 74613acd0..4d6e5769a 100644 --- a/core/src/avm2/filters.rs +++ b/core/src/avm2/filters.rs @@ -36,6 +36,14 @@ impl ShaderObject for ObjectWrapper { fn clone_box(&self) -> Box { Box::new(self.clone()) } + + fn equals(&self, other: &dyn ShaderObject) -> bool { + if let Some(other_wrapper) = other.downcast_ref::() { + self.root.as_ptr() == other_wrapper.root.as_ptr() + } else { + false + } + } } impl Debug for ObjectWrapper { diff --git a/core/src/display_object.rs b/core/src/display_object.rs index 10cdb9e4c..aabe1be0a 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -505,9 +505,14 @@ impl<'gc> DisplayObjectBase<'gc> { self.filters.clone() } - fn set_filters(&mut self, filters: Vec) { - self.filters = filters; - self.recheck_cache_as_bitmap(); + fn set_filters(&mut self, filters: Vec) -> bool { + if filters != self.filters { + self.filters = filters; + self.recheck_cache_as_bitmap(); + true + } else { + false + } } fn alpha(&self) -> f64 { @@ -1477,8 +1482,9 @@ pub trait TDisplayObject<'gc>: } fn set_filters(&self, gc_context: &Mutation<'gc>, filters: Vec) { - self.base_mut(gc_context).set_filters(filters); - self.invalidate_cached_bitmap(gc_context); + if self.base_mut(gc_context).set_filters(filters) { + self.invalidate_cached_bitmap(gc_context); + } } /// Returns the dot-syntax path to this display object, e.g. `_level0.foo.clip` diff --git a/render/src/backend.rs b/render/src/backend.rs index 9c7e55ab0..5bce5e40c 100644 --- a/render/src/backend.rs +++ b/render/src/backend.rs @@ -123,11 +123,21 @@ pub trait Texture: Downcast + Debug { } impl_downcast!(Texture); -pub trait RawTexture: Downcast + Debug {} +pub trait RawTexture: Downcast + Debug { + fn equals(&self, other: &dyn RawTexture) -> bool; +} impl_downcast!(RawTexture); #[cfg(feature = "wgpu")] -impl RawTexture for wgpu::Texture {} +impl RawTexture for wgpu::Texture { + fn equals(&self, other: &dyn RawTexture) -> bool { + if let Some(other_texture) = other.downcast_ref::() { + std::ptr::eq(self, other_texture) + } else { + false + } + } +} #[derive(Debug, Copy, Clone)] pub enum Context3DTextureFormat { diff --git a/render/src/bitmap.rs b/render/src/bitmap.rs index 19b4a2dd1..1eca68c7a 100644 --- a/render/src/bitmap.rs +++ b/render/src/bitmap.rs @@ -12,6 +12,12 @@ use crate::matrix::Matrix; #[derive(Clone, Debug)] pub struct BitmapHandle(pub Arc); +impl PartialEq for BitmapHandle { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.0, &other.0) + } +} + pub trait BitmapHandleImpl: Downcast + Debug {} impl_downcast!(BitmapHandleImpl); diff --git a/render/src/filters.rs b/render/src/filters.rs index 48c995360..094db0b75 100644 --- a/render/src/filters.rs +++ b/render/src/filters.rs @@ -6,7 +6,7 @@ use downcast_rs::{impl_downcast, Downcast}; use std::fmt::Debug; use swf::{Color, Rectangle, Twips}; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum Filter { BevelFilter(swf::BevelFilter), BlurFilter(swf::BlurFilter), @@ -35,8 +35,22 @@ pub struct ShaderFilter<'a> { pub shader_args: Vec>, } +impl<'gc> PartialEq for ShaderFilter<'gc> { + fn eq(&self, other: &Self) -> bool { + self.bottom_extension == other.bottom_extension + && self.left_extension == other.left_extension + && self.right_extension == other.right_extension + && self.top_extension == other.top_extension + && self.shader_object.equals(other.shader_object.as_ref()) + && self.shader == other.shader + && self.shader_args == other.shader_args + } +} + pub trait ShaderObject: Downcast + Debug { fn clone_box(&self) -> Box; + + fn equals(&self, other: &dyn ShaderObject) -> bool; } impl_downcast!(ShaderObject); @@ -132,7 +146,7 @@ pub enum DisplacementMapFilterMode { Wrap, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct DisplacementMapFilter { pub color: Color, pub component_x: u8, diff --git a/render/src/pixel_bender.rs b/render/src/pixel_bender.rs index e578648d6..e1e402dc0 100644 --- a/render/src/pixel_bender.rs +++ b/render/src/pixel_bender.rs @@ -22,6 +22,12 @@ pub const OUT_COORD_NAME: &str = "_OutCoord"; #[derive(Clone, Debug)] pub struct PixelBenderShaderHandle(pub Arc); +impl PartialEq for PixelBenderShaderHandle { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.0, &other.0) + } +} + pub trait PixelBenderShaderImpl: Downcast + Debug { fn parsed_shader(&self) -> &PixelBenderShader; } @@ -249,7 +255,7 @@ pub enum Operation { }, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub enum PixelBenderShaderArgument<'a> { ImageInput { index: u8, @@ -273,6 +279,18 @@ pub enum ImageInputTexture<'a> { TextureRef(&'a dyn RawTexture), } +impl PartialEq for ImageInputTexture<'_> { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Bitmap(self_bitmap), Self::Bitmap(other_bitmap)) => self_bitmap == other_bitmap, + (Self::TextureRef(self_texture), Self::TextureRef(other_texture)) => { + self_texture.equals(*other_texture) + } + _ => false, + } + } +} + impl From for ImageInputTexture<'_> { fn from(b: BitmapHandle) -> Self { ImageInputTexture::Bitmap(b)