From d18000fee8d1f4ef95be21525b013ca5213f9d59 Mon Sep 17 00:00:00 2001 From: Oriol Brufau Date: Sat, 24 May 2025 01:40:02 +0200 Subject: [PATCH] Add another incremental layout that starts at stacking tree construction (#37088) This allows to skip rebuilding the box tree when it's only necessary to rebuild the stacking context tree. Bumps Stylo to https://github.com/servo/stylo/pull/187 Testing: Unneeded (no behavior change). Just improving performance. However, this adds a new test for dynamic changes of `z-index`, which we were breaking in an earlier iteration of this patch. Signed-off-by: Oriol Brufau Co-authored-by: Martin Robinson --- Cargo.lock | 24 ++++++------ components/layout/layout_impl.rs | 20 +++++----- components/layout/traversal.rs | 4 +- tests/wpt/meta/MANIFEST.json | 13 +++++++ .../tests/css/CSS2/zindex/z-index-020.html | 39 +++++++++++++++++++ 5 files changed, 78 insertions(+), 22 deletions(-) create mode 100644 tests/wpt/tests/css/CSS2/zindex/z-index-020.html diff --git a/Cargo.lock b/Cargo.lock index 3c735cf124c..e2503d2cde4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6507,7 +6507,7 @@ dependencies = [ [[package]] name = "selectors" version = "0.28.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "bitflags 2.9.1", "cssparser", @@ -6802,7 +6802,7 @@ dependencies = [ [[package]] name = "servo_arc" version = "0.4.1" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "serde", "stable_deref_trait", @@ -7247,7 +7247,7 @@ dependencies = [ [[package]] name = "stylo" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "app_units", "arrayvec", @@ -7305,7 +7305,7 @@ dependencies = [ [[package]] name = "stylo_atoms" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "string_cache", "string_cache_codegen", @@ -7314,12 +7314,12 @@ dependencies = [ [[package]] name = "stylo_config" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" [[package]] name = "stylo_derive" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "darling", "proc-macro2", @@ -7331,7 +7331,7 @@ dependencies = [ [[package]] name = "stylo_dom" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "bitflags 2.9.1", "stylo_malloc_size_of", @@ -7340,7 +7340,7 @@ dependencies = [ [[package]] name = "stylo_malloc_size_of" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "app_units", "cssparser", @@ -7357,12 +7357,12 @@ dependencies = [ [[package]] name = "stylo_static_prefs" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" [[package]] name = "stylo_traits" version = "0.3.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "app_units", "bitflags 2.9.1", @@ -7745,7 +7745,7 @@ dependencies = [ [[package]] name = "to_shmem" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "cssparser", "servo_arc", @@ -7758,7 +7758,7 @@ dependencies = [ [[package]] name = "to_shmem_derive" version = "0.1.0" -source = "git+https://github.com/servo/stylo?branch=2025-05-01#88b34ae4293ca7286584cee37bca1f58ab79a8cb" +source = "git+https://github.com/servo/stylo?branch=2025-05-01#1707256dd825f14e98161a49fdd6749f8ca0d506" dependencies = [ "darling", "proc-macro2", diff --git a/components/layout/layout_impl.rs b/components/layout/layout_impl.rs index 4ab69976671..3452c9a6e4c 100644 --- a/components/layout/layout_impl.rs +++ b/components/layout/layout_impl.rs @@ -646,7 +646,7 @@ impl LayoutThread { highlighted_dom_node: reflow_request.highlighted_dom_node, }; - let did_reflow = self.restyle_and_build_trees( + let damage = self.restyle_and_build_trees( &reflow_request, root_element, rayon_pool, @@ -654,7 +654,7 @@ impl LayoutThread { viewport_changed, ); - self.build_stacking_context_tree(&reflow_request, did_reflow); + self.build_stacking_context_tree(&reflow_request, damage); self.build_display_list(&reflow_request, &mut layout_context); self.first_reflow.set(false); @@ -744,7 +744,7 @@ impl LayoutThread { rayon_pool: Option<&ThreadPool>, layout_context: &mut LayoutContext<'_>, viewport_changed: bool, - ) -> bool { + ) -> RestyleDamage { let dirty_root = unsafe { ServoLayoutNode::new(&reflow_request.dirty_root.unwrap()) .as_element() @@ -760,7 +760,7 @@ impl LayoutThread { if !token.should_traverse() { layout_context.style_context.stylist.rule_tree().maybe_gc(); - return false; + return RestyleDamage::empty(); } let dirty_root: ServoLayoutNode = @@ -768,9 +768,9 @@ impl LayoutThread { let root_node = root_element.as_node(); let damage = compute_damage_and_repair_style(layout_context.shared_context(), root_node); - if !viewport_changed && (damage.is_empty() || damage == RestyleDamage::REPAINT) { + if !viewport_changed && !damage.contains(RestyleDamage::REBUILD_BOX) { layout_context.style_context.stylist.rule_tree().maybe_gc(); - return false; + return damage; } let mut box_tree = self.box_tree.borrow_mut(); @@ -828,10 +828,10 @@ impl LayoutThread { // GC the rule tree if some heuristics are met. layout_context.style_context.stylist.rule_tree().maybe_gc(); - true + damage } - fn build_stacking_context_tree(&self, reflow_request: &ReflowRequest, did_reflow: bool) { + fn build_stacking_context_tree(&self, reflow_request: &ReflowRequest, damage: RestyleDamage) { if !reflow_request.reflow_goal.needs_display_list() && !reflow_request.reflow_goal.needs_display() { @@ -840,7 +840,9 @@ impl LayoutThread { let Some(fragment_tree) = &*self.fragment_tree.borrow() else { return; }; - if !did_reflow && self.stacking_context_tree.borrow().is_some() { + if !damage.contains(RestyleDamage::REBUILD_STACKING_CONTEXT) && + self.stacking_context_tree.borrow().is_some() + { return; } diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index faf25dc170d..22faa4b1191 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -131,7 +131,9 @@ pub(crate) fn compute_damage_and_repair_style_inner( } } - if propagated_damage == RestyleDamage::REPAINT && original_damage == RestyleDamage::REPAINT { + if !propagated_damage.contains(RestyleDamage::REBUILD_BOX) && + !original_damage.contains(RestyleDamage::REBUILD_BOX) + { node.repair_style(context); } diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 8f64883c6be..59a4cc1cfd8 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -119171,6 +119171,19 @@ {} ] ], + "z-index-020.html": [ + "34a7272a2541e779c487fe3501d6e6cd3f751f51", + [ + null, + [ + [ + "/css/reference/ref-filled-green-200px-square.html", + "==" + ] + ], + {} + ] + ], "z-index-abspos-001.xht": [ "63a44d15a7dce6e1a2df6124ff1064d0a68392ab", [ diff --git a/tests/wpt/tests/css/CSS2/zindex/z-index-020.html b/tests/wpt/tests/css/CSS2/zindex/z-index-020.html new file mode 100644 index 00000000000..34a7272a254 --- /dev/null +++ b/tests/wpt/tests/css/CSS2/zindex/z-index-020.html @@ -0,0 +1,39 @@ + + +CSS Test: z-index - dynamic changes + + + + + + +

Test passes if there is a filled green square and no red.

+ +
+
+ + + + +