From 5286869b9626bc073cda68d11d5462cd2a27466d Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Thu, 26 Jun 2025 16:10:48 +0200 Subject: [PATCH] layout: Start using the new extensible `RestyleDamage` type from Stylo (#37592) This will allow Servo to add custom types of damage in the near future which correspond to minor phases layout. The damage exposed by Stylo only corresponds to the major layout phses. In the future, both phases will likely be managed by Servo itself and implementors will need to provide their own damage system entirely. Testing: This shouldn't change behavior and thus is covered by existing tests. Stylo PR: https://github.com/servo/stylo/pull/207 Signed-off-by: Martin Robinson Co-authored-by: Oriol Brufau --- Cargo.lock | 36 +++++++++++------------ components/layout/layout_impl.rs | 4 +-- components/layout/traversal.rs | 21 +++++++------ components/script/layout_dom/element.rs | 12 +++++--- components/shared/layout/layout_damage.rs | 16 ++++++++++ components/shared/layout/lib.rs | 2 ++ 6 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 components/shared/layout/layout_damage.rs diff --git a/Cargo.lock b/Cargo.lock index a0f0924370e..00f117f49d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2384,7 +2384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3003,7 +3003,7 @@ dependencies = [ "gobject-sys", "libc", "system-deps", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4507,7 +4507,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi 0.5.0", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6900,7 +6900,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6913,7 +6913,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -7226,7 +7226,7 @@ dependencies = [ [[package]] name = "selectors" version = "0.29.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "bitflags 2.9.1", "cssparser", @@ -7532,7 +7532,7 @@ dependencies = [ [[package]] name = "servo_arc" version = "0.4.1" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "serde", "stable_deref_trait", @@ -7994,7 +7994,7 @@ dependencies = [ [[package]] name = "stylo" version = "0.4.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "app_units", "arrayvec", @@ -8051,7 +8051,7 @@ dependencies = [ [[package]] name = "stylo_atoms" version = "0.4.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "string_cache", "string_cache_codegen", @@ -8060,12 +8060,12 @@ dependencies = [ [[package]] name = "stylo_config" version = "0.4.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" [[package]] name = "stylo_derive" version = "0.4.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "darling", "proc-macro2", @@ -8077,7 +8077,7 @@ dependencies = [ [[package]] name = "stylo_dom" version = "0.4.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "bitflags 2.9.1", "stylo_malloc_size_of", @@ -8086,7 +8086,7 @@ dependencies = [ [[package]] name = "stylo_malloc_size_of" version = "0.4.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "app_units", "cssparser", @@ -8103,12 +8103,12 @@ dependencies = [ [[package]] name = "stylo_static_prefs" version = "0.4.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" [[package]] name = "stylo_traits" version = "0.4.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "app_units", "bitflags 2.9.1", @@ -8291,7 +8291,7 @@ dependencies = [ "getrandom 0.2.16", "once_cell", "rustix 0.38.44", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -8525,7 +8525,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "to_shmem" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "cssparser", "servo_arc", @@ -8538,7 +8538,7 @@ dependencies = [ [[package]] name = "to_shmem_derive" version = "0.1.0" -source = "git+https://github.com/servo/stylo?branch=2025-06-03#2e1f66b06836428e4b29dd8144c72432c97ff316" +source = "git+https://github.com/servo/stylo?branch=2025-06-03#da53c540faa7dd5556c6718d4644a6e957947893" dependencies = [ "darling", "proc-macro2", diff --git a/components/layout/layout_impl.rs b/components/layout/layout_impl.rs index 8ca01d391d4..e95fe213b43 100644 --- a/components/layout/layout_impl.rs +++ b/components/layout/layout_impl.rs @@ -840,8 +840,8 @@ impl LayoutThread { let mut damage = compute_damage_and_repair_style(layout_context.shared_context(), root_node); if viewport_changed { - damage = RestyleDamage::REBUILD_BOX; - } else if !damage.contains(RestyleDamage::REBUILD_BOX) { + damage = RestyleDamage::RELAYOUT; + } else if !damage.contains(RestyleDamage::RELAYOUT) { layout_context.style_context.stylist.rule_tree().maybe_gc(); return damage; } diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index f8d24dfb489..9f13504c8b6 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -104,8 +104,7 @@ pub(crate) fn compute_damage_and_repair_style_inner( node: ServoLayoutNode<'_>, parent_restyle_damage: RestyleDamage, ) -> RestyleDamage { - let original_damage; - let damage; + let element_damage; { let mut element_data = node @@ -114,28 +113,28 @@ pub(crate) fn compute_damage_and_repair_style_inner( .element_data .borrow_mut(); - original_damage = std::mem::take(&mut element_data.damage); - damage = original_damage | parent_restyle_damage; + element_damage = std::mem::take(&mut element_data.damage); if let Some(ref style) = element_data.styles.primary { if style.get_box().display == Display::None { - return damage; + return element_damage | parent_restyle_damage; } } } - let mut propagated_damage = damage; + let element_and_parent_damage = element_damage | parent_restyle_damage; + let mut damage_from_children = RestyleDamage::empty(); for child in iter_child_nodes(node) { if child.is_element() { - propagated_damage |= compute_damage_and_repair_style_inner(context, child, damage); + damage_from_children |= + compute_damage_and_repair_style_inner(context, child, element_and_parent_damage); } } - if !propagated_damage.contains(RestyleDamage::REBUILD_BOX) && - !original_damage.contains(RestyleDamage::REBUILD_BOX) - { + let damage_for_parent = damage_from_children | element_and_parent_damage; + if !damage_for_parent.contains(RestyleDamage::RELAYOUT) && !element_damage.is_empty() { node.repair_style(context); } - propagated_damage + damage_for_parent } diff --git a/components/script/layout_dom/element.rs b/components/script/layout_dom/element.rs index 738975d9631..c5cbd563fcc 100644 --- a/components/script/layout_dom/element.rs +++ b/components/script/layout_dom/element.rs @@ -11,7 +11,7 @@ use embedder_traits::UntrustedNodeAddress; use html5ever::{LocalName, Namespace, local_name, ns}; use js::jsapi::JSObject; use layout_api::wrapper_traits::{LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode}; -use layout_api::{LayoutNodeType, StyleData}; +use layout_api::{LayoutDamage, LayoutNodeType, StyleData}; use selectors::Element as _; use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint}; use selectors::bloom::{BLOOM_HASH_MASK, BloomFilter}; @@ -26,10 +26,10 @@ use style::bloom::each_relevant_element_hash; use style::context::SharedStyleContext; use style::data::ElementData; use style::dom::{DomChildren, LayoutIterator, TDocument, TElement, TNode, TShadowRoot}; -use style::properties::PropertyDeclarationBlock; +use style::properties::{ComputedValues, PropertyDeclarationBlock}; use style::selector_parser::{ - AttrValue as SelectorAttrValue, Lang, NonTSPseudoClass, PseudoElement, SelectorImpl, - extended_filtering, + AttrValue as SelectorAttrValue, Lang, NonTSPseudoClass, PseudoElement, RestyleDamage, + SelectorImpl, extended_filtering, }; use style::shared_lock::Locked as StyleLocked; use style::stylesheets::scope_rule::ImplicitScopeRoot; @@ -554,6 +554,10 @@ impl<'dom> style::dom::TElement for ServoLayoutElement<'dom> { ) } } + + fn compute_layout_damage(_old: &ComputedValues, _new: &ComputedValues) -> RestyleDamage { + RestyleDamage::from_bits_retain(LayoutDamage::REBUILD_BOX.bits()) + } } impl<'dom> ::selectors::Element for ServoLayoutElement<'dom> { diff --git a/components/shared/layout/layout_damage.rs b/components/shared/layout/layout_damage.rs new file mode 100644 index 00000000000..0b1ebe7931c --- /dev/null +++ b/components/shared/layout/layout_damage.rs @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use bitflags::bitflags; + +bitflags! { + /// Individual layout actions that may be necessary after restyling. This is an extension + /// of `RestyleDamage` from stylo, which only uses the 4 lower bits. + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub struct LayoutDamage: u16 { + /// Rebuild the entire box for this element, which means that every part of layout + /// needs to happena again. + const REBUILD_BOX = 0b111111111111 << 4; + } +} diff --git a/components/shared/layout/lib.rs b/components/shared/layout/lib.rs index 42b9f6b5f64..8b1f6009dee 100644 --- a/components/shared/layout/lib.rs +++ b/components/shared/layout/lib.rs @@ -8,6 +8,7 @@ #![deny(unsafe_code)] +mod layout_damage; pub mod wrapper_traits; use std::any::Any; @@ -28,6 +29,7 @@ use fnv::FnvHashMap; use fonts::{FontContext, SystemFontServiceProxy}; use fxhash::FxHashMap; use ipc_channel::ipc::IpcSender; +pub use layout_damage::LayoutDamage; use libc::c_void; use malloc_size_of::{MallocSizeOf as MallocSizeOfTrait, MallocSizeOfOps, malloc_size_of_is_0}; use malloc_size_of_derive::MallocSizeOf;