From 27db3e70b476f9f9e90a1926d79f2848e3f1a3aa Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Sun, 18 Jun 2023 22:05:01 +0200 Subject: [PATCH] core: Invalidate cacheAsBitmap when transform changes --- core/src/avm1/globals/movie_clip.rs | 6 ++++++ core/src/avm1/globals/transform.rs | 6 ++++++ .../globals/flash/display/display_object.rs | 6 ++++++ core/src/avm2/globals/flash/geom/transform.rs | 16 +++++++++------ core/src/display_object.rs | 19 +++++++++++++++++- core/src/display_object/avm1_button.rs | 2 ++ core/src/display_object/avm2_button.rs | 2 ++ .../nested_color_transform/expected.png | Bin 0 -> 5578 bytes .../nested_color_transform/output.txt | 0 .../nested_color_transform/test.fla | Bin 0 -> 5987 bytes .../nested_color_transform/test.swf | Bin 0 -> 670 bytes .../nested_color_transform/test.toml | 7 +++++++ .../nested_matrix/expected.png | Bin 0 -> 5600 bytes .../cache_as_bitmap/nested_matrix/output.txt | 0 .../cache_as_bitmap/nested_matrix/test.fla | Bin 0 -> 6166 bytes .../cache_as_bitmap/nested_matrix/test.swf | Bin 0 -> 714 bytes .../cache_as_bitmap/nested_matrix/test.toml | 7 +++++++ 17 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/expected.png create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/output.txt create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.fla create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.swf create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.toml create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/expected.png create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/output.txt create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/test.fla create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/test.swf create mode 100644 tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/test.toml diff --git a/core/src/avm1/globals/movie_clip.rs b/core/src/avm1/globals/movie_clip.rs index f05c5ce4f..24819d610 100644 --- a/core/src/avm1/globals/movie_clip.rs +++ b/core/src/avm1/globals/movie_clip.rs @@ -1608,6 +1608,12 @@ fn set_transform<'gc>( let color_transform = *clip.base().color_transform(); this.set_color_transform(activation.context.gc_context, color_transform); + if let Some(parent) = this.parent() { + // Self-transform changes are automatically handled, + // we only want to inform ancestors to avoid unnecessary invalidations for tx/ty + parent.invalidate_cached_bitmap(activation.context.gc_context); + } + this.set_transformed_by_script(activation.context.gc_context, true); } } diff --git a/core/src/avm1/globals/transform.rs b/core/src/avm1/globals/transform.rs index 02836ab69..931508197 100644 --- a/core/src/avm1/globals/transform.rs +++ b/core/src/avm1/globals/transform.rs @@ -97,6 +97,11 @@ fn method<'gc>( let matrix = object_to_matrix(object, activation)?; clip.set_matrix(activation.context.gc_context, matrix); clip.set_transformed_by_script(activation.context.gc_context, true); + if let Some(parent) = clip.parent() { + // Self-transform changes are automatically handled, + // we only want to inform ancestors to avoid unnecessary invalidations for tx/ty + parent.invalidate_cached_bitmap(activation.context.gc_context); + } } } Value::Undefined @@ -120,6 +125,7 @@ fn method<'gc>( activation.context.gc_context, color_transform.read().clone().into(), ); + clip.invalidate_cached_bitmap(activation.context.gc_context); clip.set_transformed_by_script(activation.context.gc_context, true); } } diff --git a/core/src/avm2/globals/flash/display/display_object.rs b/core/src/avm2/globals/flash/display/display_object.rs index 7bbeaa4ce..bb53245b3 100644 --- a/core/src/avm2/globals/flash/display/display_object.rs +++ b/core/src/avm2/globals/flash/display/display_object.rs @@ -731,6 +731,12 @@ pub fn set_transform<'gc>( let mut write = dobj.base_mut(activation.context.gc_context); write.set_matrix(matrix); write.set_color_transform(color_transform); + drop(write); + if let Some(parent) = dobj.parent() { + // Self-transform changes are automatically handled, + // we only want to inform ancestors to avoid unnecessary invalidations for tx/ty + parent.invalidate_cached_bitmap(activation.context.gc_context); + } } Ok(Value::Undefined) } diff --git a/core/src/avm2/globals/flash/geom/transform.rs b/core/src/avm2/globals/flash/geom/transform.rs index dcb0b2214..fc0082538 100644 --- a/core/src/avm2/globals/flash/geom/transform.rs +++ b/core/src/avm2/globals/flash/geom/transform.rs @@ -53,9 +53,9 @@ pub fn set_color_transform<'gc>( ) -> Result, Error<'gc>> { let this = this.unwrap(); let ct = object_to_color_transform(args.get_object(activation, 0, "value")?, activation)?; - get_display_object(this, activation)? - .base_mut(activation.context.gc_context) - .set_color_transform(ct); + let dobj = get_display_object(this, activation)?; + dobj.set_color_transform(activation.context.gc_context, ct); + dobj.invalidate_cached_bitmap(activation.context.gc_context); Ok(Value::Undefined) } @@ -76,9 +76,13 @@ pub fn set_matrix<'gc>( ) -> Result, Error<'gc>> { let this = this.unwrap(); let matrix = object_to_matrix(args.get_object(activation, 0, "value")?, activation)?; - get_display_object(this, activation)? - .base_mut(activation.context.gc_context) - .set_matrix(matrix); + let dobj = get_display_object(this, activation)?; + dobj.set_matrix(activation.context.gc_context, matrix); + if let Some(parent) = dobj.parent() { + // Self-transform changes are automatically handled, + // we only want to inform ancestors to avoid unnecessary invalidations for tx/ty + parent.invalidate_cached_bitmap(activation.context.gc_context); + } Ok(Value::Undefined) } diff --git a/core/src/display_object.rs b/core/src/display_object.rs index bcd4778f3..c7598ca5e 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -941,10 +941,16 @@ pub trait TDisplayObject<'gc>: self.base_mut(gc_context).set_place_frame(frame) } + /// Sets the matrix of this object. + /// This does NOT invalidate the cache, as it's often used with other operations. + /// It is the callers responsibility to do so. fn set_matrix(&self, gc_context: MutationContext<'gc, '_>, matrix: Matrix) { self.base_mut(gc_context).set_matrix(matrix); } + /// Sets the color transform of this object. + /// This does NOT invalidate the cache, as it's often used with other operations. + /// It is the callers responsibility to do so. fn set_color_transform( &self, gc_context: MutationContext<'gc, '_>, @@ -1184,8 +1190,13 @@ pub trait TDisplayObject<'gc>: /// Sets the opacity of this display object. /// 1 is fully opaque. /// Set by the `_alpha`/`alpha` ActionScript properties. + /// This invalidates any cacheAsBitmap automatically. fn set_alpha(&self, gc_context: MutationContext<'gc, '_>, value: f64) { - self.base_mut(gc_context).set_alpha(value) + self.base_mut(gc_context).set_alpha(value); + if let Some(parent) = self.parent() { + // Self-transform changes are automatically handled + parent.invalidate_cached_bitmap(gc_context); + } } fn name(&self) -> AvmString<'gc> { @@ -1765,9 +1776,15 @@ pub trait TDisplayObject<'gc>: if !self.transformed_by_script() { if let Some(matrix) = place_object.matrix { self.set_matrix(context.gc_context, matrix.into()); + if let Some(parent) = self.parent() { + // Self-transform changes are automatically handled, + // we only want to inform ancestors to avoid unnecessary invalidations for tx/ty + parent.invalidate_cached_bitmap(context.gc_context); + } } if let Some(color_transform) = &place_object.color_transform { self.set_color_transform(context.gc_context, *color_transform); + self.invalidate_cached_bitmap(context.gc_context); } if let Some(ratio) = place_object.ratio { if let Some(mut morph_shape) = self.as_morph_shape() { diff --git a/core/src/display_object/avm1_button.rs b/core/src/display_object/avm1_button.rs index 95497d5ed..9a4415825 100644 --- a/core/src/display_object/avm1_button.rs +++ b/core/src/display_object/avm1_button.rs @@ -191,6 +191,8 @@ impl<'gc> Avm1Button<'gc> { dispatch_removed_event(removed_child, context); } } + + self.invalidate_cached_bitmap(context.gc_context); } fn get_boolean_property( diff --git a/core/src/display_object/avm2_button.rs b/core/src/display_object/avm2_button.rs index 381866d01..6d3fdf21b 100644 --- a/core/src/display_object/avm2_button.rs +++ b/core/src/display_object/avm2_button.rs @@ -227,6 +227,8 @@ impl<'gc> Avm2Button<'gc> { } } + self.invalidate_cached_bitmap(context.gc_context); + // We manually call `construct_frame` for `child` and `state_sprite` - normally // this would be done in the `DisplayObject` constructor, but SimpleButton does // not have children in the normal DisplayObjectContainer sense. diff --git a/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/expected.png b/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..5d33ff45167de61b43ccd5f831562f5e7abbf6b0 GIT binary patch literal 5578 zcmeAS@N?(olHy`uVBq!ia0y~yU{YgXV4T3g1{9gKb@gTj2GNP0E{-7;jBg(>PEhfj zq~a;my=vxecNdqmw6w5LASefc?`LQMN6w&t$e^=j2>F!Aqq;7%BO-LLtLr$WPHORs{7|2!c`>e3e!L4<*FU+tNvLbQVv z{Fhu21Jx25{`b7YQ>f8Exq3D&xN)KXjRQulf&}hp0FEXLX#N{c`KoGSZQl`K8BqT< z(hMBI|4)t<4bXyev}_%%F(7s8XgxUEkbpF~Mw>^7b|{VO!4un%+Me&-N86~Qjr`HB z%V>uT*4rKJkd1c8hGB<{Zq@7PND;Io86E$E6{)3H2g?BBe~w!Mf@V$HJFS6Zv<#lE KelF{r5}E+&*SuW- literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/output.txt b/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.fla b/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.fla new file mode 100644 index 0000000000000000000000000000000000000000..3cdef79cdfb44e78d617830107241ef9dd8aa467 GIT binary patch literal 5987 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 B6+i$0 literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.swf b/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.swf new file mode 100644 index 0000000000000000000000000000000000000000..abec704bfae87467fee683c65c3ce55bd6dbf0a6 GIT binary patch literal 670 zcmV;P0%83_S5ptb1pokeoTZe(ZqqOv#+`2K*ojSO5+H$0cS0z2k~Uovb!BanNIMkJ z*d4sYT?0uR#p&9e*a-;<@eI5GLfV1rxbOlz1roeNvAd@0wlc#c0;&sez%YlP1h?vP&8-;F~#wJ4je!ti+6=|}ERKqZk zq9IL_xk6?KQHlq0#MTORI3ietxrraAK8>JQ<6YWIHwuL@b`ZuBY{ZJ#qr0T&(hv=B zjMSon1c!^vRzh$}lO0NfdPAt76JXYb&l1`pjBz{;VC#7W%5b;m2Oca})fzhQoMI7+ zkGiI4C0VJ+YIR4|O-(mT+9O3X6=lkMqCBy-Ns2w3;`3%rHI;Q!F{aIDv|~H<{LaCZ z%%@6NL+6sbTDG1$i8k&f!Kh!Ji%3915~YmCtB&IJT(d)y5T|t<$ARx+0Yn3tb*cNh zkN1h(5mDFBsqng6;wNjjFK>7lqD;-wZPK}1&2|oAg0=~xy~HJ4zBaxv?Y6lUu@pxx z*|O@qQ1pGzEIUohF6*jNRczZh?r#W19C5v?*&w zdz$!rKEJXvsCq-GT8+}W)l@7&ZK`^;T4}T@j;=e+vXfC~ASQbyiN8-gC!yh}3o%X@ z5lL+nvZzE%qkK(&MojkK4tBws(Y)&%=z=w)(f^6*j|ezv%xO-uuQVDzf^`U5x#4j5 zcrM2u$VG4r9`IQLU2q?O`Jaap5a06ZXYl0s2;Teh@Yi7RRqyL?NxY{yE_|EMOMC*G zd_7!}`G1br--&7t+4#1}Qnd E(-{s;O#lD@ literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.toml b/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.toml new file mode 100644 index 000000000..4a2532106 --- /dev/null +++ b/tests/tests/swfs/visual/cache_as_bitmap/nested_color_transform/test.toml @@ -0,0 +1,7 @@ +num_frames = 3 + +[image_comparison] +tolerance = 0 + +[player_options] +with_renderer = { optional = false, sample_count = 1 } diff --git a/tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/expected.png b/tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..081ddcba7306be9cf29a5442d73da90e436d5926 GIT binary patch literal 5600 zcmeAS@N?(olHy`uVBq!ia0y~yU{YgXV4T3g1{9gKb@gTj2GQl7E{-7;jBg(>PEhfj zq~a;my=vxecNdqmw6w5LASefc?`LQMN6w&t$e^=j2>F!Aqq;7%BO-LLtLr$WPHORs{7|2!c`>e3e!L4<*FU+tNvLbQVv z{Fhu21Jx25{`b7YQ>f8Exq3D&xN)KXjRQulf&}hp08%?y{4xLCz5fR{EWy@qo?g9k z`r}pq1xC{_G)Ir-%+aC^QZkPg*rPQbxWXQ-hNxW)4bq0tzwnBm)9WjNwd4QQ_WwWI zKVS7# xnpIOn&TOOtzHYQbJlY`!_5(+JtLHz*QysBcSN5|l1&-V@c)I$ztaD0e0sx7L(ii{$ literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/output.txt b/tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/test.fla b/tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/test.fla new file mode 100644 index 0000000000000000000000000000000000000000..01918afedebfe89a38ed7971498417d926e86711 GIT binary patch literal 6166 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 literal 0 HcmV?d00001 diff --git a/tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/test.toml b/tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/test.toml new file mode 100644 index 000000000..4a2532106 --- /dev/null +++ b/tests/tests/swfs/visual/cache_as_bitmap/nested_matrix/test.toml @@ -0,0 +1,7 @@ +num_frames = 3 + +[image_comparison] +tolerance = 0 + +[player_options] +with_renderer = { optional = false, sample_count = 1 }