layout: Refactor flow construction to move around large structs less.

5% perf win, and a net loss in lines of code.
This commit is contained in:
Patrick Walton 2014-02-04 23:08:53 -08:00
parent 48e9b8f752
commit d34ebf521d
4 changed files with 34 additions and 52 deletions

View file

@ -5,12 +5,14 @@
//! CSS block formatting contexts. //! CSS block formatting contexts.
use layout::box_::Box; use layout::box_::Box;
use layout::construct::FlowConstructor;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType};
use layout::flow::{BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils}; use layout::flow::{BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use layout::flow; use layout::flow;
use layout::model::{MaybeAuto, Specified, Auto, specified_or_none, specified}; use layout::model::{MaybeAuto, Specified, Auto, specified_or_none, specified};
use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType}; use layout::wrapper::ThreadSafeLayoutNode;
use std::cell::RefCell; use std::cell::RefCell;
use geom::{Point2D, Rect, SideOffsets2D, Size2D}; use geom::{Point2D, Rect, SideOffsets2D, Size2D};
@ -66,30 +68,24 @@ pub struct BlockFlow {
} }
impl BlockFlow { impl BlockFlow {
pub fn new(base: BaseFlow) -> BlockFlow { pub fn from_node(constructor: &mut FlowConstructor, node: ThreadSafeLayoutNode, is_fixed: bool)
-> BlockFlow {
BlockFlow { BlockFlow {
base: base, base: BaseFlow::new(constructor.next_flow_id(), node),
box_: None, box_: Some(Box::new(constructor, node)),
is_root: false,
is_fixed: false,
float: None
}
}
pub fn from_box(base: BaseFlow, box_: Box, is_fixed: bool) -> BlockFlow {
BlockFlow {
base: base,
box_: Some(box_),
is_root: false, is_root: false,
is_fixed: is_fixed, is_fixed: is_fixed,
float: None float: None
} }
} }
pub fn float_from_box(base: BaseFlow, float_type: FloatType, box_: Box) -> BlockFlow { pub fn float_from_node(constructor: &mut FlowConstructor,
node: ThreadSafeLayoutNode,
float_type: FloatType)
-> BlockFlow {
BlockFlow { BlockFlow {
base: base, base: BaseFlow::new(constructor.next_flow_id(), node),
box_: Some(box_), box_: Some(Box::new(constructor, node)),
is_root: false, is_root: false,
is_fixed: false, is_fixed: false,
float: Some(~FloatedBlockInfo::new(float_type)) float: Some(~FloatedBlockInfo::new(float_type))

View file

@ -14,7 +14,6 @@ use gfx::display_list::{SolidColorDisplayItem, SolidColorDisplayItemClass, TextD
use gfx::display_list::{TextDisplayItemClass, TextDisplayItemFlags, ClipDisplayItem}; use gfx::display_list::{TextDisplayItemClass, TextDisplayItemFlags, ClipDisplayItem};
use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection}; use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection};
use gfx::font::FontStyle; use gfx::font::FontStyle;
use gfx::text::text_run::TextRun; use gfx::text::text_run::TextRun;
use servo_msg::constellation_msg::{FrameRectMsg, PipelineId, SubpageId}; use servo_msg::constellation_msg::{FrameRectMsg, PipelineId, SubpageId};
use servo_net::image::holder::ImageHolder; use servo_net::image::holder::ImageHolder;
@ -33,6 +32,7 @@ use style::computed_values::{border_style, clear, font_family, line_height, posi
use style::computed_values::{text_align, text_decoration, vertical_align, visibility, white_space}; use style::computed_values::{text_align, text_decoration, vertical_align, visibility, white_space};
use css::node_style::StyledNode; use css::node_style::StyledNode;
use layout::construct::FlowConstructor;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData, ToGfxColor}; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData, ToGfxColor};
use layout::float_context::{ClearType, ClearLeft, ClearRight, ClearBoth}; use layout::float_context::{ClearType, ClearLeft, ClearRight, ClearBoth};
@ -298,7 +298,7 @@ pub struct InlineParentInfo {
impl Box { impl Box {
/// Constructs a new `Box` instance. /// Constructs a new `Box` instance.
pub fn new(node: ThreadSafeLayoutNode, specific: SpecificBoxInfo) -> Box { pub fn new(constructor: &mut FlowConstructor, node: ThreadSafeLayoutNode) -> Box {
Box { Box {
node: OpaqueNode::from_thread_safe_layout_node(&node), node: OpaqueNode::from_thread_safe_layout_node(&node),
style: node.style().clone(), style: node.style().clone(),
@ -306,7 +306,7 @@ impl Box {
border: RefCell::new(Zero::zero()), border: RefCell::new(Zero::zero()),
padding: RefCell::new(Zero::zero()), padding: RefCell::new(Zero::zero()),
margin: RefCell::new(Zero::zero()), margin: RefCell::new(Zero::zero()),
specific: specific, specific: constructor.build_specific_box_info_for_node(node),
position_offsets: RefCell::new(Zero::zero()), position_offsets: RefCell::new(Zero::zero()),
inline_info: RefCell::new(None), inline_info: RefCell::new(None),
new_line_pos: ~[], new_line_pos: ~[],

View file

@ -23,10 +23,11 @@
use css::node_style::StyledNode; use css::node_style::StyledNode;
use layout::block::BlockFlow; use layout::block::BlockFlow;
use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo}; use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo};
use layout::box_::{UnscannedTextBox, UnscannedTextBoxInfo, InlineInfo, InlineParentInfo}; use layout::box_::{InlineInfo, InlineParentInfo, SpecificBoxInfo, UnscannedTextBox};
use layout::box_::{UnscannedTextBoxInfo};
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::float_context::FloatType; use layout::float_context::FloatType;
use layout::flow::{BaseFlow, Flow, FlowLeafSet, ImmutableFlowUtils, MutableOwnedFlowUtils}; use layout::flow::{Flow, FlowLeafSet, ImmutableFlowUtils, MutableOwnedFlowUtils};
use layout::inline::InlineFlow; use layout::inline::InlineFlow;
use layout::text::TextRunScanner; use layout::text::TextRunScanner;
use layout::util::{LayoutDataAccess, OpaqueNode}; use layout::util::{LayoutDataAccess, OpaqueNode};
@ -227,7 +228,7 @@ impl<'fc> FlowConstructor<'fc> {
} }
/// Returns the next flow ID and bumps the internal counter. /// Returns the next flow ID and bumps the internal counter.
fn next_flow_id(&self) -> int { pub fn next_flow_id(&self) -> int {
let id = self.next_flow_id.get(); let id = self.next_flow_id.get();
self.next_flow_id.set(id + 1); self.next_flow_id.set(id + 1);
id id
@ -246,9 +247,10 @@ impl<'fc> FlowConstructor<'fc> {
} }
} }
/// Builds a `Box` for the given node. /// Builds specific `Box` info for the given node.
fn build_box_for_node(&mut self, node: ThreadSafeLayoutNode) -> Box { pub fn build_specific_box_info_for_node(&mut self, node: ThreadSafeLayoutNode)
let specific = match node.type_id() { -> SpecificBoxInfo {
match node.type_id() {
ElementNodeTypeId(HTMLImageElementTypeId) => { ElementNodeTypeId(HTMLImageElementTypeId) => {
match self.build_box_info_for_image(node) { match self.build_box_info_for_image(node) {
None => GenericBox, None => GenericBox,
@ -258,8 +260,7 @@ impl<'fc> FlowConstructor<'fc> {
ElementNodeTypeId(HTMLIframeElementTypeId) => IframeBox(IframeBoxInfo::new(&node)), ElementNodeTypeId(HTMLIframeElementTypeId) => IframeBox(IframeBoxInfo::new(&node)),
TextNodeTypeId => UnscannedTextBox(UnscannedTextBoxInfo::new(&node)), TextNodeTypeId => UnscannedTextBox(UnscannedTextBoxInfo::new(&node)),
_ => GenericBox, _ => GenericBox,
}; }
Box::new(node, specific)
} }
/// Creates an inline flow from a set of inline boxes and adds it as a child of the given flow. /// Creates an inline flow from a set of inline boxes and adds it as a child of the given flow.
@ -275,8 +276,7 @@ impl<'fc> FlowConstructor<'fc> {
return return
} }
let inline_base = BaseFlow::new(self.next_flow_id(), node); let mut inline_flow = ~InlineFlow::from_boxes(self.next_flow_id(), node, boxes) as ~Flow;
let mut inline_flow = ~InlineFlow::from_boxes(inline_base, boxes) as ~Flow;
inline_flow.mark_as_leaf(self.layout_context.flow_leaf_set.get()); inline_flow.mark_as_leaf(self.layout_context.flow_leaf_set.get());
TextRunScanner::new().scan_for_runs(self.font_context, inline_flow); TextRunScanner::new().scan_for_runs(self.font_context, inline_flow);
@ -391,9 +391,7 @@ impl<'fc> FlowConstructor<'fc> {
/// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed /// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed
/// to happen. /// to happen.
fn build_flow_for_block(&mut self, node: ThreadSafeLayoutNode, is_fixed: bool) -> ~Flow { fn build_flow_for_block(&mut self, node: ThreadSafeLayoutNode, is_fixed: bool) -> ~Flow {
let base = BaseFlow::new(self.next_flow_id(), node); let mut flow = ~BlockFlow::from_node(self, node, is_fixed) as ~Flow;
let box_ = self.build_box_for_node(node);
let mut flow = ~BlockFlow::from_box(base, box_, is_fixed) as ~Flow;
self.build_children_of_block_flow(&mut flow, node); self.build_children_of_block_flow(&mut flow, node);
flow flow
} }
@ -402,10 +400,7 @@ impl<'fc> FlowConstructor<'fc> {
/// a `BlockFlow` underneath it. /// a `BlockFlow` underneath it.
fn build_flow_for_floated_block(&mut self, node: ThreadSafeLayoutNode, float_type: FloatType) fn build_flow_for_floated_block(&mut self, node: ThreadSafeLayoutNode, float_type: FloatType)
-> ~Flow { -> ~Flow {
let base = BaseFlow::new(self.next_flow_id(), node); let mut flow = ~BlockFlow::float_from_node(self, node, float_type) as ~Flow;
let box_ = self.build_box_for_node(node);
let mut flow = ~BlockFlow::float_from_box(base, float_type, box_) as ~Flow;
self.build_children_of_block_flow(&mut flow, node); self.build_children_of_block_flow(&mut flow, node);
flow flow
} }
@ -523,7 +518,7 @@ impl<'fc> FlowConstructor<'fc> {
fn set_inline_info_for_inline_child(&mut self, fn set_inline_info_for_inline_child(&mut self,
boxes: &~[&Box], boxes: &~[&Box],
parent_node: ThreadSafeLayoutNode) { parent_node: ThreadSafeLayoutNode) {
let parent_box = self.build_box_for_node(parent_node); let parent_box = Box::new(self, parent_node);
let font_style = parent_box.font_style(); let font_style = parent_box.font_style();
let font_group = self.font_context.get_resolved_font_for_style(&font_style); let font_group = self.font_context.get_resolved_font_for_style(&font_style);
let (font_ascent,font_descent) = font_group.borrow().with_mut( |fg| { let (font_ascent,font_descent) = font_group.borrow().with_mut( |fg| {
@ -578,7 +573,7 @@ impl<'fc> FlowConstructor<'fc> {
let construction_item = InlineBoxesConstructionItem(InlineBoxesConstructionResult { let construction_item = InlineBoxesConstructionItem(InlineBoxesConstructionResult {
splits: None, splits: None,
boxes: ~[ boxes: ~[
self.build_box_for_node(node) Box::new(self, node)
], ],
}); });
ConstructionItemConstructionResult(construction_item) ConstructionItemConstructionResult(construction_item)

View file

@ -9,9 +9,9 @@ use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::flow::{BaseFlow, FlowClass, Flow, InlineFlowClass}; use layout::flow::{BaseFlow, FlowClass, Flow, InlineFlowClass};
use layout::flow; use layout::flow;
use layout::float_context::FloatContext; use layout::float_context::{FloatContext, FloatLeft, PlacementInfo};
use layout::util::ElementMapping; use layout::util::ElementMapping;
use layout::float_context::{PlacementInfo, FloatLeft}; use layout::wrapper::ThreadSafeLayoutNode;
use extra::container::Deque; use extra::container::Deque;
use extra::ringbuf::RingBuf; use extra::ringbuf::RingBuf;
@ -466,18 +466,9 @@ pub struct InlineFlow {
} }
impl InlineFlow { impl InlineFlow {
pub fn new(base: BaseFlow) -> InlineFlow { pub fn from_boxes(id: int, node: ThreadSafeLayoutNode, boxes: ~[Box]) -> InlineFlow {
InlineFlow { InlineFlow {
base: base, base: BaseFlow::new(id, node),
boxes: ~[],
lines: ~[],
elems: ElementMapping::new(),
}
}
pub fn from_boxes(base: BaseFlow, boxes: ~[Box]) -> InlineFlow {
InlineFlow {
base: base,
boxes: boxes, boxes: boxes,
lines: ~[], lines: ~[],
elems: ElementMapping::new(), elems: ElementMapping::new(),