servo: Merge #18591 - stylo: do not handle the fallback discrete animation inside the Animate trait (from chenpighead:stylo-singular-matrix-animation); r=BorisChiou
authorJeremy Chen <jeremychen@mozilla.com>
Thu, 21 Sep 2017 03:16:58 -0500
changeset 431696 e8fabb53ad00dbc94ad2f77d3d58dbe04ca34f22
parent 431695 8eba074485cc441037a82b2aae44013ff29ed372
child 431697 9044841344c9af963ed30293d8c5ecea0ee23845
push id7785
push userryanvm@gmail.com
push dateThu, 21 Sep 2017 13:39:55 +0000
treeherdermozilla-beta@06d4034a8a03 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBorisChiou
bugs18591, 1394284
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #18591 - stylo: do not handle the fallback discrete animation inside the Animate trait (from chenpighead:stylo-singular-matrix-animation); r=BorisChiou At present, we do the fallback discrete animation for non-invertible matrices in ComputedMatrix.animate(). However, according to the spec, we should fallback to discrete animation for cases like: 1. animation between transform with single non-invertible matrix 2. animation between transform with matched transform functions that have at least one non-invertible matrix 2. animation between transform with mismatched transform functions that have at least one non-invertible matrix. The current implementation only handles the first case. Moreover, we already have fallback discrete animation procedures in CSS Animation and Web Animation, so we should be able to not doing any fallback inside the Animate trait. In this patch, we let the animation between non-invertible matrices to return Err(). So, we can propagate the Err() to the callers, and let the fallback discrete animation procedure stay at the Servo_MatrixTransform_Operate, which is ouside the Animate trait. Gecko bug: [Bug 1394284](https://bugzilla.mozilla.org/show_bug.cgi?id=1394284) --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix [Bug 1394284](https://bugzilla.mozilla.org/show_bug.cgi?id=1394284) - [X] There are wpt tests for these changes, and thet will be landed in [Bug 1394284](https://bugzilla.mozilla.org/show_bug.cgi?id=1394284) Source-Repo: https://github.com/servo/servo Source-Revision: ce7cee75e4c0c8357b489be42589d96348870627
servo/components/style/properties/helpers/animated_properties.mako.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -1448,21 +1448,20 @@ impl Animate for ComputedMatrix {
     fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
         if self.is_3d() || other.is_3d() {
             let decomposed_from = decompose_3d_matrix(*self);
             let decomposed_to = decompose_3d_matrix(*other);
             match (decomposed_from, decomposed_to) {
                 (Ok(this), Ok(other)) => {
                     Ok(ComputedMatrix::from(this.animate(&other, procedure)?))
                 },
-                _ => {
-                    let (this_weight, other_weight) = procedure.weights();
-                    let result = if this_weight > other_weight { *self } else { *other };
-                    Ok(result)
-                },
+                // Matrices can be undecomposable due to couple reasons, e.g.,
+                // non-invertible matrices. In this case, we should report Err
+                // here, and let the caller do the fallback procedure.
+                _ => Err(())
             }
         } else {
             let this = MatrixDecomposed2D::from(*self);
             let other = MatrixDecomposed2D::from(*other);
             Ok(ComputedMatrix::from(this.animate(&other, procedure)?))
         }
     }
 
@@ -1472,21 +1471,20 @@ impl Animate for ComputedMatrix {
             (decompose_3d_matrix(*self), decompose_3d_matrix(*other))
         } else {
             (decompose_2d_matrix(self), decompose_2d_matrix(other))
         };
         match (from, to) {
             (Ok(from), Ok(to)) => {
                 Ok(ComputedMatrix::from(from.animate(&to, procedure)?))
             },
-            _ => {
-                let (this_weight, other_weight) = procedure.weights();
-                let result = if this_weight > other_weight { *self } else { *other };
-                Ok(result)
-            },
+            // Matrices can be undecomposable due to couple reasons, e.g.,
+            // non-invertible matrices. In this case, we should report Err here,
+            // and let the caller do the fallback procedure.
+            _ => Err(())
         }
     }
 }
 
 impl ComputeSquaredDistance for ComputedMatrix {
     #[inline]
     #[cfg(feature = "servo")]
     fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -2213,19 +2213,23 @@ pub extern "C" fn Servo_MatrixTransform_
     let from = ComputedMatrix::from(unsafe { from.as_ref() }.expect("not a valid 'from' matrix"));
     let to = ComputedMatrix::from(unsafe { to.as_ref() }.expect("not a valid 'to' matrix"));
     let result = match matrix_operator {
         Interpolate => from.animate(&to, Procedure::Interpolate { progress }),
         Accumulate => from.animate(&to, Procedure::Accumulate { count: progress as u64 }),
     };
 
     let output = unsafe { output.as_mut() }.expect("not a valid 'output' matrix");
-    if let Ok(result) =  result {
+    if let Ok(result) = result {
         *output = result.into();
-    };
+    } else if progress < 0.5 {
+        *output = from.clone().into();
+    } else {
+        *output = to.clone().into();
+    }
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_ParseStyleAttribute(data: *const nsACString,
                                             raw_extra_data: *mut URLExtraData,
                                             quirks_mode: nsCompatibility,
                                             loader: *mut Loader)
                                             -> RawServoDeclarationBlockStrong {