Skip to content

Commit

Permalink
Hoist most styling functionality from TNode to TElement.
Browse files Browse the repository at this point in the history
MozReview-Commit-ID: DZ8ZrsZIiAU
  • Loading branch information
bholley committed Oct 29, 2016
1 parent 47d29fd commit 5442fbe
Show file tree
Hide file tree
Showing 17 changed files with 391 additions and 355 deletions.
1 change: 0 additions & 1 deletion components/layout/lib.rs
Expand Up @@ -46,7 +46,6 @@ extern crate range;
extern crate rustc_serialize;
extern crate script_layout_interface;
extern crate script_traits;
extern crate selectors;
extern crate smallvec;
#[macro_use(atom, ns)] extern crate string_cache;
extern crate style;
Expand Down
35 changes: 26 additions & 9 deletions components/layout/traversal.rs
Expand Up @@ -11,13 +11,12 @@ use flow::{self, PreorderFlowTraversal};
use flow::{CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils, PostorderFlowTraversal};
use gfx::display_list::OpaqueNode;
use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use script_layout_interface::wrapper_traits::{LayoutElement, LayoutNode, ThreadSafeLayoutNode};
use std::mem;
use style::atomic_refcell::AtomicRefCell;
use style::context::{LocalStyleContext, SharedStyleContext, StyleContext};
use style::data::NodeData;
use style::dom::TNode;
use style::selector_impl::ServoSelectorImpl;
use style::dom::{StylingMode, TElement, TNode};
use style::traversal::{DomTraversalContext, put_thread_local_bloom_filter};
use style::traversal::{recalc_style_at, remove_from_bloom_filter};
use style::traversal::RestyleResult;
Expand All @@ -32,7 +31,7 @@ pub struct RecalcStyleAndConstructFlows<'lc> {

impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
where N: LayoutNode + TNode,
N::ConcreteElement: ::selectors::Element<Impl=ServoSelectorImpl>
N::ConcreteElement: LayoutElement

{
type SharedContext = SharedLayoutContext;
Expand Down Expand Up @@ -114,9 +113,27 @@ impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
construct_flows_at(&self.context, self.root, node);
}

fn ensure_node_data(node: &N) -> &AtomicRefCell<NodeData> {
node.initialize_data();
node.get_style_data().unwrap()
fn should_traverse_child(parent: N::ConcreteElement, child: N) -> bool {
// If this node has been marked as damaged in some way, we need to
// traverse it unconditionally for layout.
if child.has_changed() {
return true;
}

match child.as_element() {
Some(el) => el.styling_mode() != StylingMode::Stop,
// Aside from the has_changed case above, we want to traverse non-element children
// in two additional cases:
// (1) They child doesn't yet have layout data (preorder traversal initializes it).
// (2) The parent element has restyle damage (so the text flow also needs fixup).
None => child.get_raw_data().is_none() ||
parent.as_node().to_threadsafe().restyle_damage() != RestyleDamage::empty(),
}
}

fn ensure_element_data(element: &N::ConcreteElement) -> &AtomicRefCell<NodeData> {
element.as_node().initialize_data();
element.get_style_data().unwrap()
}

fn local_context(&self) -> &LocalStyleContext {
Expand All @@ -140,8 +157,8 @@ fn construct_flows_at<'a, N: LayoutNode>(context: &'a LayoutContext<'a>, root: O

// Always reconstruct if incremental layout is turned off.
let nonincremental_layout = opts::get().nonincremental_layout;
if nonincremental_layout || node.has_dirty_descendants() ||
tnode.restyle_damage() != RestyleDamage::empty() {
if nonincremental_layout || tnode.restyle_damage() != RestyleDamage::empty() ||
node.as_element().map_or(false, |el| el.has_dirty_descendants()) {
let mut flow_constructor = FlowConstructor::new(context);
if nonincremental_layout || !flow_constructor.repair_if_possible(&tnode) {
flow_constructor.process(&tnode);
Expand Down
38 changes: 18 additions & 20 deletions components/layout/wrapper.rs
Expand Up @@ -33,12 +33,12 @@
use core::nonzero::NonZero;
use data::{LayoutDataFlags, PersistentLayoutData};
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
use script_layout_interface::wrapper_traits::{GetLayoutData, LayoutNode};
use script_layout_interface::wrapper_traits::{ThreadSafeLayoutElement, ThreadSafeLayoutNode};
use script_layout_interface::wrapper_traits::GetLayoutData;
use style::atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use style::computed_values::content::{self, ContentItem};

pub type NonOpaqueStyleAndLayoutData = *mut AtomicRefCell<PersistentLayoutData>;
pub type NonOpaqueStyleAndLayoutData = AtomicRefCell<PersistentLayoutData>;

pub trait LayoutNodeLayoutData {
/// Similar to borrow_data*, but returns the full PersistentLayoutData rather
Expand All @@ -50,21 +50,11 @@ pub trait LayoutNodeLayoutData {

impl<T: GetLayoutData> LayoutNodeLayoutData for T {
fn borrow_layout_data(&self) -> Option<AtomicRef<PersistentLayoutData>> {
unsafe {
self.get_style_and_layout_data().map(|opaque| {
let container = *opaque.ptr as NonOpaqueStyleAndLayoutData;
(*container).borrow()
})
}
self.get_raw_data().map(|d| d.borrow())
}

fn mutate_layout_data(&self) -> Option<AtomicRefMut<PersistentLayoutData>> {
unsafe {
self.get_style_and_layout_data().map(|opaque| {
let container = *opaque.ptr as NonOpaqueStyleAndLayoutData;
(*container).borrow_mut()
})
}
self.get_raw_data().map(|d| d.borrow_mut())
}

fn flow_debug_id(self) -> usize {
Expand All @@ -73,19 +63,27 @@ impl<T: GetLayoutData> LayoutNodeLayoutData for T {
}

pub trait LayoutNodeHelpers {
fn initialize_data(self);
fn initialize_data(&self);
fn get_raw_data(&self) -> Option<&NonOpaqueStyleAndLayoutData>;
}

impl<T: LayoutNode> LayoutNodeHelpers for T {
fn initialize_data(self) {
if self.borrow_layout_data().is_none() {
let ptr: NonOpaqueStyleAndLayoutData =
impl<T: GetLayoutData> LayoutNodeHelpers for T {
fn initialize_data(&self) {
if self.get_raw_data().is_none() {
let ptr: *mut NonOpaqueStyleAndLayoutData =
Box::into_raw(box AtomicRefCell::new(PersistentLayoutData::new()));
let opaque = OpaqueStyleAndLayoutData {
ptr: unsafe { NonZero::new(ptr as *mut AtomicRefCell<PartialPersistentLayoutData>) }
};
self.init_style_and_layout_data(opaque);
}
};
}

fn get_raw_data(&self) -> Option<&NonOpaqueStyleAndLayoutData> {
self.get_style_and_layout_data().map(|opaque| {
let container = *opaque.ptr as *mut NonOpaqueStyleAndLayoutData;
unsafe { &*container }
})
}
}

Expand Down
1 change: 1 addition & 0 deletions components/layout_thread/Cargo.toml
Expand Up @@ -30,6 +30,7 @@ profile_traits = {path = "../profile_traits"}
script = {path = "../script"}
script_layout_interface = {path = "../script_layout_interface"}
script_traits = {path = "../script_traits"}
selectors = "0.14"
serde_derive = "0.8"
serde_json = "0.8"
style = {path = "../style"}
Expand Down
17 changes: 10 additions & 7 deletions components/layout_thread/lib.rs
Expand Up @@ -37,6 +37,7 @@ extern crate profile_traits;
extern crate script;
extern crate script_layout_interface;
extern crate script_traits;
extern crate selectors;
extern crate serde_json;
extern crate style;
extern crate url;
Expand Down Expand Up @@ -94,6 +95,7 @@ use script_layout_interface::rpc::{LayoutRPC, MarginStyleResponse, NodeOverflowR
use script_layout_interface::wrapper_traits::LayoutNode;
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
use script_traits::{StackingContextScrollState, UntrustedNodeAddress};
use selectors::Element;
use std::borrow::ToOwned;
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
Expand Down Expand Up @@ -1109,11 +1111,11 @@ impl LayoutThread {
// NB: The dirty bit is propagated down the tree.
unsafe { node.set_dirty(); }

let mut current = node.parent_node();
while let Some(node) = current {
if node.has_dirty_descendants() { break; }
unsafe { node.set_dirty_descendants(); }
current = node.parent_node();
let mut current = node.parent_node().and_then(|n| n.as_element());
while let Some(el) = current {
if el.has_dirty_descendants() { break; }
unsafe { el.set_dirty_descendants(); }
current = el.parent_element();
}

next = iter.next_skipping_children();
Expand Down Expand Up @@ -1155,7 +1157,8 @@ impl LayoutThread {
viewport_size_changed,
data.reflow_info.goal);

if node.is_dirty() || node.has_dirty_descendants() {
let el = node.as_element();
if el.is_some() && (el.unwrap().deprecated_dirty_bit_is_set() || el.unwrap().has_dirty_descendants()) {
// Recalculate CSS styles and rebuild flows and fragments.
profile(time::ProfilerCategory::LayoutStyleRecalc,
self.profiler_metadata(),
Expand Down Expand Up @@ -1485,7 +1488,7 @@ impl LayoutThread {
/// because the struct type is transmuted to a different type on the script side.
unsafe fn handle_reap_style_and_layout_data(&self, data: OpaqueStyleAndLayoutData) {
let ptr: *mut AtomicRefCell<PartialPersistentLayoutData> = *data.ptr;
let non_opaque: NonOpaqueStyleAndLayoutData = ptr as *mut _;
let non_opaque: *mut NonOpaqueStyleAndLayoutData = ptr as *mut _;
let _ = Box::from_raw(non_opaque);
}

Expand Down

0 comments on commit 5442fbe

Please sign in to comment.