From 29876d2703336fc74a3857854839badc1bb58ceb Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Tue, 6 Dec 2016 14:07:08 -1000 Subject: [PATCH] Rework the way scroll roots are collected Collect scroll roots during the collect_stacking_context phase instead of during display list construction. This will be useful in order to collect containing block scroll roots as well as to give scroll roots sequential ids in the future. This change also pulls stacking context children out of the StackingContext struct itself, which should reduce very slightly the memory used by the finished display list. This also simplifies the DisplayListBuilder because it no longer has to maintain a stack of ScrollRootIds and StackingContextIds and can instead just rely on the program stack. --- components/gfx/display_list/mod.rs | 39 +-- components/layout/block.rs | 9 +- components/layout/display_list_builder.rs | 314 +++++++++++++--------- components/layout/flex.rs | 8 +- components/layout/flow.rs | 12 +- components/layout/inline.rs | 9 +- components/layout/list_item.rs | 8 +- components/layout/multicol.rs | 14 +- components/layout/sequential.rs | 6 +- components/layout/table.rs | 8 +- components/layout/table_caption.rs | 8 +- components/layout/table_cell.rs | 8 +- components/layout/table_colgroup.rs | 6 +- components/layout/table_row.rs | 8 +- components/layout/table_rowgroup.rs | 8 +- components/layout/table_wrapper.rs | 8 +- components/layout/traversal.rs | 23 +- 17 files changed, 224 insertions(+), 272 deletions(-) diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index eeb78f9f9e71..1de082bdf456 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -303,9 +303,6 @@ pub struct StackingContext { /// The scroll policy of this layer. pub scroll_policy: ScrollPolicy, - /// Children of this StackingContext. - pub children: Vec, - /// The id of the parent scrolling area that contains this StackingContext. pub parent_scroll_id: ScrollRootId, } @@ -338,7 +335,6 @@ impl StackingContext { perspective: perspective, establishes_3d_context: establishes_3d_context, scroll_policy: scroll_policy, - children: Vec::new(), parent_scroll_id: parent_scroll_id, } } @@ -359,32 +355,7 @@ impl StackingContext { ScrollRootId::root()) } - pub fn add_child(&mut self, mut child: StackingContext) { - child.update_overflow_for_all_children(); - self.children.push(child); - } - - pub fn child_at_mut(&mut self, index: usize) -> &mut StackingContext { - &mut self.children[index] - } - - pub fn children(&self) -> &[StackingContext] { - &self.children - } - - fn update_overflow_for_all_children(&mut self) { - for child in self.children.iter() { - if self.context_type == StackingContextType::Real && - child.context_type == StackingContextType::Real { - // This child might be transformed, so we need to take into account - // its transformed overflow rect too, but at the correct position. - let overflow = child.overflow_rect_in_parent_space(); - self.overflow = self.overflow.union(&overflow); - } - } - } - - fn overflow_rect_in_parent_space(&self) -> Rect { + pub fn overflow_rect_in_parent_space(&self) -> Rect { // Transform this stacking context to get it into the same space as // the parent stacking context. // @@ -402,14 +373,6 @@ impl StackingContext { f32_rect_to_au_rect(overflow) } - pub fn print_with_tree(&self, print_tree: &mut PrintTree) { - print_tree.new_level(format!("{:?}", self)); - for kid in self.children() { - kid.print_with_tree(print_tree); - } - print_tree.end_level(); - } - pub fn to_display_list_items(self) -> (DisplayItem, DisplayItem) { let mut base_item = BaseDisplayItem::empty(); base_item.stacking_context_id = self.id; diff --git a/components/layout/block.rs b/components/layout/block.rs index bdb38742aaea..c2bdfedccfbb 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -42,8 +42,7 @@ use flow::IS_ABSOLUTELY_POSITIONED; use flow_list::FlowList; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{IS_INLINE_FLEX_ITEM, IS_BLOCK_FLEX_ITEM}; -use gfx::display_list::{ClippingRegion, StackingContext}; -use gfx_traits::ScrollRootId; +use gfx::display_list::ClippingRegion; use gfx_traits::print_tree::PrintTree; use layout_debug; use model::{AdjoiningMargins, CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo, MaybeAuto}; @@ -2195,10 +2194,8 @@ impl Flow for BlockFlow { } } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.collect_stacking_contexts_for_block(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.collect_stacking_contexts_for_block(state); } fn build_display_list(&mut self, state: &mut DisplayListBuildState) { diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 8dd881cd2772..a32253adc697 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -94,24 +94,30 @@ pub struct DisplayListBuildState<'a> { pub shared_layout_context: &'a SharedLayoutContext, pub root_stacking_context: StackingContext, pub items: HashMap>, + pub stacking_context_children: HashMap>, pub scroll_roots: HashMap, - pub stacking_context_id_stack: Vec, - pub scroll_root_id_stack: Vec, pub processing_scroll_root_element: bool, + + /// The current stacking context id, used to keep track of state when building. + /// recursively building and processing the display list. + pub current_stacking_context_id: StackingContextId, + + /// The current scroll root id, used to keep track of state when + /// recursively building and processing the display list. + pub current_scroll_root_id: ScrollRootId, } impl<'a> DisplayListBuildState<'a> { - pub fn new(shared_layout_context: &'a SharedLayoutContext, - stacking_context_id: StackingContextId) - -> DisplayListBuildState<'a> { + pub fn new(shared_layout_context: &'a SharedLayoutContext) -> DisplayListBuildState<'a> { DisplayListBuildState { shared_layout_context: shared_layout_context, root_stacking_context: StackingContext::root(), items: HashMap::new(), + stacking_context_children: HashMap::new(), scroll_roots: HashMap::new(), - stacking_context_id_stack: vec!(stacking_context_id), - scroll_root_id_stack: vec!(ScrollRootId::root()), processing_scroll_root_element: false, + current_stacking_context_id: StackingContextId::root(), + current_scroll_root_id: ScrollRootId::root(), } } @@ -120,40 +126,32 @@ impl<'a> DisplayListBuildState<'a> { items.push(display_item); } - fn add_scroll_root(&mut self, scroll_root: ScrollRoot) { - debug_assert!(!self.scroll_roots.contains_key(&scroll_root.id)); - self.scroll_roots.insert(scroll_root.id, scroll_root); - } - - pub fn stacking_context_id(&self) -> StackingContextId { - self.stacking_context_id_stack.last().unwrap().clone() + fn add_stacking_context(&mut self, + parent_id: StackingContextId, + mut stacking_context: StackingContext) { + self.update_overflow_for_stacking_context(&mut stacking_context); + self.add_stacking_context_without_calcuating_overflow(parent_id, stacking_context); } - pub fn push_stacking_context_id(&mut self, stacking_context_id: StackingContextId) { - self.stacking_context_id_stack.push(stacking_context_id); + fn add_stacking_context_without_calcuating_overflow(&mut self, + parent_id: StackingContextId, + stacking_context: StackingContext) { + let contexts = self.stacking_context_children.entry(parent_id).or_insert(Vec::new()); + contexts.push(stacking_context); } - pub fn pop_stacking_context_id(&mut self) { - assert!(!self.stacking_context_id_stack.is_empty()); - self.stacking_context_id_stack.pop(); - } - - pub fn scroll_root_id(&self) -> ScrollRootId { - self.scroll_root_id_stack.last().unwrap().clone() - } - - pub fn parent_scroll_root_id(&self) -> ScrollRootId { - debug_assert!(self.scroll_root_id_stack.len() > 1); - self.scroll_root_id_stack[self.scroll_root_id_stack.len() - 2] + fn add_scroll_root(&mut self, scroll_root: ScrollRoot) { + debug_assert!(!self.scroll_roots.contains_key(&scroll_root.id)); + self.scroll_roots.insert(scroll_root.id, scroll_root); } - pub fn push_scroll_root_id(&mut self, id: ScrollRootId) { - self.scroll_root_id_stack.push(id); - } + fn parent_scroll_root_id(&self, scroll_root_id: ScrollRootId) -> ScrollRootId { + if scroll_root_id == ScrollRootId::root() { + return ScrollRootId::root() + } - pub fn pop_scroll_root_id(&mut self) { - self.scroll_root_id_stack.pop(); - assert!(!self.scroll_root_id_stack.is_empty()); + debug_assert!(self.scroll_roots.contains_key(&scroll_root_id)); + self.scroll_roots.get(&scroll_root_id).unwrap().parent_id } fn create_base_display_item(&self, @@ -166,9 +164,9 @@ impl<'a> DisplayListBuildState<'a> { let scroll_root_id = if (section == DisplayListSection::BackgroundAndBorders || section == DisplayListSection::BlockBackgroundsAndBorders) && self.processing_scroll_root_element { - self.parent_scroll_root_id() + self.parent_scroll_root_id(self.current_scroll_root_id) } else { - self.scroll_root_id() + self.current_scroll_root_id }; BaseDisplayItem::new(&bounds, @@ -178,7 +176,7 @@ impl<'a> DisplayListBuildState<'a> { }, &clip, section, - self.stacking_context_id(), + self.current_stacking_context_id, scroll_root_id) } @@ -196,16 +194,34 @@ impl<'a> DisplayListBuildState<'a> { } } + fn update_overflow_for_stacking_context(&mut self, stacking_context: &mut StackingContext) { + if stacking_context.context_type != StackingContextType::Real { + return; + } + + let children = self.stacking_context_children.get_mut(&stacking_context.id); + if let Some(children) = children { + for child in children { + if child.context_type == StackingContextType::Real { + // This child might be transformed, so we need to take into account + // its transformed overflow rect too, but at the correct position. + let overflow = child.overflow_rect_in_parent_space(); + stacking_context.overflow = stacking_context.overflow.union(&overflow); + } + } + } + } + fn to_display_list_for_stacking_context(&mut self, list: &mut Vec, - mut stacking_context: StackingContext, + stacking_context: StackingContext, scroll_root_stack: &mut Vec) { let mut child_items = self.items.remove(&stacking_context.id).unwrap_or(Vec::new()); child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section)); child_items.reverse(); let mut child_stacking_contexts = - mem::replace(&mut stacking_context.children, Vec::new()); + self.stacking_context_children.remove(&stacking_context.id).unwrap_or_else(Vec::new); child_stacking_contexts.sort(); let real_stacking_context = stacking_context.context_type == StackingContextType::Real; @@ -1772,92 +1788,152 @@ impl FragmentDisplayListBuilding for Fragment { } pub trait BlockFlowDisplayListBuilding { - fn collect_stacking_contexts_for_block(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId); + fn collect_stacking_contexts_for_block(&mut self, state: &mut DisplayListBuildState); + fn collect_scroll_root_for_block(&mut self, state: &mut DisplayListBuildState) -> ScrollRootId; + fn create_pseudo_stacking_context_for_block(&mut self, + stacking_context_id: StackingContextId, + parent_stacking_context_id: StackingContextId, + parent_scroll_root_id: ScrollRootId, + state: &mut DisplayListBuildState); + fn create_real_stacking_context_for_block(&mut self, + stacking_context_id: StackingContextId, + parent_stacking_context_id: StackingContextId, + parent_scroll_root_id: ScrollRootId, + state: &mut DisplayListBuildState); fn build_display_list_for_block(&mut self, state: &mut DisplayListBuildState, border_painting_mode: BorderPaintingMode); } impl BlockFlowDisplayListBuilding for BlockFlow { - fn collect_stacking_contexts_for_block(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - let scroll_root_id = if self.has_scrolling_overflow() { - ScrollRootId::new_of_type(self.fragment.node.id() as usize, - self.fragment.fragment_type()) - } else { - parent_scroll_root_id - }; - self.base.scroll_root_id = scroll_root_id; + fn collect_stacking_contexts_for_block(&mut self, state: &mut DisplayListBuildState) { + let parent_scroll_root_id = state.current_scroll_root_id; + self.base.scroll_root_id = self.collect_scroll_root_for_block(state); + state.current_scroll_root_id = self.base.scroll_root_id; let block_stacking_context_type = self.block_stacking_context_type(); if block_stacking_context_type == BlockStackingContextType::NonstackingContext { - self.base.stacking_context_id = parent.id; - self.base.collect_stacking_contexts_for_children(parent, scroll_root_id); - return; + self.base.stacking_context_id = state.current_stacking_context_id; + self.base.collect_stacking_contexts_for_children(state); + } else { + let parent_stacking_context_id = state.current_stacking_context_id; + let stacking_context_id = + StackingContextId::new_of_type(self.fragment.node.id() as usize, + self.fragment.fragment_type()); + state.current_stacking_context_id = stacking_context_id; + self.base.stacking_context_id = stacking_context_id; + + if block_stacking_context_type == BlockStackingContextType::PseudoStackingContext { + self.create_pseudo_stacking_context_for_block(stacking_context_id, + parent_stacking_context_id, + parent_scroll_root_id, + state); + } else { + self.create_real_stacking_context_for_block(stacking_context_id, + parent_stacking_context_id, + parent_scroll_root_id, + state); + } + + state.current_stacking_context_id = parent_stacking_context_id; } - let stacking_context_id = StackingContextId::new_of_type(self.fragment.node.id() as usize, - self.fragment.fragment_type()); - self.base.stacking_context_id = stacking_context_id; + state.current_scroll_root_id = parent_scroll_root_id; + } - if block_stacking_context_type == BlockStackingContextType::PseudoStackingContext { - let creation_mode = if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) || - self.fragment.style.get_box().position != position::T::static_ { - StackingContextCreationMode::PseudoPositioned - } else { - assert!(self.base.flags.is_float()); - StackingContextCreationMode::PseudoFloat - }; + fn collect_scroll_root_for_block(&mut self, state: &mut DisplayListBuildState) -> ScrollRootId { + if !self.has_scrolling_overflow() { + return state.current_scroll_root_id; + } - let mut new_context = self.fragment.create_stacking_context(stacking_context_id, - &self.base, - ScrollPolicy::Scrollable, - creation_mode, - parent_scroll_root_id); - self.base.collect_stacking_contexts_for_children(&mut new_context, scroll_root_id); - let new_children: Vec = new_context.children.drain(..).collect(); - - let mut non_floating_children = Vec::new(); - for child in new_children { - if child.context_type == StackingContextType::PseudoFloat { - new_context.children.push(child); - } else { - non_floating_children.push(child); - } + let scroll_root_id = ScrollRootId::new_of_type(self.fragment.node.id() as usize, + self.fragment.fragment_type()); + let coordinate_system = if self.fragment.establishes_stacking_context() { + CoordinateSystem::Own + } else { + CoordinateSystem::Parent + }; + + let border_box = self.fragment.stacking_relative_border_box( + &self.base.stacking_relative_position, + &self.base.early_absolute_position_info.relative_containing_block_size, + self.base.early_absolute_position_info.relative_containing_block_mode, + coordinate_system); + + let parent_scroll_root_id = state.current_scroll_root_id; + state.add_scroll_root( + ScrollRoot { + id: scroll_root_id, + parent_id: parent_scroll_root_id, + clip: self.fragment.stacking_relative_content_box(&border_box), + size: self.base.overflow.scroll.size, } + ); + scroll_root_id + } - parent.add_child(new_context); - parent.children.append(&mut non_floating_children); - return; + fn create_pseudo_stacking_context_for_block(&mut self, + stacking_context_id: StackingContextId, + parent_stacking_context_id: StackingContextId, + parent_scroll_root_id: ScrollRootId, + state: &mut DisplayListBuildState) { + let creation_mode = if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) || + self.fragment.style.get_box().position != position::T::static_ { + StackingContextCreationMode::PseudoPositioned + } else { + assert!(self.base.flags.is_float()); + StackingContextCreationMode::PseudoFloat + }; + + let new_context = self.fragment.create_stacking_context(stacking_context_id, + &self.base, + ScrollPolicy::Scrollable, + creation_mode, + parent_scroll_root_id); + state.add_stacking_context(parent_stacking_context_id, new_context); + + self.base.collect_stacking_contexts_for_children(state); + + let new_children = + state.stacking_context_children.remove(&stacking_context_id).unwrap_or_else(Vec::new); + for child in new_children { + if child.context_type == StackingContextType::PseudoFloat { + state.add_stacking_context_without_calcuating_overflow(stacking_context_id, child); + } else { + state.add_stacking_context_without_calcuating_overflow(parent_stacking_context_id, + child); + } } + } + fn create_real_stacking_context_for_block(&mut self, + stacking_context_id: StackingContextId, + parent_stacking_context_id: StackingContextId, + parent_scroll_root_id: ScrollRootId, + state: &mut DisplayListBuildState) { let scroll_policy = if self.is_fixed() { ScrollPolicy::FixedPosition } else { ScrollPolicy::Scrollable }; - let mut stacking_context = self.fragment.create_stacking_context( + let stacking_context = self.fragment.create_stacking_context( stacking_context_id, &self.base, scroll_policy, StackingContextCreationMode::Normal, parent_scroll_root_id); - self.base.collect_stacking_contexts_for_children(&mut stacking_context, scroll_root_id); - parent.add_child(stacking_context); + state.add_stacking_context(parent_stacking_context_id, stacking_context); + self.base.collect_stacking_contexts_for_children(state); } fn build_display_list_for_block(&mut self, state: &mut DisplayListBuildState, border_painting_mode: BorderPaintingMode) { - let establishes_stacking_context = self.fragment.establishes_stacking_context(); let background_border_section = if self.base.flags.is_float() { DisplayListSection::BackgroundAndBorders } else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { - if establishes_stacking_context { + if self.fragment.establishes_stacking_context() { DisplayListSection::BackgroundAndBorders } else { DisplayListSection::BlockBackgroundsAndBorders @@ -1867,29 +1943,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { }; if self.has_scrolling_overflow() { - let size = self.base.overflow.scroll.size; - let coordinate_system = if establishes_stacking_context { - CoordinateSystem::Own - } else { - CoordinateSystem::Parent - }; - - let border_box = self.fragment.stacking_relative_border_box( - &self.base.stacking_relative_position, - &self.base.early_absolute_position_info.relative_containing_block_size, - self.base.early_absolute_position_info.relative_containing_block_mode, - coordinate_system); - - let parent_id = state.parent_scroll_root_id(); state.processing_scroll_root_element = true; - state.add_scroll_root( - ScrollRoot { - id: self.base.scroll_root_id, - parent_id: parent_id, - clip: self.fragment.stacking_relative_content_box(&border_box), - size: size, - } - ); } // Add the box that starts the block context. @@ -1914,9 +1968,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } pub trait InlineFlowDisplayListBuilding { - fn collect_stacking_contexts_for_inline(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId); + fn collect_stacking_contexts_for_inline(&mut self, state: &mut DisplayListBuildState); fn build_display_list_for_inline_fragment_at_index(&mut self, state: &mut DisplayListBuildState, index: usize); @@ -1924,34 +1976,35 @@ pub trait InlineFlowDisplayListBuilding { } impl InlineFlowDisplayListBuilding for InlineFlow { - fn collect_stacking_contexts_for_inline(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.base.stacking_context_id = parent.id; - self.base.scroll_root_id = parent_scroll_root_id; + fn collect_stacking_contexts_for_inline(&mut self, state: &mut DisplayListBuildState) { + self.base.stacking_context_id = state.current_stacking_context_id; + self.base.scroll_root_id = state.current_scroll_root_id; for mut fragment in self.fragments.fragments.iter_mut() { match fragment.specific { SpecificFragmentInfo::InlineBlock(ref mut block_flow) => { let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref); - block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + block_flow.collect_stacking_contexts(state); } SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => { let block_flow = FlowRef::deref_mut(&mut block_flow.flow_ref); - block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + block_flow.collect_stacking_contexts(state); } _ if fragment.establishes_stacking_context() => { fragment.stacking_context_id = StackingContextId::new_of_type(fragment.fragment_id(), fragment.fragment_type()); - parent.add_child(fragment.create_stacking_context( - fragment.stacking_context_id, - &self.base, - ScrollPolicy::Scrollable, - StackingContextCreationMode::Normal, - parent_scroll_root_id)); + let current_stacking_context_id = state.current_stacking_context_id; + let current_scroll_root_id = state.current_scroll_root_id; + state.add_stacking_context(current_stacking_context_id, + fragment.create_stacking_context( + fragment.stacking_context_id, + &self.base, + ScrollPolicy::Scrollable, + StackingContextCreationMode::Normal, + current_scroll_root_id)); } - _ => fragment.stacking_context_id = parent.id, + _ => fragment.stacking_context_id = state.current_stacking_context_id, } } } @@ -1988,14 +2041,15 @@ impl InlineFlowDisplayListBuilding for InlineFlow { fragment.stacking_context_id) }; + let parent_stacking_context_id = state.current_stacking_context_id; if establishes_stacking_context { - state.push_stacking_context_id(stacking_context_id); + state.current_stacking_context_id = stacking_context_id; } self.build_display_list_for_inline_fragment_at_index(state, index); if establishes_stacking_context { - state.pop_stacking_context_id(); + state.current_stacking_context_id = parent_stacking_context_id } } diff --git a/components/layout/flex.rs b/components/layout/flex.rs index c40c6a1b4331..2a45e5f4514f 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -16,8 +16,6 @@ use flow; use flow::{Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow}; use flow::{INLINE_POSITION_IS_STATIC, IS_ABSOLUTELY_POSITIONED}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use layout_debug; use model::{IntrinsicISizes, MaybeAuto, SizeConstraint}; use model::{specified, specified_or_none}; @@ -967,10 +965,8 @@ impl Flow for FlexFlow { self.build_display_list_for_flex(state); } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 34fcd3bf300f..3c171738fb73 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -35,7 +35,7 @@ use floats::{Floats, SpeculatedFloatPlacement}; use flow_list::{FlowList, MutFlowListIterator}; use flow_ref::{FlowRef, WeakFlowRef}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::{ClippingRegion, StackingContext}; +use gfx::display_list::ClippingRegion; use gfx_traits::{ScrollRootId, StackingContextId}; use gfx_traits::print_tree::PrintTree; use inline::InlineFlow; @@ -221,9 +221,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static { None } - fn collect_stacking_contexts(&mut self, - _parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState); /// If this is a float, places it. The default implementation does nothing. fn place_float_if_applicable<'a>(&mut self) {} @@ -1115,11 +1113,9 @@ impl BaseFlow { return self as *const BaseFlow as usize; } - pub fn collect_stacking_contexts_for_children(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { + pub fn collect_stacking_contexts_for_children(&mut self, state: &mut DisplayListBuildState) { for kid in self.children.iter_mut() { - kid.collect_stacking_contexts(parent, parent_scroll_root_id); + kid.collect_stacking_contexts(state); } } diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 833d93c30397..2d591b1ee020 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -16,10 +16,9 @@ use flow::OpaqueFlow; use flow_ref::FlowRef; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::SpecificFragmentInfo; -use gfx::display_list::{OpaqueNode, StackingContext}; +use gfx::display_list::OpaqueNode; use gfx::font::FontMetrics; use gfx::font_context::FontContext; -use gfx_traits::ScrollRootId; use gfx_traits::print_tree::PrintTree; use layout_debug; use model::IntrinsicISizesContribution; @@ -1622,10 +1621,8 @@ impl Flow for InlineFlow { fn update_late_computed_block_position_if_necessary(&mut self, _: Au) {} - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.collect_stacking_contexts_for_inline(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.collect_stacking_contexts_for_inline(state); } fn build_display_list(&mut self, state: &mut DisplayListBuildState) { diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index 20cc7bfa8505..0ea9acf38c0f 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -17,8 +17,6 @@ use flow::{Flow, FlowClass, OpaqueFlow}; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, GeneratedContentInfo}; use fragment::Overflow; use generated_content; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use inline::InlineFlow; use std::sync::Arc; use style::computed_values::{list_style_type, position}; @@ -144,10 +142,8 @@ impl Flow for ListItemFlow { self.build_display_list_for_list_item(state); } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs index b5651369ebf7..5bb6f05ac96f 100644 --- a/components/layout/multicol.rs +++ b/components/layout/multicol.rs @@ -15,8 +15,6 @@ use euclid::Size2D; use floats::FloatKind; use flow::{Flow, FlowClass, OpaqueFlow, mut_base, FragmentationContext}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use gfx_traits::print_tree::PrintTree; use std::cmp::{min, max}; use std::fmt; @@ -188,10 +186,8 @@ impl Flow for MulticolFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { @@ -272,10 +268,8 @@ impl Flow for MulticolColumnFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index b8c62aaafb00..6dd0f8c440b9 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -14,7 +14,6 @@ use flow::{PostorderFlowTraversal, PreorderFlowTraversal}; use flow::IS_ABSOLUTELY_POSITIONED; use fragment::FragmentBorderBoxIterator; use generated_content::ResolveGeneratedContent; -use gfx_traits::ScrollRootId; use servo_config::opts; use style::servo::restyle_damage::{REFLOW, STORE_OVERFLOW}; use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList}; @@ -76,9 +75,8 @@ pub fn traverse_flow_tree_preorder(root: &mut Flow, pub fn build_display_list_for_subtree<'a>(flow_root: &mut Flow, shared_layout_context: &'a SharedLayoutContext) -> DisplayListBuildState<'a> { - let mut state = DisplayListBuildState::new(shared_layout_context, - flow::base(flow_root).stacking_context_id); - flow_root.collect_stacking_contexts(&mut state.root_stacking_context, ScrollRootId::root()); + let mut state = DisplayListBuildState::new(shared_layout_context); + flow_root.collect_stacking_contexts(&mut state); let mut build_display_list = BuildDisplayList { state: state }; build_display_list.traverse(flow_root); diff --git a/components/layout/table.rs b/components/layout/table.rs index 031cf2ab1976..9ad018f622e2 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -16,8 +16,6 @@ use flow; use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow}; use flow_list::MutFlowListIterator; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use gfx_traits::print_tree::PrintTree; use layout_debug; use model::{IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto}; @@ -501,10 +499,8 @@ impl Flow for TableFlow { self.block_flow.build_display_list_for_block(state, border_painting_mode); } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs index 523a1f0e0711..926aa872f6b5 100644 --- a/components/layout/table_caption.rs +++ b/components/layout/table_caption.rs @@ -13,8 +13,6 @@ use display_list_builder::DisplayListBuildState; use euclid::Point2D; use flow::{Flow, FlowClass, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use gfx_traits::print_tree::PrintTree; use std::fmt; use std::sync::Arc; @@ -83,10 +81,8 @@ impl Flow for TableCaptionFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index 5e20f195078d..15b3a42ed510 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -14,8 +14,6 @@ use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, Dis use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use gfx_traits::print_tree::PrintTree; use layout_debug; use model::MaybeAuto; @@ -262,10 +260,8 @@ impl Flow for TableCellFlow { self.block_flow.build_display_list_for_block(state, border_painting_mode) } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs index 468e0ffb285a..93a67a394ef5 100644 --- a/components/layout/table_colgroup.rs +++ b/components/layout/table_colgroup.rs @@ -12,8 +12,6 @@ use display_list_builder::DisplayListBuildState; use euclid::Point2D; use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo}; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use layout_debug; use std::cmp::max; use std::fmt; @@ -96,9 +94,7 @@ impl Flow for TableColGroupFlow { // Table columns are invisible. fn build_display_list(&mut self, _: &mut DisplayListBuildState) { } - fn collect_stacking_contexts(&mut self, - _parent: &mut StackingContext, - _parent_scroll_root_id: ScrollRootId) {} + fn collect_stacking_contexts(&mut self, _: &mut DisplayListBuildState) {} fn repair_style(&mut self, _: &Arc) {} diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index d4dddb1a4030..c6dba54ceec1 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -15,8 +15,6 @@ use euclid::Point2D; use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow}; use flow_list::MutFlowListIterator; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use gfx_traits::print_tree::PrintTree; use layout_debug; use model::MaybeAuto; @@ -481,10 +479,8 @@ impl Flow for TableRowFlow { self.block_flow.build_display_list_for_block(state, border_painting_mode); } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index a76d7a82ccfc..4b8f44757cde 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -13,8 +13,6 @@ use display_list_builder::DisplayListBuildState; use euclid::Point2D; use flow::{Flow, FlowClass, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use gfx_traits::print_tree::PrintTree; use layout_debug; use serde::{Serialize, Serializer}; @@ -184,10 +182,8 @@ impl Flow for TableRowGroupFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 7510ae3988ae..4f40a94e28e3 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -22,8 +22,6 @@ use euclid::Point2D; use floats::FloatKind; use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; -use gfx::display_list::StackingContext; -use gfx_traits::ScrollRootId; use gfx_traits::print_tree::PrintTree; use model::MaybeAuto; use std::cmp::{max, min}; @@ -462,10 +460,8 @@ impl Flow for TableWrapperFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, - parent: &mut StackingContext, - parent_scroll_root_id: ScrollRootId) { - self.block_flow.collect_stacking_contexts(parent, parent_scroll_root_id); + fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + self.block_flow.collect_stacking_contexts(state); } fn repair_style(&mut self, new_style: &Arc) { diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 0f7b1a3d89da..0b65d78df15d 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -232,17 +232,11 @@ pub struct BuildDisplayList<'a> { impl<'a> BuildDisplayList<'a> { #[inline] pub fn traverse(&mut self, flow: &mut Flow) { - let new_stacking_context = - flow::base(flow).stacking_context_id != self.state.stacking_context_id(); - if new_stacking_context { - self.state.push_stacking_context_id(flow::base(flow).stacking_context_id); - } + let parent_stacking_context_id = self.state.current_stacking_context_id; + self.state.current_stacking_context_id = flow::base(flow).stacking_context_id; - let new_scroll_root = - flow::base(flow).scroll_root_id != self.state.scroll_root_id(); - if new_scroll_root { - self.state.push_scroll_root_id(flow::base(flow).scroll_root_id); - } + let parent_scroll_root_id = self.state.current_scroll_root_id; + self.state.current_scroll_root_id = flow::base(flow).scroll_root_id; if self.should_process() { flow.build_display_list(&mut self.state); @@ -253,13 +247,8 @@ impl<'a> BuildDisplayList<'a> { self.traverse(kid); } - if new_stacking_context { - self.state.pop_stacking_context_id(); - } - - if new_scroll_root { - self.state.pop_scroll_root_id(); - } + self.state.current_stacking_context_id = parent_stacking_context_id; + self.state.current_scroll_root_id = parent_scroll_root_id; } #[inline]