Test LCCR change. try: -b do -p linux64 -u all[linux64-qr] -t none
authorGlenn Watson <gwatson@mozilla.com>
Fri, 22 Sep 2017 09:29:02 +1000
changeset 1300827 3b88c7245af9af6976d639f5bddac6096ad3c55e
parent 1300600 ca7d18dbacbf103d74a3213d8d08a7c3e4def9a2
child 1578488 bb0dc7ecf7285d0184cbf2310f89d0a7af990e1d
push id223178
push usergwatson@mozilla.com
push dateThu, 21 Sep 2017 23:29:51 +0000
treeherdertry@3b88c7245af9 [default view] [failures only]
milestone58.0a1
Test LCCR change. try: -b do -p linux64 -u all[linux64-qr] -t none
gfx/webrender/src/clip_scroll_node.rs
gfx/webrender/src/util.rs
--- a/gfx/webrender/src/clip_scroll_node.rs
+++ b/gfx/webrender/src/clip_scroll_node.rs
@@ -265,19 +265,29 @@ impl ClipScrollNode {
 
     pub fn update_transform(&mut self, state: &TransformUpdateState) {
         let scrolled_parent_combined_clip = state
             .parent_combined_viewport_rect
             .translate(&-state.parent_scroll_offset);
 
         let (local_transform, accumulated_scroll_offset) = match self.node_type {
             NodeType::ReferenceFrame(ref info) => {
-                self.combined_local_viewport_rect = info.transform
-                    .with_destination::<LayerPixel>()
-                    .inverse_rect_footprint(&scrolled_parent_combined_clip);
+                // If current transform or parent transform has perspective component, then we
+                // shouldn't transform the LCCR by this transform because we only consider 2d
+                // component for LCCR. Once the perspective component is presence, the LCCR
+                // would be wrong.
+                self.combined_local_viewport_rect =
+                    if info.transform.has_perspective_component() ||
+                       state.parent_reference_frame_transform.has_perspective_component() {
+                        scrolled_parent_combined_clip.intersection(&self.local_clip_rect)
+                                                     .unwrap_or(LayerRect::zero())
+                    } else {
+                        info.transform.with_destination::<LayerPixel>()
+                                 .inverse_rect_footprint(&scrolled_parent_combined_clip)
+                    };
                 self.reference_frame_relative_scroll_offset = LayerVector2D::zero();
                 (info.transform, state.parent_accumulated_scroll_offset)
             }
             NodeType::Clip(_) | NodeType::ScrollFrame(_) => {
                 // Move the parent's viewport into the local space (of the node origin)
                 // and intersect with the local clip rectangle to get the local viewport.
                 self.combined_local_viewport_rect = scrolled_parent_combined_clip
                     .intersection(&self.local_clip_rect)
--- a/gfx/webrender/src/util.rs
+++ b/gfx/webrender/src/util.rs
@@ -13,16 +13,17 @@ use std::f32::consts::FRAC_1_SQRT_2;
 // Matches the definition of SK_ScalarNearlyZero in Skia.
 const NEARLY_ZERO: f32 = 1.0 / 4096.0;
 
 // TODO: Implement these in euclid!
 pub trait MatrixHelpers<Src, Dst> {
     fn transform_rect(&self, rect: &TypedRect<f32, Src>) -> TypedRect<f32, Dst>;
     fn is_identity(&self) -> bool;
     fn preserves_2d_axis_alignment(&self) -> bool;
+    fn has_perspective_component(&self) -> bool;
     fn inverse_project(&self, target: &TypedPoint2D<f32, Dst>) -> Option<TypedPoint2D<f32, Src>>;
     fn inverse_rect_footprint(&self, rect: &TypedRect<f32, Dst>) -> TypedRect<f32, Src>;
 }
 
 impl<Src, Dst> MatrixHelpers<Src, Dst> for TypedTransform3D<f32, Src, Dst> {
     fn transform_rect(&self, rect: &TypedRect<f32, Src>) -> TypedRect<f32, Dst> {
         let top_left = self.transform_point2d(&rect.origin);
         let top_right = self.transform_point2d(&rect.top_right());
@@ -62,16 +63,20 @@ impl<Src, Dst> MatrixHelpers<Src, Dst> f
         if self.m22.abs() > NEARLY_ZERO {
             col1 += 1;
             row1 += 1;
         }
 
         col0 < 2 && col1 < 2 && row0 < 2 && row1 < 2
     }
 
+    fn has_perspective_component(&self) -> bool {
+         self.m14 != 0.0 || self.m24 != 0.0 || self.m34 != 0.0 || self.m44 != 1.0
+    }
+
     fn inverse_project(&self, target: &TypedPoint2D<f32, Dst>) -> Option<TypedPoint2D<f32, Src>> {
         let m: TypedTransform2D<f32, Src, Dst>;
         m = TypedTransform2D::column_major(
             self.m11 - target.x * self.m14,
             self.m21 - target.x * self.m24,
             self.m41 - target.x * self.m44,
             self.m12 - target.y * self.m14,
             self.m22 - target.y * self.m24,