From 92e2adf45f293c16d9a027fa1d3b85bd57bae6e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 29 May 2018 15:09:00 +0200 Subject: [PATCH] style: Cleanup transform animation. Reviewed-by: hiro But: 1465066 MozReview-Commit-ID: D9rq8CZIgf5 --- .../helpers/animated_properties.mako.rs | 124 +++++++----------- 1 file changed, 50 insertions(+), 74 deletions(-) diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 9ada8d523c3..f45b7ffe91e 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -2501,107 +2501,83 @@ impl Animate for ComputedScale { /// impl Animate for ComputedTransform { #[inline] - fn animate( - &self, - other_: &Self, - procedure: Procedure, - ) -> Result { - - let animate_equal_lists = |this: &[ComputedTransformOperation], - other: &[ComputedTransformOperation]| - -> Result { - Ok(Transform(this.iter().zip(other) - .map(|(this, other)| this.animate(other, procedure)) - .collect::, _>>()?)) - // If we can't animate for a pair of matched transform lists - // this means we have at least one undecomposable matrix, - // so we should bubble out Err here, and let the caller do - // the fallback procedure. - }; - if self.0.is_empty() && other_.0.is_empty() { - return Ok(Transform(vec![])); - } - - - let this = &self.0; - let other = &other_.0; + fn animate(&self, other: &Self, procedure: Procedure) -> Result { + use std::borrow::Cow; if procedure == Procedure::Add { - let result = this.iter().chain(other).cloned().collect::>(); + let result = self.0.iter().chain(&other.0).cloned().collect::>(); return Ok(Transform(result)); } - - // For matched transform lists. - { - if this.len() == other.len() { - let is_matched_transforms = this.iter().zip(other).all(|(this, other)| { - is_matched_operation(this, other) - }); - - if is_matched_transforms { - return animate_equal_lists(this, other); - } - } - } - - // For mismatched transform lists. - let mut owned_this = this.clone(); - let mut owned_other = other.clone(); - - if this.is_empty() { - let this = other_.to_animated_zero()?.0; - if this.iter().zip(other).all(|(this, other)| is_matched_operation(this, other)) { - return animate_equal_lists(&this, other) - } - owned_this = this; - } - if other.is_empty() { - let other = self.to_animated_zero()?.0; - if this.iter().zip(&other).all(|(this, other)| is_matched_operation(this, other)) { - return animate_equal_lists(this, &other) - } - owned_other = other; - } - // https://drafts.csswg.org/css-transforms-1/#transform-transform-neutral-extend-animation - fn match_operations_if_possible( - this: &mut Vec, - other: &mut Vec, - ) -> Result<(), ()> { + fn match_operations_if_possible<'a>( + this: &mut Cow<'a, Vec>, + other: &mut Cow<'a, Vec>, + ) -> bool { if !this.iter().zip(other.iter()).all(|(this, other)| is_matched_operation(this, other)) { - return Err(()); + return false; } if this.len() == other.len() { - return Ok(()) + return true; } - let (shorter, longer) = if this.len() < other.len() { (this, other) } else { (other, this) }; + let (shorter, longer) = + if this.len() < other.len() { + (this.to_mut(), other) + } else { + (other.to_mut(), this) + }; + shorter.reserve(longer.len()); for op in longer.iter().skip(shorter.len()) { - shorter.push(op.to_animated_zero()?); + shorter.push(op.to_animated_zero().unwrap()); } - Ok(()) - }; - if match_operations_if_possible(&mut owned_this, &mut owned_other).is_ok() { - return animate_equal_lists(&owned_this, &owned_other) + // The resulting operations won't be matched regardless if the + // extended component is already InterpolateMatrix / + // AccumulateMatrix. + // + // Otherwise they should be matching operations all the time. + let already_mismatched = matches!( + longer[0], + TransformOperation::InterpolateMatrix { .. } | + TransformOperation::AccumulateMatrix { .. } + ); + + debug_assert_eq!( + !already_mismatched, + longer.iter().zip(shorter.iter()).all(|(this, other)| is_matched_operation(this, other)), + "ToAnimatedZero should generate matched operations" + ); + + !already_mismatched + } + + let mut this = Cow::Borrowed(&self.0); + let mut other = Cow::Borrowed(&other.0); + + if match_operations_if_possible(&mut this, &mut other) { + return Ok(Transform( + this.iter().zip(other.iter()) + .map(|(this, other)| this.animate(other, procedure)) + .collect::, _>>()? + )); } match procedure { Procedure::Add => Err(()), Procedure::Interpolate { progress } => { Ok(Transform(vec![TransformOperation::InterpolateMatrix { - from_list: Transform(owned_this), - to_list: Transform(owned_other), + from_list: Transform(this.into_owned()), + to_list: Transform(other.into_owned()), progress: Percentage(progress as f32), }])) }, Procedure::Accumulate { count } => { Ok(Transform(vec![TransformOperation::AccumulateMatrix { - from_list: Transform(owned_this), - to_list: Transform(owned_other), + from_list: Transform(this.into_owned()), + to_list: Transform(other.into_owned()), count: cmp::min(count, i32::max_value() as u64) as i32, }])) },