style: Get rid of unstyled children only traversals.

They're useless now, provided we remove the hack to not traverse XBL-bound
elements on initial styling.

Bug: 1418456
Reviewed-by: heycam
MozReview-Commit-ID: AvBVdyF1wb6
This commit is contained in:
Emilio Cobos Álvarez 2017-11-17 21:13:48 +01:00
parent 63bd783c55
commit b1fecea0aa
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
4 changed files with 18 additions and 80 deletions

View file

@ -557,11 +557,6 @@ pub trait TElement
!data.hint.has_animation_hint_or_recascade();
}
if traversal_flags.contains(TraversalFlags::UnstyledOnly) {
// We don't process invalidations in UnstyledOnly mode.
return data.has_styles();
}
if self.has_snapshot() && !self.handled_snapshot() {
return false;
}

View file

@ -146,13 +146,6 @@ pub trait DomTraversal<E: TElement> : Sync {
) -> PreTraverseToken<E> {
let traversal_flags = shared_context.traversal_flags;
// If this is an unstyled-only traversal, the caller has already verified
// that there's something to traverse, and we don't need to do any
// invalidation since we're not doing any restyling.
if traversal_flags.contains(TraversalFlags::UnstyledOnly) {
return PreTraverseToken(Some(root))
}
let mut data = root.mutate_data();
let mut data = data.as_mut().map(|d| &mut **d);
@ -208,11 +201,6 @@ pub trait DomTraversal<E: TElement> : Sync {
debug!("element_needs_traversal({:?}, {:?}, {:?})",
el, traversal_flags, data);
if traversal_flags.contains(TraversalFlags::UnstyledOnly) {
return data.map_or(true, |d| !d.has_styles()) || el.has_dirty_descendants();
}
// In case of animation-only traversal we need to traverse the element
// if the element has animation only dirty descendants bit,
// animation-only restyle hint or recascade.
@ -266,7 +254,6 @@ pub trait DomTraversal<E: TElement> : Sync {
&self,
context: &mut StyleContext<E>,
parent: E,
is_initial_style: bool,
parent_data: &ElementData,
) -> bool {
debug_assert!(cfg!(feature = "gecko") ||
@ -278,33 +265,6 @@ pub trait DomTraversal<E: TElement> : Sync {
return true;
}
// Gecko-only XBL handling.
//
// If we're computing initial styles and the parent has a Gecko XBL
// binding, that binding may inject anonymous children and remap the
// explicit children to an insertion point (or hide them entirely). It
// may also specify a scoped stylesheet, which changes the rules that
// apply within the subtree. These two effects can invalidate the result
// of property inheritance and selector matching (respectively) within
// the subtree.
//
// To avoid wasting work, we defer initial styling of XBL subtrees until
// frame construction, which does an explicit traversal of the unstyled
// children after shuffling the subtree. That explicit traversal may in
// turn find other bound elements, which get handled in the same way.
//
// We explicitly avoid handling restyles here (explicitly removing or
// changing bindings), since that adds complexity and is rarer. If it
// happens, we may just end up doing wasted work, since Gecko
// recursively drops Servo ElementData when the XBL insertion parent of
// an Element is changed.
if cfg!(feature = "gecko") && is_initial_style &&
parent_data.styles.primary().has_moz_binding()
{
debug!("Parent {:?} has XBL binding, deferring traversal", parent);
return true;
}
return false;
}
@ -424,7 +384,7 @@ where
let is_initial_style = !data.has_styles();
context.thread_local.statistics.elements_traversed += 1;
debug_assert!(flags.intersects(TraversalFlags::AnimationOnly | TraversalFlags::UnstyledOnly) ||
debug_assert!(flags.intersects(TraversalFlags::AnimationOnly) ||
!element.has_snapshot() || element.handled_snapshot(),
"Should've handled snapshots here already");
@ -471,15 +431,11 @@ where
// those operations and compute the propagated restyle hint (unless we're
// not processing invalidations, in which case don't need to propagate it
// and must avoid clearing it).
let propagated_hint = if flags.contains(TraversalFlags::UnstyledOnly) {
RestyleHint::empty()
} else {
debug_assert!(flags.for_animation_only() ||
!data.hint.has_animation_hint(),
"animation restyle hint should be handled during \
animation-only restyles");
data.hint.propagate(&flags)
};
let propagated_hint = data.hint.propagate(&flags);
trace!("propagated_hint={:?}, cascade_requirement={:?}, \
is_display_none={:?}, implementing_pseudo={:?}",
@ -518,7 +474,7 @@ where
traverse_children =
traverse_children &&
!traversal.should_cull_subtree(context, element, is_initial_style, &data);
!traversal.should_cull_subtree(context, element, &data);
// Examine our children, and enqueue the appropriate ones for traversal.
if traverse_children {
@ -800,12 +756,6 @@ where
propagated_hint,
child.implemented_pseudo_element());
// Make sure to not run style invalidation of styled elements in an
// unstyled-children-only traversal.
if child_data.is_some() && flags.intersects(TraversalFlags::UnstyledOnly) {
continue;
}
if let Some(ref mut child_data) = child_data {
let mut child_hint = propagated_hint;
match cascade_requirement {

View file

@ -16,9 +16,6 @@ bitflags! {
/// Traverse and update all elements with CSS animations since
/// @keyframes rules may have changed. Triggered by CSS rule changes.
const ForCSSRuleChanges = 1 << 1;
/// Styles unstyled elements, but does not handle invalidations on
/// already-styled elements.
const UnstyledOnly = 1 << 2;
/// A forgetful traversal ignores the previous state of the frame tree, and
/// thus does not compute damage or maintain other state describing the styles
/// pre-traversal. A forgetful traversal is usually the right thing if you
@ -61,7 +58,6 @@ pub fn assert_traversal_flags_match() {
check_traversal_flags! {
ServoTraversalFlags_AnimationOnly => TraversalFlags::AnimationOnly,
ServoTraversalFlags_ForCSSRuleChanges => TraversalFlags::ForCSSRuleChanges,
ServoTraversalFlags_UnstyledOnly => TraversalFlags::UnstyledOnly,
ServoTraversalFlags_Forgetful => TraversalFlags::Forgetful,
ServoTraversalFlags_ClearDirtyBits => TraversalFlags::ClearDirtyBits,
ServoTraversalFlags_ClearAnimationOnlyDirtyDescendants =>

View file

@ -294,9 +294,7 @@ pub extern "C" fn Servo_TraverseSubtree(
debug!("Servo_TraverseSubtree (flags={:?})", traversal_flags);
debug!("{:?}", ShowSubtreeData(element.as_node()));
// It makes no sense to do an animation restyle when we're styling
// newly-inserted content.
if !traversal_flags.contains(TraversalFlags::UnstyledOnly) {
let needs_animation_only_restyle =
element.has_animation_only_dirty_descendants() ||
element.has_animation_restyle_hints();
@ -309,7 +307,6 @@ pub extern "C" fn Servo_TraverseSubtree(
traversal_flags | TraversalFlags::AnimationOnly,
unsafe { &*snapshots });
}
}
traverse_subtree(element,
raw_data,