mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Break TraversalFlags::ForReconstruct down into several independent pieces.
These will be useful in followup work. MozReview-Commit-ID: Dyp9R0PG36v
This commit is contained in:
parent
5c6d3b820e
commit
6148db670b
3 changed files with 41 additions and 30 deletions
|
@ -302,8 +302,8 @@ trait PrivateMatchMethods: TElement {
|
||||||
new_values: &Arc<ComputedValues>,
|
new_values: &Arc<ComputedValues>,
|
||||||
pseudo: Option<&PseudoElement>)
|
pseudo: Option<&PseudoElement>)
|
||||||
-> ChildCascadeRequirement {
|
-> ChildCascadeRequirement {
|
||||||
// Don't accumulate damage if we're in a restyle for reconstruction.
|
// Don't accumulate damage if we're in a forgetful traversal.
|
||||||
if shared_context.traversal_flags.contains(traversal_flags::ForReconstruct) {
|
if shared_context.traversal_flags.contains(traversal_flags::Forgetful) {
|
||||||
return ChildCascadeRequirement::MustCascadeChildren;
|
return ChildCascadeRequirement::MustCascadeChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,8 +499,8 @@ pub trait MatchMethods : TElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't accumulate damage if we're in a restyle for reconstruction.
|
// Don't accumulate damage if we're in a forgetful traversal.
|
||||||
if context.shared.traversal_flags.contains(traversal_flags::ForReconstruct) {
|
if context.shared.traversal_flags.contains(traversal_flags::Forgetful) {
|
||||||
return ChildCascadeRequirement::MustCascadeChildren;
|
return ChildCascadeRequirement::MustCascadeChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -170,11 +170,6 @@ pub trait DomTraversal<E: TElement> : Sync {
|
||||||
shared_context: &SharedStyleContext,
|
shared_context: &SharedStyleContext,
|
||||||
traversal_flags: TraversalFlags
|
traversal_flags: TraversalFlags
|
||||||
) -> PreTraverseToken {
|
) -> PreTraverseToken {
|
||||||
debug_assert!(!(traversal_flags.contains(traversal_flags::ForReconstruct) &&
|
|
||||||
traversal_flags.contains(traversal_flags::UnstyledChildrenOnly)),
|
|
||||||
"must not specify FOR_RECONSTRUCT in combination with \
|
|
||||||
UNSTYLED_CHILDREN_ONLY");
|
|
||||||
|
|
||||||
if traversal_flags.contains(traversal_flags::UnstyledChildrenOnly) {
|
if traversal_flags.contains(traversal_flags::UnstyledChildrenOnly) {
|
||||||
if root.borrow_data().map_or(true, |d| d.has_styles() && d.styles.is_display_none()) {
|
if root.borrow_data().map_or(true, |d| d.has_styles() && d.styles.is_display_none()) {
|
||||||
return PreTraverseToken {
|
return PreTraverseToken {
|
||||||
|
@ -314,9 +309,11 @@ pub trait DomTraversal<E: TElement> : Sync {
|
||||||
// to traverse any element with damage so that we can perform fixup /
|
// to traverse any element with damage so that we can perform fixup /
|
||||||
// reconstruction on our way back up the tree.
|
// reconstruction on our way back up the tree.
|
||||||
//
|
//
|
||||||
// We also need to traverse nodes with explicit damage and no other
|
// In aggressively forgetful traversals (where we seek out and clear damage
|
||||||
// restyle data, so that this damage can be cleared.
|
// in addition to not computing it) we also need to traverse nodes with
|
||||||
if (cfg!(feature = "servo") || traversal_flags.contains(traversal_flags::ForReconstruct)) &&
|
// explicit damage and no other restyle data, so that this damage can be cleared.
|
||||||
|
if (cfg!(feature = "servo") ||
|
||||||
|
traversal_flags.contains(traversal_flags::AggressivelyForgetful)) &&
|
||||||
!data.restyle.damage.is_empty() {
|
!data.restyle.damage.is_empty() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -566,7 +563,6 @@ where
|
||||||
// * We generated a reconstruct hint on self (which could mean that we
|
// * We generated a reconstruct hint on self (which could mean that we
|
||||||
// switched from display:none to something else, which means the children
|
// switched from display:none to something else, which means the children
|
||||||
// need initial styling).
|
// need initial styling).
|
||||||
// * This is a reconstruct traversal.
|
|
||||||
// * This is a servo non-incremental traversal.
|
// * This is a servo non-incremental traversal.
|
||||||
//
|
//
|
||||||
// Additionally, there are a few scenarios where we avoid traversing the
|
// Additionally, there are a few scenarios where we avoid traversing the
|
||||||
|
@ -576,7 +572,6 @@ where
|
||||||
!propagated_hint.is_empty() ||
|
!propagated_hint.is_empty() ||
|
||||||
context.thread_local.is_initial_style() ||
|
context.thread_local.is_initial_style() ||
|
||||||
data.restyle.reconstructed_self() ||
|
data.restyle.reconstructed_self() ||
|
||||||
flags.contains(traversal_flags::ForReconstruct) ||
|
|
||||||
is_servo_nonincremental_layout();
|
is_servo_nonincremental_layout();
|
||||||
|
|
||||||
traverse_children = traverse_children &&
|
traverse_children = traverse_children &&
|
||||||
|
@ -594,17 +589,18 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are in a restyle for reconstruction, drop the existing restyle
|
// If we are in a forgetful traversal, drop the existing restyle
|
||||||
// data here, since we won't need to perform a post-traversal to pick up
|
// data here, since we won't need to perform a post-traversal to pick up
|
||||||
// any change hints.
|
// any change hints.
|
||||||
if context.shared.traversal_flags.contains(traversal_flags::ForReconstruct) {
|
if flags.contains(traversal_flags::Forgetful) {
|
||||||
data.clear_restyle_state();
|
data.clear_restyle_state();
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are two cases when we want to clear the dity descendants bit here
|
// There are two cases when we want to clear the dity descendants bit here
|
||||||
// after styling this element.
|
// after styling this element. The first case is when we were explicitly
|
||||||
|
// asked to clear the bit by the caller.
|
||||||
//
|
//
|
||||||
// The first case is when this element is the root of a display:none
|
// The second case is when this element is the root of a display:none
|
||||||
// subtree, even if the style didn't change (since, if the style did change,
|
// subtree, even if the style didn't change (since, if the style did change,
|
||||||
// we'd have already cleared it above).
|
// we'd have already cleared it above).
|
||||||
//
|
//
|
||||||
|
@ -613,14 +609,16 @@ where
|
||||||
// moderately expensive). Instead, DOM implementations can unconditionally
|
// moderately expensive). Instead, DOM implementations can unconditionally
|
||||||
// set the dirty descendants bit on any styled parent, and let the traversal
|
// set the dirty descendants bit on any styled parent, and let the traversal
|
||||||
// sort it out.
|
// sort it out.
|
||||||
//
|
if flags.contains(traversal_flags::ClearDirtyDescendants) ||
|
||||||
// The second case is when we are in a restyle for reconstruction, where we
|
data.styles.is_display_none() {
|
||||||
// won't need to perform a post-traversal to pick up any change hints.
|
|
||||||
if data.styles.is_display_none() ||
|
|
||||||
context.shared.traversal_flags.contains(traversal_flags::ForReconstruct) {
|
|
||||||
unsafe { element.unset_dirty_descendants(); }
|
unsafe { element.unset_dirty_descendants(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Similarly, check if we're supposed to clear the animation bit.
|
||||||
|
if flags.contains(traversal_flags::ClearAnimationOnlyDirtyDescendants) {
|
||||||
|
unsafe { element.unset_animation_only_dirty_descendants(); }
|
||||||
|
}
|
||||||
|
|
||||||
context.thread_local.end_element(element);
|
context.thread_local.end_element(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,10 +775,9 @@ where
|
||||||
// Set the dirty descendants bit on the parent as needed, so that we
|
// Set the dirty descendants bit on the parent as needed, so that we
|
||||||
// can find elements during the post-traversal.
|
// can find elements during the post-traversal.
|
||||||
//
|
//
|
||||||
// If we are in a restyle for reconstruction, there is no need to
|
// Note that these bits may be cleared again at the bottom of
|
||||||
// perform a post-traversal, so we don't need to set the dirty
|
// recalc_style_at if requested by the caller.
|
||||||
// descendants bit on the parent.
|
if !is_initial_style {
|
||||||
if !flags.contains(traversal_flags::ForReconstruct) && !is_initial_style {
|
|
||||||
if flags.for_animation_only() {
|
if flags.for_animation_only() {
|
||||||
unsafe { element.set_animation_only_dirty_descendants(); }
|
unsafe { element.set_animation_only_dirty_descendants(); }
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,8 +18,18 @@ bitflags! {
|
||||||
const ForCSSRuleChanges = 1 << 1,
|
const ForCSSRuleChanges = 1 << 1,
|
||||||
/// Traverse only unstyled children of the root and their descendants.
|
/// Traverse only unstyled children of the root and their descendants.
|
||||||
const UnstyledChildrenOnly = 1 << 2,
|
const UnstyledChildrenOnly = 1 << 2,
|
||||||
/// FIXME(bholley): This will go away.
|
/// A forgetful traversal ignores the previous state of the frame tree, and
|
||||||
const ForReconstruct = 1 << 3,
|
/// thus does not compute damage or maintain other state describing the styles
|
||||||
|
/// pre-traversal. A forgetful traversal is usually the right thing if you
|
||||||
|
/// aren't going to do a post-traversal.
|
||||||
|
const Forgetful = 1 << 3,
|
||||||
|
/// Actively seeks out and clears change hints that may have been posted into
|
||||||
|
/// the tree. Nonsensical without also passing Forgetful.
|
||||||
|
const AggressivelyForgetful = 1 << 4,
|
||||||
|
/// Clears the dirty descendants bit in the subtree.
|
||||||
|
const ClearDirtyDescendants = 1 << 5,
|
||||||
|
/// Clears the animation-only dirty descendants bit in the subtree.
|
||||||
|
const ClearAnimationOnlyDirtyDescendants = 1 << 6,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +56,11 @@ pub fn assert_traversal_flags_match() {
|
||||||
ServoTraversalFlags_AnimationOnly => AnimationOnly,
|
ServoTraversalFlags_AnimationOnly => AnimationOnly,
|
||||||
ServoTraversalFlags_ForCSSRuleChanges => ForCSSRuleChanges,
|
ServoTraversalFlags_ForCSSRuleChanges => ForCSSRuleChanges,
|
||||||
ServoTraversalFlags_UnstyledChildrenOnly => UnstyledChildrenOnly,
|
ServoTraversalFlags_UnstyledChildrenOnly => UnstyledChildrenOnly,
|
||||||
ServoTraversalFlags_ForReconstruct => ForReconstruct,
|
ServoTraversalFlags_Forgetful => Forgetful,
|
||||||
|
ServoTraversalFlags_AggressivelyForgetful => AggressivelyForgetful,
|
||||||
|
ServoTraversalFlags_ClearDirtyDescendants => ClearDirtyDescendants,
|
||||||
|
ServoTraversalFlags_ClearAnimationOnlyDirtyDescendants =>
|
||||||
|
ClearAnimationOnlyDirtyDescendants,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue