Rename BoxTreeRoot/FragmentTreeRoot to BoxTree/FragmentTree

This commit is contained in:
Simon Sapin 2020-04-17 20:39:59 +02:00
parent ee62c7f2e4
commit c43ab0c267
6 changed files with 93 additions and 85 deletions

View file

@ -29,7 +29,7 @@ mod float;
pub mod inline;
mod root;
pub use root::{BoxTreeRoot, FragmentTreeRoot};
pub use root::{BoxTree, FragmentTree};
#[derive(Debug, Serialize)]
pub(crate) struct BlockFormattingContext {

View file

@ -34,21 +34,33 @@ use style::values::computed::Length;
use style_traits::CSSPixel;
#[derive(Serialize)]
pub struct BoxTreeRoot(BlockFormattingContext);
pub struct BoxTree {
/// Contains typically exactly one block-level box, which was generated by the root element.
/// There may be zero if that element has `display: none`.
root: BlockFormattingContext,
}
#[derive(Serialize)]
pub struct FragmentTreeRoot {
/// The children of the root of the fragment tree.
children: Vec<ArcRefCell<Fragment>>,
pub struct FragmentTree {
/// Fragments at the top-level of the tree.
///
/// If the root element has `display: none`, there are zero fragments.
/// Otherwise, there is at least one:
///
/// * The first fragment is generated by the root element.
/// * There may be additional fragments generated by positioned boxes
/// that have the initial containing block.
root_fragments: Vec<ArcRefCell<Fragment>>,
/// The scrollable overflow of the root of the fragment tree.
/// The scrollable overflow rectangle for the entire tree
/// https://drafts.csswg.org/css-overflow/#scrollable
scrollable_overflow: PhysicalRect<Length>,
/// The containing block used in the layout of this fragment tree.
initial_containing_block: PhysicalRect<Length>,
}
impl BoxTreeRoot {
impl BoxTree {
pub fn construct<'dom, Node>(context: &LayoutContext, root_element: Node) -> Self
where
Node: 'dom + Copy + LayoutNode<'dom> + Send + Sync,
@ -58,10 +70,12 @@ impl BoxTreeRoot {
// Zero box for `:root { display: none }`, one for the root element otherwise.
assert!(boxes.len() <= 1);
Self(BlockFormattingContext {
contains_floats: contains_floats == ContainsFloats::Yes,
contents: BlockContainer::BlockLevelBoxes(boxes),
})
Self {
root: BlockFormattingContext {
contains_floats: contains_floats == ContainsFloats::Yes,
contents: BlockContainer::BlockLevelBoxes(boxes),
},
}
}
}
@ -135,12 +149,12 @@ fn construct_for_root_element<'dom>(
(contains_floats, vec![root_box])
}
impl BoxTreeRoot {
impl BoxTree {
pub fn layout(
&self,
layout_context: &LayoutContext,
viewport: euclid::Size2D<f32, CSSPixel>,
) -> FragmentTreeRoot {
) -> FragmentTree {
let style = ComputedValues::initial_values();
// FIXME: use the documents mode:
@ -160,21 +174,21 @@ impl BoxTreeRoot {
let dummy_tree_rank = 0;
let mut positioning_context =
PositioningContext::new_for_containing_block_for_all_descendants();
let independent_layout = self.0.layout(
let independent_layout = self.root.layout(
layout_context,
&mut positioning_context,
&(&initial_containing_block).into(),
dummy_tree_rank,
);
let mut children = independent_layout
let mut root_fragments = independent_layout
.fragments
.into_iter()
.map(|fragment| ArcRefCell::new(fragment))
.collect::<Vec<_>>();
// Zero box for `:root { display: none }`, one for the root element otherwise.
assert!(children.len() <= 1);
assert!(root_fragments.len() <= 1);
// There may be more fragments at the top-level
// (for positioned boxes whose containing is the initial containing block)
@ -182,39 +196,41 @@ impl BoxTreeRoot {
positioning_context.layout_initial_containing_block_children(
layout_context,
&initial_containing_block,
&mut children,
&mut root_fragments,
);
let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| {
let child_overflow = child
.borrow()
.scrollable_overflow(&physical_containing_block);
let scrollable_overflow = root_fragments
.iter()
.fold(PhysicalRect::zero(), |acc, child| {
let child_overflow = child
.borrow()
.scrollable_overflow(&physical_containing_block);
// https://drafts.csswg.org/css-overflow/#scrolling-direction
// We want to clip scrollable overflow on box-start and inline-start
// sides of the scroll container.
//
// FIXME(mrobinson, bug 25564): This should take into account writing
// mode.
let child_overflow = PhysicalRect::new(
euclid::Point2D::zero(),
euclid::Size2D::new(
child_overflow.size.width + child_overflow.origin.x,
child_overflow.size.height + child_overflow.origin.y,
),
);
acc.union(&child_overflow)
});
// https://drafts.csswg.org/css-overflow/#scrolling-direction
// We want to clip scrollable overflow on box-start and inline-start
// sides of the scroll container.
//
// FIXME(mrobinson, bug 25564): This should take into account writing
// mode.
let child_overflow = PhysicalRect::new(
euclid::Point2D::zero(),
euclid::Size2D::new(
child_overflow.size.width + child_overflow.origin.x,
child_overflow.size.height + child_overflow.origin.y,
),
);
acc.union(&child_overflow)
});
FragmentTreeRoot {
children,
FragmentTree {
root_fragments,
scrollable_overflow,
initial_containing_block: physical_containing_block,
}
}
}
impl FragmentTreeRoot {
impl FragmentTree {
pub fn build_display_list(&self, builder: &mut crate::display_list::DisplayListBuilder) {
let mut stacking_context = StackingContext::create_root(&builder.wr);
{
@ -228,7 +244,7 @@ impl FragmentTreeRoot {
),
};
for fragment in &self.children {
for fragment in &self.root_fragments {
fragment.borrow().build_stacking_context_tree(
fragment,
&mut stacking_context_builder,
@ -245,7 +261,7 @@ impl FragmentTreeRoot {
pub fn print(&self) {
let mut print_tree = PrintTree::new("Fragment Tree".to_string());
for fragment in &self.children {
for fragment in &self.root_fragments {
fragment.borrow().print(&mut print_tree);
}
}
@ -261,7 +277,7 @@ impl FragmentTreeRoot {
&self,
mut process_func: impl FnMut(&Fragment, &PhysicalRect<Length>) -> Option<T>,
) -> Option<T> {
self.children.iter().find_map(|child| {
self.root_fragments.iter().find_map(|child| {
child
.borrow()
.find(&self.initial_containing_block, &mut process_func)

View file

@ -5,7 +5,7 @@
//! Supports writing a trace file created during each layout scope
//! that can be viewed by an external tool to make layout debugging easier.
use crate::flow::{BoxTreeRoot, FragmentTreeRoot};
use crate::flow::{BoxTree, FragmentTree};
use serde_json::{to_string, to_value, Value};
use std::cell::RefCell;
use std::fs;
@ -63,8 +63,8 @@ impl ScopeData {
}
struct State {
fragment_tree: Arc<FragmentTreeRoot>,
box_tree: Arc<BoxTreeRoot>,
fragment_tree: Arc<FragmentTree>,
box_tree: Arc<BoxTree>,
scope_stack: Vec<Box<ScopeData>>,
}
@ -109,7 +109,7 @@ pub fn generate_unique_debug_id() -> u16 {
/// Begin a layout debug trace. If this has not been called,
/// creating debug scopes has no effect.
pub fn begin_trace(box_tree: Arc<BoxTreeRoot>, fragment_tree: Arc<FragmentTreeRoot>) {
pub fn begin_trace(box_tree: Arc<BoxTree>, fragment_tree: Arc<FragmentTree>) {
assert!(STATE_KEY.with(|ref r| r.borrow().is_none()));
STATE_KEY.with(|ref r| {

View file

@ -30,7 +30,7 @@ mod style_ext;
pub mod traversal;
pub mod wrapper;
pub use flow::{BoxTreeRoot, FragmentTreeRoot};
pub use flow::{BoxTree, FragmentTree};
use crate::geom::flow_relative::Vec2;
use style::properties::ComputedValues;

View file

@ -4,7 +4,7 @@
//! Utilities for querying the layout, as needed by the layout thread.
use crate::context::LayoutContext;
use crate::flow::FragmentTreeRoot;
use crate::flow::FragmentTree;
use crate::fragments::Fragment;
use app_units::Au;
use euclid::default::{Point2D, Rect};
@ -166,14 +166,9 @@ impl LayoutRPC for LayoutRPCImpl {
pub fn process_content_box_request(
requested_node: OpaqueNode,
fragment_tree_root: Option<Arc<FragmentTreeRoot>>,
fragment_tree: Option<Arc<FragmentTree>>,
) -> Option<Rect<Au>> {
let fragment_tree_root = match fragment_tree_root {
Some(fragment_tree_root) => fragment_tree_root,
None => return None,
};
Some(fragment_tree_root.get_content_box_for_node(requested_node))
Some(fragment_tree?.get_content_box_for_node(requested_node))
}
pub fn process_content_boxes_request(_requested_node: OpaqueNode) -> Vec<Rect<Au>> {
@ -182,14 +177,13 @@ pub fn process_content_boxes_request(_requested_node: OpaqueNode) -> Vec<Rect<Au
pub fn process_node_geometry_request(
requested_node: OpaqueNode,
fragment_tree_root: Option<Arc<FragmentTreeRoot>>,
fragment_tree: Option<Arc<FragmentTree>>,
) -> Rect<i32> {
let fragment_tree_root = match fragment_tree_root {
Some(fragment_tree_root) => fragment_tree_root,
None => return Rect::zero(),
};
fragment_tree_root.get_border_dimensions_for_node(requested_node)
if let Some(fragment_tree) = fragment_tree {
fragment_tree.get_border_dimensions_for_node(requested_node)
} else {
Rect::zero()
}
}
pub fn process_node_scroll_id_request<'dom>(
@ -212,7 +206,7 @@ pub fn process_resolved_style_request<'dom>(
node: impl LayoutNode<'dom>,
pseudo: &Option<PseudoElement>,
property: &PropertyId,
fragment_tree_root: Option<Arc<FragmentTreeRoot>>,
fragment_tree: Option<Arc<FragmentTree>>,
) -> String {
if !node.as_element().unwrap().has_data() {
return process_resolved_style_request_for_unstyled_node(context, node, pseudo, property);
@ -286,11 +280,11 @@ pub fn process_resolved_style_request<'dom>(
return computed_style();
}
let fragment_tree_root = match fragment_tree_root {
Some(fragment_tree_root) => fragment_tree_root,
let fragment_tree = match fragment_tree {
Some(fragment_tree) => fragment_tree,
None => return computed_style(),
};
fragment_tree_root
fragment_tree
.find(|fragment, containing_block| {
let box_fragment = match fragment {
Fragment::Box(ref box_fragment) if box_fragment.tag == node.opaque() => {

View file

@ -45,7 +45,7 @@ use layout::query::{
process_offset_parent_query, process_resolved_style_request, process_text_index_request,
};
use layout::traversal::RecalcStyle;
use layout::{BoxTreeRoot, FragmentTreeRoot};
use layout::{BoxTree, FragmentTree};
use layout_traits::LayoutThreadFactory;
use libc::c_void;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
@ -160,11 +160,11 @@ pub struct LayoutThread {
/// The number of Web fonts that have been requested but not yet loaded.
outstanding_web_fonts: Arc<AtomicUsize>,
/// The root of the box tree.
box_tree_root: RefCell<Option<Arc<BoxTreeRoot>>>,
/// The box tree.
box_tree: RefCell<Option<Arc<BoxTree>>>,
/// The root of the fragment tree.
fragment_tree_root: RefCell<Option<Arc<FragmentTreeRoot>>>,
/// The fragment tree.
fragment_tree: RefCell<Option<Arc<FragmentTree>>>,
/// The document-specific shared lock used for author-origin stylesheets
document_shared_lock: Option<SharedRwLock>,
@ -513,8 +513,8 @@ impl LayoutThread {
font_cache_sender: ipc_font_cache_sender,
generation: Cell::new(0),
outstanding_web_fonts: Arc::new(AtomicUsize::new(0)),
box_tree_root: Default::default(),
fragment_tree_root: Default::default(),
box_tree: Default::default(),
fragment_tree: Default::default(),
document_shared_lock: None,
// Epoch starts at 1 because of the initial display list for epoch 0 that we send to WR
epoch: Cell::new(Epoch(1)),
@ -1078,7 +1078,7 @@ impl LayoutThread {
driver::traverse_dom(&traversal, token, rayon_pool);
let root_node = document.root_element().unwrap().as_node();
let build_box_tree = || BoxTreeRoot::construct(traversal.context(), root_node);
let build_box_tree = || BoxTree::construct(traversal.context(), root_node);
let box_tree = if let Some(pool) = rayon_pool {
pool.install(build_box_tree)
} else {
@ -1103,8 +1103,8 @@ impl LayoutThread {
} else {
run_layout()
});
*self.box_tree_root.borrow_mut() = Some(box_tree);
*self.fragment_tree_root.borrow_mut() = Some(fragment_tree);
*self.box_tree.borrow_mut() = Some(box_tree);
*self.fragment_tree.borrow_mut() = Some(fragment_tree);
}
for element in elements_with_snapshot {
@ -1130,7 +1130,7 @@ impl LayoutThread {
layout_context.style_context.stylist.rule_tree().maybe_gc();
// Perform post-style recalculation layout passes.
if let Some(root) = &*self.fragment_tree_root.borrow() {
if let Some(root) = &*self.fragment_tree.borrow() {
self.perform_post_style_recalc_layout_passes(
root.clone(),
&data.reflow_goal,
@ -1162,7 +1162,7 @@ impl LayoutThread {
ReflowGoal::LayoutQuery(ref querymsg, _) => match querymsg {
&QueryMsg::ContentBoxQuery(node) => {
rw_data.content_box_response =
process_content_box_request(node, self.fragment_tree_root.borrow().clone());
process_content_box_request(node, self.fragment_tree.borrow().clone());
},
&QueryMsg::ContentBoxesQuery(node) => {
rw_data.content_boxes_response = process_content_boxes_request(node);
@ -1175,10 +1175,8 @@ impl LayoutThread {
rw_data.text_index_response = process_text_index_request(node, point_in_node);
},
&QueryMsg::ClientRectQuery(node) => {
rw_data.client_rect_response = process_node_geometry_request(
node,
self.fragment_tree_root.borrow().clone(),
);
rw_data.client_rect_response =
process_node_geometry_request(node, self.fragment_tree.borrow().clone());
},
&QueryMsg::NodeScrollGeometryQuery(node) => {
rw_data.scroll_area_response = process_node_scroll_area_request(node);
@ -1190,7 +1188,7 @@ impl LayoutThread {
},
&QueryMsg::ResolvedStyleQuery(node, ref pseudo, ref property) => {
let node = unsafe { ServoLayoutNode::new(&node) };
let fragment_tree = self.fragment_tree_root.borrow().clone();
let fragment_tree = self.fragment_tree.borrow().clone();
rw_data.resolved_style_response = process_resolved_style_request(
context,
node,
@ -1270,13 +1268,13 @@ impl LayoutThread {
fn perform_post_style_recalc_layout_passes(
&self,
fragment_tree: Arc<FragmentTreeRoot>,
fragment_tree: Arc<FragmentTree>,
reflow_goal: &ReflowGoal,
document: Option<&ServoLayoutDocument>,
context: &mut LayoutContext,
) {
if self.trace_layout {
if let Some(box_tree) = &*self.box_tree_root.borrow() {
if let Some(box_tree) = &*self.box_tree.borrow() {
layout_debug::begin_trace(box_tree.clone(), fragment_tree.clone());
}
}