mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
style: Avoid propagating the restyle flag all through the dom when a node gets dirty.
This puts us in pair with stylo.
This commit is contained in:
parent
96ea1a335c
commit
d81fe27b11
4 changed files with 21 additions and 35 deletions
|
@ -77,7 +77,9 @@ impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
|
||||||
recalc_style_at(&self.context, self.root, node);
|
recalc_style_at(&self.context, self.root, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_postorder(&self, node: N) { construct_flows_at(&self.context, self.root, node); }
|
fn process_postorder(&self, node: N) {
|
||||||
|
construct_flows_at(&self.context, self.root, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A bottom-up, parallelizable traversal.
|
/// A bottom-up, parallelizable traversal.
|
||||||
|
@ -96,7 +98,7 @@ fn construct_flows_at<'a, N: LayoutNode>(context: &'a LayoutContext<'a>, root: O
|
||||||
|
|
||||||
// Always reconstruct if incremental layout is turned off.
|
// Always reconstruct if incremental layout is turned off.
|
||||||
let nonincremental_layout = opts::get().nonincremental_layout;
|
let nonincremental_layout = opts::get().nonincremental_layout;
|
||||||
if nonincremental_layout || node.has_dirty_descendants() {
|
if nonincremental_layout || node.is_dirty() || node.has_dirty_descendants() {
|
||||||
let mut flow_constructor = FlowConstructor::new(context);
|
let mut flow_constructor = FlowConstructor::new(context);
|
||||||
if nonincremental_layout || !flow_constructor.repair_if_possible(&tnode) {
|
if nonincremental_layout || !flow_constructor.repair_if_possible(&tnode) {
|
||||||
flow_constructor.process(&tnode);
|
flow_constructor.process(&tnode);
|
||||||
|
|
|
@ -479,19 +479,7 @@ impl Node {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Dirty descendants.
|
self.set_flag(IS_DIRTY, true);
|
||||||
fn dirty_subtree(node: &Node) {
|
|
||||||
// Stop if this subtree is already dirty.
|
|
||||||
if node.is_dirty() { return }
|
|
||||||
|
|
||||||
node.set_flag(IS_DIRTY | HAS_DIRTY_DESCENDANTS, true);
|
|
||||||
|
|
||||||
for kid in node.children() {
|
|
||||||
dirty_subtree(kid.r());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dirty_subtree(self);
|
|
||||||
|
|
||||||
// 4. Dirty ancestors.
|
// 4. Dirty ancestors.
|
||||||
for ancestor in self.ancestors() {
|
for ancestor in self.ancestors() {
|
||||||
|
|
|
@ -153,10 +153,24 @@ pub trait DomTraversalContext<N: TNode> {
|
||||||
///
|
///
|
||||||
/// Note that this is true unconditionally for servo, since it requires to
|
/// Note that this is true unconditionally for servo, since it requires to
|
||||||
/// bubble the widths bottom-up for all the DOM.
|
/// bubble the widths bottom-up for all the DOM.
|
||||||
fn should_process(&self, _node: N) -> bool { true }
|
fn should_process(&self, node: N) -> bool {
|
||||||
|
node.is_dirty() || node.has_dirty_descendants()
|
||||||
|
}
|
||||||
|
|
||||||
/// Do an action over the child before pushing him to the work queue.
|
/// Do an action over the child before pushing him to the work queue.
|
||||||
fn pre_process_child_hook(&self, _parent: N, _kid: N) {}
|
///
|
||||||
|
/// By default, propagate the IS_DIRTY flag down the tree.
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn pre_process_child_hook(&self, parent: N, kid: N) {
|
||||||
|
// NOTE: At this point is completely safe to modify either the parent or
|
||||||
|
// the child, since we have exclusive access to both of them.
|
||||||
|
if parent.is_dirty() {
|
||||||
|
unsafe {
|
||||||
|
kid.set_dirty(true);
|
||||||
|
parent.set_dirty_descendants(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the style for a single node.
|
/// Calculates the style for a single node.
|
||||||
|
|
|
@ -6,7 +6,6 @@ use context::StandaloneStyleContext;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use style::context::SharedStyleContext;
|
use style::context::SharedStyleContext;
|
||||||
use style::dom::OpaqueNode;
|
use style::dom::OpaqueNode;
|
||||||
use style::dom::TNode;
|
|
||||||
use style::traversal::{DomTraversalContext, recalc_style_at};
|
use style::traversal::{DomTraversalContext, recalc_style_at};
|
||||||
use wrapper::GeckoNode;
|
use wrapper::GeckoNode;
|
||||||
|
|
||||||
|
@ -37,21 +36,4 @@ impl<'lc, 'ln> DomTraversalContext<GeckoNode<'ln>> for RecalcStyleOnly<'lc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_postorder(&self, _: GeckoNode<'ln>) {}
|
fn process_postorder(&self, _: GeckoNode<'ln>) {}
|
||||||
|
|
||||||
/// In Gecko we use this traversal just for restyling, so we can stop once
|
|
||||||
/// we know there aren't more dirty nodes under ourselves.
|
|
||||||
fn should_process(&self, node: GeckoNode<'ln>) -> bool {
|
|
||||||
node.is_dirty() || node.has_dirty_descendants()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pre_process_child_hook(&self, parent: GeckoNode<'ln>, kid: GeckoNode<'ln>) {
|
|
||||||
// NOTE: At this point is completely safe to modify either the parent or
|
|
||||||
// the child, since we have exclusive access to them.
|
|
||||||
if parent.is_dirty() {
|
|
||||||
unsafe {
|
|
||||||
kid.set_dirty(true);
|
|
||||||
parent.set_dirty_descendants(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue