Bug 1521689 - Reduce invalidations caused by world clip rects. r=emilio
authorGlenn Watson <github@intuitionlibrary.com>
Wed, 23 Jan 2019 03:47:21 +0000
changeset 514948 221f90b839ec18b16a58bd24f7827f4c51dfca48
parent 514947 4c5506d94111dc00ed8bfa200d82606e5d5aab3a
child 514949 bde038bd29375b06804a4a6a899779a63b852be0
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1521689
milestone66.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
Bug 1521689 - Reduce invalidations caused by world clip rects. r=emilio Differential Revision: https://phabricator.services.mozilla.com/D17206
gfx/wr/webrender/src/clip_scroll_tree.rs
gfx/wr/webrender/src/picture.rs
--- a/gfx/wr/webrender/src/clip_scroll_tree.rs
+++ b/gfx/wr/webrender/src/clip_scroll_tree.rs
@@ -160,16 +160,37 @@ impl ClipScrollTree {
 
         if inverse {
             transform.inverse()
         } else {
             Some(transform)
         }
     }
 
+    /// Returns true if the spatial node is the same as the parent, or is
+    /// a child of the parent.
+    pub fn is_same_or_child_of(
+        &self,
+        spatial_node_index: SpatialNodeIndex,
+        parent_spatial_node_index: SpatialNodeIndex,
+    ) -> bool {
+        let mut index = spatial_node_index;
+
+        loop {
+            if index == parent_spatial_node_index {
+                return true;
+            }
+
+            index = match self.spatial_nodes[index.0 as usize].parent {
+                Some(parent) => parent,
+                None => return false,
+            }
+        }
+    }
+
     /// The root reference frame, which is the true root of the ClipScrollTree. Initially
     /// this ID is not valid, which is indicated by ```spatial_nodes``` being empty.
     pub fn root_reference_frame_index(&self) -> SpatialNodeIndex {
         // TODO(mrobinson): We should eventually make this impossible to misuse.
         debug_assert!(!self.spatial_nodes.is_empty());
         ROOT_SPATIAL_NODE_INDEX
     }
 
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -1153,24 +1153,37 @@ impl TileCache {
                                 world_clip_rect = world_clip_rect
                                     .intersection(&clip_world_rect)
                                     .unwrap_or(WorldRect::zero());
 
                                 // If the clip rect is in the same spatial node, it can be handled by the
                                 // local clip rect.
                                 if clip_chain_node.spatial_node_index == prim_instance.spatial_node_index {
                                     culling_rect = culling_rect.intersection(&local_clip_rect).unwrap_or(LayoutRect::zero());
-                                } else {
+
+                                    false
+                                } else if !clip_scroll_tree.is_same_or_child_of(
+                                    clip_chain_node.spatial_node_index,
+                                    self.spatial_node_index,
+                                ) {
+                                    // If the clip node is *not* a child of the main scroll root,
+                                    // add it to the list of potential world clips to be checked later.
+                                    // If it *is* a child of the main scroll root, then just track
+                                    // it as a normal clip dependency, since it likely moves in
+                                    // the same way as the primitive when scrolling (and if it doesn't,
+                                    // we want to invalidate and rasterize).
                                     world_clips.push((
                                         clip_world_rect.into(),
                                         clip_chain_node.spatial_node_index,
                                     ));
+
+                                    false
+                                } else {
+                                    true
                                 }
-
-                                false
                             }
                             None => {
                                 true
                             }
                         }
                     } else {
                         true
                     }