core: Invalidate cacheAsBitmap when transform changes

This commit is contained in:
Nathan Adams 2023-06-18 22:05:01 +02:00
parent 0f01efb322
commit 27db3e70b4
17 changed files with 64 additions and 7 deletions

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

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

View File

@ -53,9 +53,9 @@ pub fn set_color_transform<'gc>(
) -> Result<Value<'gc>, 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<Value<'gc>, 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)
}

View File

@ -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() {

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -0,0 +1,7 @@
num_frames = 3
[image_comparison]
tolerance = 0
[player_options]
with_renderer = { optional = false, sample_count = 1 }

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -0,0 +1,7 @@
num_frames = 3
[image_comparison]
tolerance = 0
[player_options]
with_renderer = { optional = false, sample_count = 1 }