mirror of
https://github.com/servo/servo.git
synced 2025-06-06 00:25:37 +00:00
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 <obrufau@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
1f5087d773
commit
d18000fee8
5 changed files with 78 additions and 22 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -6507,7 +6507,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "selectors"
|
name = "selectors"
|
||||||
version = "0.28.0"
|
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 = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"cssparser",
|
"cssparser",
|
||||||
|
@ -6802,7 +6802,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "servo_arc"
|
name = "servo_arc"
|
||||||
version = "0.4.1"
|
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 = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
|
@ -7247,7 +7247,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo"
|
name = "stylo"
|
||||||
version = "0.3.0"
|
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 = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
|
@ -7305,7 +7305,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_atoms"
|
name = "stylo_atoms"
|
||||||
version = "0.3.0"
|
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 = [
|
dependencies = [
|
||||||
"string_cache",
|
"string_cache",
|
||||||
"string_cache_codegen",
|
"string_cache_codegen",
|
||||||
|
@ -7314,12 +7314,12 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_config"
|
name = "stylo_config"
|
||||||
version = "0.3.0"
|
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]]
|
[[package]]
|
||||||
name = "stylo_derive"
|
name = "stylo_derive"
|
||||||
version = "0.3.0"
|
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 = [
|
dependencies = [
|
||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -7331,7 +7331,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_dom"
|
name = "stylo_dom"
|
||||||
version = "0.3.0"
|
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 = [
|
dependencies = [
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
"stylo_malloc_size_of",
|
"stylo_malloc_size_of",
|
||||||
|
@ -7340,7 +7340,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_malloc_size_of"
|
name = "stylo_malloc_size_of"
|
||||||
version = "0.3.0"
|
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 = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"cssparser",
|
"cssparser",
|
||||||
|
@ -7357,12 +7357,12 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stylo_static_prefs"
|
name = "stylo_static_prefs"
|
||||||
version = "0.3.0"
|
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]]
|
[[package]]
|
||||||
name = "stylo_traits"
|
name = "stylo_traits"
|
||||||
version = "0.3.0"
|
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 = [
|
dependencies = [
|
||||||
"app_units",
|
"app_units",
|
||||||
"bitflags 2.9.1",
|
"bitflags 2.9.1",
|
||||||
|
@ -7745,7 +7745,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "to_shmem"
|
name = "to_shmem"
|
||||||
version = "0.2.0"
|
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 = [
|
dependencies = [
|
||||||
"cssparser",
|
"cssparser",
|
||||||
"servo_arc",
|
"servo_arc",
|
||||||
|
@ -7758,7 +7758,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "to_shmem_derive"
|
name = "to_shmem_derive"
|
||||||
version = "0.1.0"
|
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 = [
|
dependencies = [
|
||||||
"darling",
|
"darling",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
|
@ -646,7 +646,7 @@ impl LayoutThread {
|
||||||
highlighted_dom_node: reflow_request.highlighted_dom_node,
|
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,
|
&reflow_request,
|
||||||
root_element,
|
root_element,
|
||||||
rayon_pool,
|
rayon_pool,
|
||||||
|
@ -654,7 +654,7 @@ impl LayoutThread {
|
||||||
viewport_changed,
|
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.build_display_list(&reflow_request, &mut layout_context);
|
||||||
|
|
||||||
self.first_reflow.set(false);
|
self.first_reflow.set(false);
|
||||||
|
@ -744,7 +744,7 @@ impl LayoutThread {
|
||||||
rayon_pool: Option<&ThreadPool>,
|
rayon_pool: Option<&ThreadPool>,
|
||||||
layout_context: &mut LayoutContext<'_>,
|
layout_context: &mut LayoutContext<'_>,
|
||||||
viewport_changed: bool,
|
viewport_changed: bool,
|
||||||
) -> bool {
|
) -> RestyleDamage {
|
||||||
let dirty_root = unsafe {
|
let dirty_root = unsafe {
|
||||||
ServoLayoutNode::new(&reflow_request.dirty_root.unwrap())
|
ServoLayoutNode::new(&reflow_request.dirty_root.unwrap())
|
||||||
.as_element()
|
.as_element()
|
||||||
|
@ -760,7 +760,7 @@ impl LayoutThread {
|
||||||
|
|
||||||
if !token.should_traverse() {
|
if !token.should_traverse() {
|
||||||
layout_context.style_context.stylist.rule_tree().maybe_gc();
|
layout_context.style_context.stylist.rule_tree().maybe_gc();
|
||||||
return false;
|
return RestyleDamage::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
let dirty_root: ServoLayoutNode =
|
let dirty_root: ServoLayoutNode =
|
||||||
|
@ -768,9 +768,9 @@ impl LayoutThread {
|
||||||
|
|
||||||
let root_node = root_element.as_node();
|
let root_node = root_element.as_node();
|
||||||
let damage = compute_damage_and_repair_style(layout_context.shared_context(), root_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();
|
layout_context.style_context.stylist.rule_tree().maybe_gc();
|
||||||
return false;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut box_tree = self.box_tree.borrow_mut();
|
let mut box_tree = self.box_tree.borrow_mut();
|
||||||
|
@ -828,10 +828,10 @@ impl LayoutThread {
|
||||||
|
|
||||||
// GC the rule tree if some heuristics are met.
|
// GC the rule tree if some heuristics are met.
|
||||||
layout_context.style_context.stylist.rule_tree().maybe_gc();
|
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() &&
|
if !reflow_request.reflow_goal.needs_display_list() &&
|
||||||
!reflow_request.reflow_goal.needs_display()
|
!reflow_request.reflow_goal.needs_display()
|
||||||
{
|
{
|
||||||
|
@ -840,7 +840,9 @@ impl LayoutThread {
|
||||||
let Some(fragment_tree) = &*self.fragment_tree.borrow() else {
|
let Some(fragment_tree) = &*self.fragment_tree.borrow() else {
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
node.repair_style(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
tests/wpt/meta/MANIFEST.json
vendored
13
tests/wpt/meta/MANIFEST.json
vendored
|
@ -119171,6 +119171,19 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"z-index-020.html": [
|
||||||
|
"34a7272a2541e779c487fe3501d6e6cd3f751f51",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"/css/reference/ref-filled-green-200px-square.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"z-index-abspos-001.xht": [
|
"z-index-abspos-001.xht": [
|
||||||
"63a44d15a7dce6e1a2df6124ff1064d0a68392ab",
|
"63a44d15a7dce6e1a2df6124ff1064d0a68392ab",
|
||||||
[
|
[
|
||||||
|
|
39
tests/wpt/tests/css/CSS2/zindex/z-index-020.html
vendored
Normal file
39
tests/wpt/tests/css/CSS2/zindex/z-index-020.html
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<title>CSS Test: z-index - dynamic changes</title>
|
||||||
|
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||||
|
<link rel="help" href="http://www.w3.org/TR/CSS21/visuren.html#z-index" />
|
||||||
|
<link rel="match" href="../../reference/ref-filled-green-200px-square.html">
|
||||||
|
<meta name="assert" content="Checks that z-index can be changed dynamically.">
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
#red {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
#target {
|
||||||
|
background: green;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
#target.front {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||||
|
|
||||||
|
<div id="red"></div>
|
||||||
|
<div id="target"></div>
|
||||||
|
|
||||||
|
<script src="/common/reftest-wait.js"></script>
|
||||||
|
<script src="/common/rendering-utils.js"></script>
|
||||||
|
<script>
|
||||||
|
waitForAtLeastOneFrame().then(() => {
|
||||||
|
document.getElementById("target").className = "front";
|
||||||
|
takeScreenshot();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue