diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-01-10 04:48:31 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-10 04:48:31 -0800 |
commit | dabb79c7878fce31b8b979dd5fcfdfb8713a9d80 (patch) | |
tree | 0ad536fc842868eb80081dde7513c151fe037ae2 /components/layout | |
parent | f54dd0112bd9e51b21e9a5ee38bb2cfc0326e071 (diff) | |
parent | 29876d2703336fc74a3857854839badc1bb58ceb (diff) | |
download | servo-dabb79c7878fce31b8b979dd5fcfdfb8713a9d80.tar.gz servo-dabb79c7878fce31b8b979dd5fcfdfb8713a9d80.zip |
Auto merge of #14603 - mrobinson:collect-scoll-roots, r=emilio
Rework the way scroll roots are collected
<!-- 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
- [ ] These changes fix #__ (github issue number if applicable).
<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because they should not change behavior.
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
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.
<!-- 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/14603)
<!-- Reviewable:end -->
Diffstat (limited to 'components/layout')
-rw-r--r-- | components/layout/block.rs | 9 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 314 | ||||
-rw-r--r-- | components/layout/flex.rs | 8 | ||||
-rw-r--r-- | components/layout/flow.rs | 12 | ||||
-rw-r--r-- | components/layout/inline.rs | 9 | ||||
-rw-r--r-- | components/layout/list_item.rs | 8 | ||||
-rw-r--r-- | components/layout/multicol.rs | 14 | ||||
-rw-r--r-- | components/layout/sequential.rs | 6 | ||||
-rw-r--r-- | components/layout/table.rs | 8 | ||||
-rw-r--r-- | components/layout/table_caption.rs | 8 | ||||
-rw-r--r-- | components/layout/table_cell.rs | 8 | ||||
-rw-r--r-- | components/layout/table_colgroup.rs | 6 | ||||
-rw-r--r-- | components/layout/table_row.rs | 8 | ||||
-rw-r--r-- | components/layout/table_rowgroup.rs | 8 | ||||
-rw-r--r-- | components/layout/table_wrapper.rs | 8 | ||||
-rw-r--r-- | components/layout/traversal.rs | 23 |
16 files changed, 223 insertions, 234 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs index bdb38742aae..c2bdfedccfb 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 8dd881cd277..a32253adc69 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<StackingContextId, Vec<DisplayItem>>, + pub stacking_context_children: HashMap<StackingContextId, Vec<StackingContext>>, pub scroll_roots: HashMap<ScrollRootId, ScrollRoot>, - pub stacking_context_id_stack: Vec<StackingContextId>, - pub scroll_root_id_stack: Vec<ScrollRootId>, 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<DisplayItem>, - mut stacking_context: StackingContext, + stacking_context: StackingContext, scroll_root_stack: &mut Vec<ScrollRootId>) { 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<StackingContext> = 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 c40c6a1b433..2a45e5f4514 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<ServoComputedValues>) { diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 34fcd3bf300..3c171738fb7 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 833d93c3039..2d591b1ee02 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 20cc7bfa850..0ea9acf38c0 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<ServoComputedValues>) { diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs index b5651369ebf..5bb6f05ac96 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<ServoComputedValues>) { @@ -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<ServoComputedValues>) { diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index b8c62aaafb0..6dd0f8c440b 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 031cf2ab197..9ad018f622e 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<ServoComputedValues>) { diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs index 523a1f0e071..926aa872f6b 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<ServoComputedValues>) { diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index 5e20f195078..15b3a42ed51 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<ServoComputedValues>) { diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs index 468e0ffb285..93a67a394ef 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<ServoComputedValues>) {} diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index d4dddb1a403..c6dba54ceec 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<ServoComputedValues>) { diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index a76d7a82ccf..4b8f44757cd 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<ServoComputedValues>) { diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 7510ae3988a..4f40a94e28e 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<ServoComputedValues>) { diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 0f7b1a3d89d..0b65d78df15 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] |