Skip to content
Permalink
Browse files

Auto merge of #12757 - emilio:stylo, r=bholley,pcwalton

stylo: Stop restyling display: none elements, remove the has_changed hack that made us use ReconstructFrame unconditionally.

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

r? @bholley

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12757)
<!-- Reviewable:end -->
  • Loading branch information...
bors-servo committed Aug 11, 2016
2 parents 3c7de6b + 9b8eac0 commit 1b2450339c40dbcb65e94a346ea434d45f0edf90
@@ -135,7 +135,7 @@ pub fn recalc_style_for_animations(context: &SharedLayoutContext,
update_style_for_animation(&context.style_context,
animation,
&mut fragment.style);
damage |= RestyleDamage::compute(Some(&old_style), &fragment.style);
damage |= RestyleDamage::compute(&old_style, &fragment.style);
}
}
});
@@ -1374,12 +1374,20 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
// We visit the kids first and reset their HAS_NEWLY_CONSTRUCTED_FLOW flags after checking
// them. NOTE: Make sure not to bail out early before resetting all the flags!
let mut need_to_reconstruct = false;

// If the node has display: none, it's possible that we haven't even
// styled the children once, so we need to bailout early here.
if node.style(self.style_context()).get_box().clone_display() == display::T::none {
return false;
}

for kid in node.children() {
if kid.flags().contains(HAS_NEWLY_CONSTRUCTED_FLOW) {
kid.remove_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
need_to_reconstruct = true
}
}

if need_to_reconstruct {
return false
}
@@ -30,14 +30,15 @@ use std::ops::Deref;
use std::sync::{Arc, Mutex};
use string_cache::Atom;
use style::computed_values;
use style::context::StyleContext;
use style::logical_geometry::{WritingMode, BlockFlowDirection, InlineBaseDirection};
use style::properties::longhands::{display, position};
use style::properties::style_structs;
use style::selector_impl::PseudoElement;
use style::selector_matching::Stylist;
use style::values::LocalToCss;
use style_traits::cursor::Cursor;
use wrapper::ThreadSafeLayoutNodeHelpers;
use wrapper::{LayoutNodeLayoutData, ThreadSafeLayoutNodeHelpers};

/// Mutable data belonging to the LayoutThread.
///
@@ -620,11 +621,39 @@ pub fn process_node_scroll_area_request< N: LayoutNode>(requested_node: N, layou
}
}

/// Ensures that a node's data, and all its parents' is initialized. This is
/// needed to resolve style lazily.
fn ensure_node_data_initialized<N: LayoutNode>(node: &N) {
let mut cur = Some(node.clone());
while let Some(current) = cur {
if current.borrow_data().is_some() {
break;
}

current.initialize_data();
cur = current.parent_node();
}
}

/// Return the resolved value of property for a given (pseudo)element.
/// https://drafts.csswg.org/cssom/#resolved-value
pub fn process_resolved_style_request<N: LayoutNode>(
requested_node: N, pseudo: &Option<PseudoElement>,
property: &Atom, layout_root: &mut FlowRef) -> Option<String> {
pub fn process_resolved_style_request<'a, N, C>(requested_node: N,
style_context: &'a C,
pseudo: &Option<PseudoElement>,
property: &Atom,
layout_root: &mut FlowRef) -> Option<String>
where N: LayoutNode,
C: StyleContext<'a>
{
use style::traversal::ensure_node_styled;

// This node might have display: none, or it's style might be not up to
// date, so we might need to do style recalc.
//
// FIXME(emilio): Is a bit shame we have to do this instead of in style.
ensure_node_data_initialized(&requested_node);
ensure_node_styled(requested_node, style_context);

let layout_node = requested_node.to_threadsafe();
let layout_node = match *pseudo {
Some(PseudoElement::Before) => layout_node.get_before_pseudo(),
@@ -16,6 +16,7 @@ use std::mem;
use style::context::SharedStyleContext;
use style::dom::TNode;
use style::selector_impl::ServoSelectorImpl;
use style::traversal::RestyleResult;
use style::traversal::{DomTraversalContext, remove_from_bloom_filter, recalc_style_at};
use util::opts;
use wrapper::{LayoutNodeLayoutData, ThreadSafeLayoutNodeHelpers};
@@ -69,12 +70,12 @@ impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
}
}

fn process_preorder(&self, node: N) {
// FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML
// parser.
fn process_preorder(&self, node: N) -> RestyleResult {
// FIXME(pcwalton): Stop allocating here. Ideally this should just be
// done by the HTML parser.
node.initialize_data();

recalc_style_at(&self.context, self.root, node);
recalc_style_at(&self.context, self.root, node)
}

fn process_postorder(&self, node: N) {
@@ -1237,8 +1237,13 @@ impl LayoutThread {
},
ReflowQueryType::ResolvedStyleQuery(node, ref pseudo, ref property) => {
let node = unsafe { ServoLayoutNode::new(&node) };
let layout_context = LayoutContext::new(&shared_layout_context);
rw_data.resolved_style_response =
process_resolved_style_request(node, pseudo, property, &mut root_flow);
process_resolved_style_request(node,
&layout_context,
pseudo,
property,
&mut root_flow);
},
ReflowQueryType::OffsetParentQuery(node) => {
let node = unsafe { ServoLayoutNode::new(&node) };
@@ -61,7 +61,7 @@ use style::dom::{PresentationalHintsSynthetizer, OpaqueNode, TDocument, TElement
use style::element_state::*;
use style::properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
use style::refcell::{Ref, RefCell, RefMut};
use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, ServoSelectorImpl};
use style::selector_impl::{ElementSnapshot, NonTSPseudoClass, PseudoElement, ServoSelectorImpl};
use style::sink::Push;
use style::str::is_whitespace;
use url::Url;
@@ -266,7 +266,8 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {

#[inline]
fn existing_style_for_restyle_damage<'a>(&'a self,
current_cv: Option<&'a Arc<ComputedValues>>)
current_cv: Option<&'a Arc<ComputedValues>>,
_pseudo_element: Option<&PseudoElement>)
-> Option<&'a Arc<ComputedValues>> {
current_cv
}
@@ -47,7 +47,11 @@ impl TRestyleDamage for RestyleDamage {
/// For Servo the style source is always the computed values.
type PreExistingComputedValues = Arc<ServoComputedValues>;

fn compute(old: Option<&Arc<ServoComputedValues>>,
fn empty() -> Self {
RestyleDamage::empty()
}

fn compute(old: &Arc<ServoComputedValues>,
new: &Arc<ServoComputedValues>) -> RestyleDamage {
compute_damage(old, new)
}
@@ -150,13 +154,7 @@ macro_rules! add_if_not_equal(
})
);

fn compute_damage(old: Option<&Arc<ServoComputedValues>>, new: &Arc<ServoComputedValues>) -> RestyleDamage {
let new = &**new;
let old: &ServoComputedValues = match old {
None => return RestyleDamage::rebuild_and_reflow(),
Some(cv) => &**cv,
};

fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> RestyleDamage {
let mut damage = RestyleDamage::empty();

// This should check every CSS property, as enumerated in the fields of
@@ -12,9 +12,10 @@ use element_state::ElementState;
use properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
use refcell::{Ref, RefMut};
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
use selector_impl::ElementExt;
use selector_impl::{ElementExt, PseudoElement};
use selectors::matching::DeclarationBlock;
use sink::Push;
use std::fmt::Debug;
use std::ops::BitOr;
use std::sync::Arc;
use string_cache::{Atom, Namespace};
@@ -44,7 +45,7 @@ impl OpaqueNode {
}
}

pub trait TRestyleDamage : BitOr<Output=Self> + Copy {
pub trait TRestyleDamage : Debug + PartialEq + BitOr<Output=Self> + Copy {
/// The source for our current computed values in the cascade. This is a
/// ComputedValues in Servo and a StyleContext in Gecko.
///
@@ -55,9 +56,11 @@ pub trait TRestyleDamage : BitOr<Output=Self> + Copy {
/// This should be obtained via TNode::existing_style_for_restyle_damage
type PreExistingComputedValues;

fn compute(old: Option<&Self::PreExistingComputedValues>,
fn compute(old: &Self::PreExistingComputedValues,
new: &Arc<ComputedValues>) -> Self;

fn empty() -> Self;

fn rebuild_and_reflow() -> Self;
}

@@ -174,7 +177,8 @@ pub trait TNode : Sized + Copy + Clone {
/// as an argument here, but otherwise Servo would crash due to double
/// borrows to return it.
fn existing_style_for_restyle_damage<'a>(&'a self,
current_computed_values: Option<&'a Arc<ComputedValues>>)
current_computed_values: Option<&'a Arc<ComputedValues>>,
pseudo: Option<&PseudoElement>)
-> Option<&'a <Self::ConcreteRestyleDamage as TRestyleDamage>::PreExistingComputedValues>;
}

0 comments on commit 1b24503

Please sign in to comment.
You can’t perform that action at this time.