From ee46bc57ed1fcd4c26748e1ba3da47634bbf7be4 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 30 Aug 2017 20:03:44 +0200 Subject: [PATCH] Separate stacking context collection and display list building state These are two different passes during layout, but previously they shared a state object. While some of the members are the same, many are different so we separate them out into two separate objects. We also change the HashMaps of these state objects to use the FnvHashMap. --- components/layout/block.rs | 3 +- components/layout/display_list_builder.rs | 192 ++++++++++++++-------- components/layout/flex.rs | 3 +- components/layout/flow.rs | 7 +- components/layout/inline.rs | 3 +- components/layout/list_item.rs | 3 +- components/layout/multicol.rs | 6 +- components/layout/sequential.rs | 5 +- components/layout/table.rs | 3 +- components/layout/table_caption.rs | 4 +- components/layout/table_cell.rs | 3 +- components/layout/table_colgroup.rs | 4 +- components/layout/table_row.rs | 3 +- components/layout/table_rowgroup.rs | 4 +- components/layout/table_wrapper.rs | 4 +- 15 files changed, 153 insertions(+), 94 deletions(-) diff --git a/components/layout/block.rs b/components/layout/block.rs index 40bc9eb9413c..790003abc3af 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -31,6 +31,7 @@ use app_units::{Au, MAX_AU}; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; use display_list_builder::{DisplayListBuildState, EstablishContainingBlock}; +use display_list_builder::StackingContextCollectionState; use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; use floats::{ClearType, FloatKind, Floats, PlacementInfo}; use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag}; @@ -2150,7 +2151,7 @@ impl Flow for BlockFlow { } } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.collect_stacking_contexts_for_block(state, EstablishContainingBlock::Yes); } diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 6387c72ce3d2..cbd76a580c8d 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -18,6 +18,7 @@ use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, TypedSize2D}; use euclid::Vector2D; use flex::FlexFlow; use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED}; +use fnv::FnvHashMap; use flow_ref::FlowRef; use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ImageFragmentInfo, ScannedTextFragmentInfo}; use fragment::{SpecificFragmentInfo, TruncatedFragmentInfo}; @@ -35,7 +36,7 @@ use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT}; use ipc_channel::ipc; use list_item::ListItemFlow; use model::{self, MaybeAuto}; -use msg::constellation_msg::BrowsingContextId; +use msg::constellation_msg::{BrowsingContextId, PipelineId}; use net_traits::image::base::PixelFormat; use net_traits::image_cache::UsePlaceholder; use range::Range; @@ -44,7 +45,6 @@ use servo_config::opts; use servo_geometry::max_rect; use servo_url::ServoUrl; use std::{cmp, f32}; -use std::collections::HashMap; use std::default::Default; use std::mem; use std::sync::Arc; @@ -159,13 +159,18 @@ impl StackingContextInfo { } } -pub struct DisplayListBuildState<'a> { - pub layout_context: &'a LayoutContext<'a>, +pub struct StackingContextCollectionState { + /// The PipelineId of this stacking context collection. + pub pipeline_id: PipelineId, + + /// The root of the StackingContext tree. pub root_stacking_context: StackingContext, - pub items: HashMap>, - stacking_context_info: HashMap, - pub scroll_root_parents: HashMap, - pub processing_scroll_root_element: bool, + + /// StackingContext and ScrollRoot children for each StackingContext. + stacking_context_info: FnvHashMap, + + /// A map establishing the parent child relationship of every ScrollRoot. + pub scroll_root_parents: FnvHashMap, /// The current stacking context id, used to keep track of state when building. /// recursively building and processing the display list. @@ -183,10 +188,6 @@ pub struct DisplayListBuildState<'a> { /// by their containing block's scroll root. pub containing_block_clip_and_scroll_info: ClipAndScrollInfo, - /// Vector containing iframe sizes, used to inform the constellation about - /// new iframe sizes - pub iframe_sizes: Vec<(BrowsingContextId, TypedSize2D)>, - /// A stack of clips used to cull display list entries that are outside the /// rendered region. pub clip_stack: Vec>, @@ -199,32 +200,24 @@ pub struct DisplayListBuildState<'a> { parent_stacking_relative_content_box: Rect, } -impl<'a> DisplayListBuildState<'a> { - pub fn new(layout_context: &'a LayoutContext) -> DisplayListBuildState<'a> { - let root_clip_info = ClipAndScrollInfo::simple(layout_context.id.root_scroll_node()); - DisplayListBuildState { - layout_context: layout_context, - root_stacking_context: StackingContext::root(layout_context.id), - items: HashMap::new(), - stacking_context_info: HashMap::new(), - scroll_root_parents: HashMap::new(), - processing_scroll_root_element: false, +impl StackingContextCollectionState { + pub fn new(pipeline_id: PipelineId) -> StackingContextCollectionState { + let root_clip_info = ClipAndScrollInfo::simple(pipeline_id.root_scroll_node()); + StackingContextCollectionState { + pipeline_id: pipeline_id, + root_stacking_context: StackingContext::root(pipeline_id), + stacking_context_info: FnvHashMap::default(), + scroll_root_parents: FnvHashMap::default(), current_stacking_context_id: StackingContextId::root(), current_real_stacking_context_id: StackingContextId::root(), current_clip_and_scroll_info: root_clip_info, containing_block_clip_and_scroll_info: root_clip_info, - iframe_sizes: Vec::new(), clip_stack: Vec::new(), containing_block_clip_stack: Vec::new(), parent_stacking_relative_content_box: Rect::zero(), } } - fn add_display_item(&mut self, display_item: DisplayItem) { - let items = self.items.entry(display_item.stacking_context_id()).or_insert(Vec::new()); - items.push(display_item); - } - fn add_stacking_context(&mut self, parent_id: StackingContextId, stacking_context: StackingContext) { @@ -239,7 +232,7 @@ impl<'a> DisplayListBuildState<'a> { } fn add_scroll_root(&mut self, scroll_root: ScrollRoot) { - // We want the scroll root to be defined by another other possible item that could use it, + // We want the scroll root to be defined before any possible item that could use it, // so we make sure that it is added to the beginning of the parent "real" (non-pseudo) // stacking context. This ensures that item reordering will not result in an item using // the scroll root before it is defined. @@ -249,6 +242,63 @@ impl<'a> DisplayListBuildState<'a> { .or_insert(StackingContextInfo::new()); info.scroll_roots.push(scroll_root); } +} + +pub struct DisplayListBuildState<'a> { + /// A LayoutContext reference important for creating WebRender images. + pub layout_context: &'a LayoutContext<'a>, + + /// The root of the StackingContext tree. + pub root_stacking_context: StackingContext, + + /// StackingContext and ScrollRoot children for each StackingContext. + stacking_context_info: FnvHashMap, + + /// A map establishing the parent child relationship of every ScrollRoot. + pub scroll_root_parents: FnvHashMap, + + /// The items in this display list. + pub items: FnvHashMap>, + + /// Whether or not we are processing an element that establishes a scroll root, used + /// to determine what ScrollRoot to place backgrounds and borders into. + 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 clip and scroll info, used to keep track of state when + /// recursively building and processing the display list. + pub current_clip_and_scroll_info: ClipAndScrollInfo, + + /// Vector containing iframe sizes, used to inform the constellation about + /// new iframe sizes + pub iframe_sizes: Vec<(BrowsingContextId, TypedSize2D)>, +} + +impl<'a> DisplayListBuildState<'a> { + pub fn new(layout_context: &'a LayoutContext, + state: StackingContextCollectionState) + -> DisplayListBuildState<'a> { + let root_clip_info = ClipAndScrollInfo::simple(layout_context.id.root_scroll_node()); + DisplayListBuildState { + layout_context: layout_context, + root_stacking_context: state.root_stacking_context, + items: FnvHashMap::default(), + stacking_context_info: state.stacking_context_info, + scroll_root_parents: state.scroll_root_parents, + processing_scroll_root_element: false, + current_stacking_context_id: StackingContextId::root(), + current_clip_and_scroll_info: root_clip_info, + iframe_sizes: Vec::new(), + } + } + + fn add_display_item(&mut self, display_item: DisplayItem) { + let items = self.items.entry(display_item.stacking_context_id()).or_insert(Vec::new()); + items.push(display_item); + } fn parent_scroll_root_id(&self, scroll_root_id: ClipId) -> ClipId { if scroll_root_id.is_root_scroll_node() { @@ -2268,47 +2318,47 @@ pub enum EstablishContainingBlock { pub trait BlockFlowDisplayListBuilding { fn collect_stacking_contexts_for_block(&mut self, - state: &mut DisplayListBuildState, + state: &mut StackingContextCollectionState, can_establish_containing_block: EstablishContainingBlock); fn transform_clip_to_coordinate_space(&mut self, - state: &mut DisplayListBuildState, - preserved_state: &mut PreservedDisplayListState); + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState); fn setup_clipping_for_block(&mut self, - state: &mut DisplayListBuildState, - preserved_state: &mut PreservedDisplayListState, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, stacking_context_type: BlockStackingContextType, can_establish_containing_block: EstablishContainingBlock) -> ClipAndScrollInfo; fn setup_scroll_root_for_position(&mut self, - state: &mut DisplayListBuildState, + state: &mut StackingContextCollectionState, border_box: &Rect); fn setup_scroll_root_for_overflow(&mut self, - state: &mut DisplayListBuildState, + state: &mut StackingContextCollectionState, border_box: &Rect); fn setup_scroll_root_for_css_clip(&mut self, - state: &mut DisplayListBuildState, - preserved_state: &mut PreservedDisplayListState, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, stacking_relative_border_box: &Rect); fn create_pseudo_stacking_context_for_block(&mut self, parent_stacking_context_id: StackingContextId, parent_clip_and_scroll_info: ClipAndScrollInfo, - state: &mut DisplayListBuildState); + state: &mut StackingContextCollectionState); fn create_real_stacking_context_for_block(&mut self, parent_stacking_context_id: StackingContextId, parent_clip_and_scroll_info: ClipAndScrollInfo, - state: &mut DisplayListBuildState); + state: &mut StackingContextCollectionState); fn build_display_list_for_block(&mut self, state: &mut DisplayListBuildState, border_painting_mode: BorderPaintingMode); } -/// This structure manages ensuring that modification to DisplayListBuildState -/// is only temporary. It's useful for moving recursively down the flow tree -/// and ensuring that the state is restored for siblings. To use this structure, -/// we must call PreservedDisplayListState::restore in order to restore the state. +/// This structure manages ensuring that modification to StackingContextCollectionState is +/// only temporary. It's useful for moving recursively down the flow tree and ensuring +/// that the state is restored for siblings. To use this structure, we must call +/// SavedStackingContextCollectionState::restore in order to restore the state. /// TODO(mrobinson): It would be nice to use RAII here to avoid having to call restore. -pub struct PreservedDisplayListState { +pub struct SavedStackingContextCollectionState { stacking_context_id: StackingContextId, real_stacking_context_id: StackingContextId, clip_and_scroll_info: ClipAndScrollInfo, @@ -2318,9 +2368,9 @@ pub struct PreservedDisplayListState { stacking_relative_content_box: Rect, } -impl PreservedDisplayListState { - fn new(state: &mut DisplayListBuildState) -> PreservedDisplayListState { - PreservedDisplayListState { +impl SavedStackingContextCollectionState { + fn new(state: &mut StackingContextCollectionState) -> SavedStackingContextCollectionState { + SavedStackingContextCollectionState { stacking_context_id: state.current_stacking_context_id, real_stacking_context_id: state.current_real_stacking_context_id, clip_and_scroll_info: state.current_clip_and_scroll_info, @@ -2331,13 +2381,13 @@ impl PreservedDisplayListState { } } - fn switch_to_containing_block_clip(&mut self, state: &mut DisplayListBuildState) { + fn switch_to_containing_block_clip(&mut self, state: &mut StackingContextCollectionState) { let clip = state.containing_block_clip_stack.last().cloned().unwrap_or_else(max_rect); state.clip_stack.push(clip); self.clips_pushed += 1; } - fn restore(self, state: &mut DisplayListBuildState) { + fn restore(self, state: &mut StackingContextCollectionState) { state.current_stacking_context_id = self.stacking_context_id; state.current_real_stacking_context_id = self.real_stacking_context_id; state.current_clip_and_scroll_info = self.clip_and_scroll_info; @@ -2353,7 +2403,7 @@ impl PreservedDisplayListState { } fn push_clip(&mut self, - state: &mut DisplayListBuildState, + state: &mut StackingContextCollectionState, clip: &Rect, positioning: position::T) { let mut clip = *clip; @@ -2375,8 +2425,8 @@ impl PreservedDisplayListState { impl BlockFlowDisplayListBuilding for BlockFlow { fn transform_clip_to_coordinate_space(&mut self, - state: &mut DisplayListBuildState, - preserved_state: &mut PreservedDisplayListState) { + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState) { if state.clip_stack.is_empty() { return; } @@ -2434,9 +2484,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } fn collect_stacking_contexts_for_block(&mut self, - state: &mut DisplayListBuildState, + state: &mut StackingContextCollectionState, can_establish_containing_block: EstablishContainingBlock) { - let mut preserved_state = PreservedDisplayListState::new(state); + let mut preserved_state = SavedStackingContextCollectionState::new(state); let block_stacking_context_type = self.block_stacking_context_type(); self.base.stacking_context_id = match block_stacking_context_type { @@ -2485,8 +2535,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } fn setup_clipping_for_block(&mut self, - state: &mut DisplayListBuildState, - preserved_state: &mut PreservedDisplayListState, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, stacking_context_type: BlockStackingContextType, can_establish_containing_block: EstablishContainingBlock) -> ClipAndScrollInfo { @@ -2543,7 +2593,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } fn setup_scroll_root_for_position(&mut self, - state: &mut DisplayListBuildState, + state: &mut StackingContextCollectionState, border_box: &Rect) { if self.positioning() != position::T::sticky { return; @@ -2591,8 +2641,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { to_max_offset(constraint_rect.max_x(), border_box_in_parent.max_x()))); let new_scroll_root_id = ClipId::new(self.fragment.unique_id(IdType::OverflowClip), - state.layout_context.id.to_webrender()); - let parent_id = self.clip_and_scroll_info(state.layout_context.id).scroll_node_id; + state.pipeline_id.to_webrender()); + let parent_id = self.clip_and_scroll_info(state.pipeline_id).scroll_node_id; state.add_scroll_root( ScrollRoot { id: new_scroll_root_id, @@ -2609,7 +2659,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } fn setup_scroll_root_for_overflow(&mut self, - state: &mut DisplayListBuildState, + state: &mut StackingContextCollectionState, border_box: &Rect) { if !self.overflow_style_may_require_scroll_root() { return; @@ -2632,7 +2682,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // when fragments map to more than one flow, such as in the case of table // wrappers. We just accept the first scroll root in that case. let new_scroll_root_id = ClipId::new(self.fragment.unique_id(IdType::OverflowClip), - state.layout_context.id.to_webrender()); + state.pipeline_id.to_webrender()); if state.has_scroll_root(new_scroll_root_id) { return; } @@ -2654,7 +2704,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { let content_size = self.base.overflow.scroll.origin + self.base.overflow.scroll.size; let content_size = Size2D::new(content_size.x, content_size.y); - let parent_id = self.clip_and_scroll_info(state.layout_context.id).scroll_node_id; + let parent_id = self.clip_and_scroll_info(state.pipeline_id).scroll_node_id; state.add_scroll_root( ScrollRoot { id: new_scroll_root_id, @@ -2673,8 +2723,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { /// Adds a scroll root for a block to take the `clip` property into account /// per CSS 2.1 § 11.1.2. fn setup_scroll_root_for_css_clip(&mut self, - state: &mut DisplayListBuildState, - preserved_state: &mut PreservedDisplayListState, + state: &mut StackingContextCollectionState, + preserved_state: &mut SavedStackingContextCollectionState, stacking_relative_border_box: &Rect) { // Account for `clip` per CSS 2.1 § 11.1.2. let style_clip_rect = match self.fragment.style().get_effects().clip { @@ -2702,7 +2752,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // TODO(mrobinson): This should be more resilient while maintaining the space // efficiency of ScrollRootId. let new_scroll_root_id = ClipId::new(self.fragment.unique_id(IdType::CSSClip), - state.layout_context.id.to_webrender()); + state.pipeline_id.to_webrender()); // If we already have a scroll root for this flow, just return. This can happen // when fragments map to more than one flow, such as in the case of table @@ -2714,7 +2764,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { let clip_rect = Rect::new(clip_origin, clip_size); preserved_state.push_clip(state, &clip_rect, self.positioning()); - let parent_id = self.clip_and_scroll_info(state.layout_context.id).scroll_node_id; + let parent_id = self.clip_and_scroll_info(state.pipeline_id).scroll_node_id; state.add_scroll_root( ScrollRoot { id: new_scroll_root_id, @@ -2733,7 +2783,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { fn create_pseudo_stacking_context_for_block(&mut self, parent_stacking_context_id: StackingContextId, parent_clip_and_scroll_info: ClipAndScrollInfo, - state: &mut DisplayListBuildState) { + state: &mut StackingContextCollectionState) { let creation_mode = if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) || self.fragment.style.get_box().position != position::T::static_ { StackingContextType::PseudoPositioned @@ -2767,7 +2817,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { fn create_real_stacking_context_for_block(&mut self, parent_stacking_context_id: StackingContextId, parent_clip_and_scroll_info: ClipAndScrollInfo, - state: &mut DisplayListBuildState) { + state: &mut StackingContextCollectionState) { let scroll_policy = if self.is_fixed() { ScrollPolicy::Fixed } else { @@ -2824,7 +2874,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } pub trait InlineFlowDisplayListBuilding { - fn collect_stacking_contexts_for_inline(&mut self, state: &mut DisplayListBuildState); + fn collect_stacking_contexts_for_inline(&mut self, state: &mut StackingContextCollectionState); fn build_display_list_for_inline_fragment_at_index(&mut self, state: &mut DisplayListBuildState, index: usize); @@ -2832,7 +2882,7 @@ pub trait InlineFlowDisplayListBuilding { } impl InlineFlowDisplayListBuilding for InlineFlow { - fn collect_stacking_contexts_for_inline(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts_for_inline(&mut self, state: &mut StackingContextCollectionState) { self.base.stacking_context_id = state.current_stacking_context_id; self.base.clip_and_scroll_info = Some(state.current_clip_and_scroll_info); self.base.clip = state.clip_stack.last().cloned().unwrap_or_else(max_rect); diff --git a/components/layout/flex.rs b/components/layout/flex.rs index 14e02aa6fb2b..dbfe7840ff54 100644 --- a/components/layout/flex.rs +++ b/components/layout/flex.rs @@ -10,6 +10,7 @@ use app_units::{Au, MAX_AU}; use block::{AbsoluteAssignBSizesTraversal, BlockFlow, MarginsMayCollapseFlag}; use context::LayoutContext; use display_list_builder::{DisplayListBuildState, FlexFlowDisplayListBuilding}; +use display_list_builder::StackingContextCollectionState; use euclid::Point2D; use floats::FloatKind; use flow; @@ -988,7 +989,7 @@ impl Flow for FlexFlow { self.build_display_list_for_flex(state); } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts(state); } diff --git a/components/layout/flow.rs b/components/layout/flow.rs index f4c545ec730b..24a8a6c3cb28 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -28,7 +28,7 @@ use app_units::Au; use block::{BlockFlow, FormattingContextType}; use context::LayoutContext; -use display_list_builder::DisplayListBuildState; +use display_list_builder::{DisplayListBuildState, StackingContextCollectionState}; use euclid::{Transform3D, Point2D, Vector2D, Rect, Size2D}; use flex::FlexFlow; use floats::{Floats, SpeculatedFloatPlacement}; @@ -223,7 +223,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static { None } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState); + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState); /// If this is a float, places it. The default implementation does nothing. fn place_float_if_applicable<'a>(&mut self) {} @@ -1106,7 +1106,8 @@ impl BaseFlow { return self as *const BaseFlow as usize; } - pub fn collect_stacking_contexts_for_children(&mut self, state: &mut DisplayListBuildState) { + pub fn collect_stacking_contexts_for_children(&mut self, + state: &mut StackingContextCollectionState) { for kid in self.children.iter_mut() { kid.collect_stacking_contexts(state); } diff --git a/components/layout/inline.rs b/components/layout/inline.rs index f07943fd3218..40ccf8380e0f 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -9,6 +9,7 @@ use app_units::{Au, MIN_AU}; use block::AbsoluteAssignBSizesTraversal; use context::LayoutContext; use display_list_builder::{DisplayListBuildState, InlineFlowDisplayListBuilding}; +use display_list_builder::StackingContextCollectionState; use euclid::{Point2D, Size2D}; use floats::{FloatKind, Floats, PlacementInfo}; use flow::{self, BaseFlow, Flow, FlowClass, ForceNonfloatedFlag}; @@ -1655,7 +1656,7 @@ impl Flow for InlineFlow { fn update_late_computed_block_position_if_necessary(&mut self, _: Au) {} - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.collect_stacking_contexts_for_inline(state); } diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index 22d2f8786d01..a83464112856 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -11,6 +11,7 @@ use app_units::Au; use block::BlockFlow; use context::{LayoutContext, with_thread_local_font_context}; use display_list_builder::{DisplayListBuildState, ListItemFlowDisplayListBuilding}; +use display_list_builder::StackingContextCollectionState; use euclid::Point2D; use floats::FloatKind; use flow::{Flow, FlowClass, OpaqueFlow}; @@ -147,7 +148,7 @@ impl Flow for ListItemFlow { self.build_display_list_for_list_item(state); } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts(state); } diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs index 3e7cb66c2c9e..e2294e55c1d7 100644 --- a/components/layout/multicol.rs +++ b/components/layout/multicol.rs @@ -10,7 +10,7 @@ use ServoArc; use app_units::Au; use block::BlockFlow; use context::LayoutContext; -use display_list_builder::DisplayListBuildState; +use display_list_builder::{DisplayListBuildState, StackingContextCollectionState}; use euclid::{Point2D, Vector2D}; use floats::FloatKind; use flow::{Flow, FlowClass, OpaqueFlow, mut_base, FragmentationContext}; @@ -189,7 +189,7 @@ impl Flow for MulticolFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts(state); } @@ -279,7 +279,7 @@ impl Flow for MulticolColumnFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts(state); } diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 6673ecc8e14c..86a7d90142fb 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -6,7 +6,7 @@ use app_units::Au; use context::LayoutContext; -use display_list_builder::DisplayListBuildState; +use display_list_builder::{DisplayListBuildState, StackingContextCollectionState}; use euclid::{Point2D, Vector2D}; use floats::SpeculatedFloatPlacement; use flow::{self, Flow, ImmutableFlowUtils, IS_ABSOLUTELY_POSITIONED}; @@ -69,9 +69,10 @@ pub fn reflow(root: &mut Flow, layout_context: &LayoutContext, relayout_mode: Re pub fn build_display_list_for_subtree<'a>(flow_root: &mut Flow, layout_context: &'a LayoutContext) -> DisplayListBuildState<'a> { - let mut state = DisplayListBuildState::new(layout_context); + let mut state = StackingContextCollectionState::new(layout_context.id); flow_root.collect_stacking_contexts(&mut state); + let state = DisplayListBuildState::new(layout_context, state); let mut build_display_list = BuildDisplayList { state: state, }; diff --git a/components/layout/table.rs b/components/layout/table.rs index 2659b2605011..74dcca539ede 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -12,6 +12,7 @@ use block::{ISizeConstraintInput, ISizeConstraintSolution}; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; use display_list_builder::{DisplayListBuildState, EstablishContainingBlock}; +use display_list_builder::StackingContextCollectionState; use euclid::Point2D; use flow; use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow}; @@ -503,7 +504,7 @@ impl Flow for TableFlow { self.block_flow.build_display_list_for_block(state, border_painting_mode); } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::Yes); } diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs index 39e20d95bbf2..2ee55382f6cd 100644 --- a/components/layout/table_caption.rs +++ b/components/layout/table_caption.rs @@ -10,7 +10,7 @@ use app_units::Au; use block::BlockFlow; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState}; -use display_list_builder::EstablishContainingBlock; +use display_list_builder::{EstablishContainingBlock, StackingContextCollectionState}; use euclid::Point2D; use flow::{Flow, FlowClass, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; @@ -80,7 +80,7 @@ impl Flow for TableCaptionFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); } diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index c696b3f58f48..42dfce82cfff 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -11,6 +11,7 @@ use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag}; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; use display_list_builder::{DisplayListBuildState, EstablishContainingBlock}; +use display_list_builder::StackingContextCollectionState; use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; @@ -261,7 +262,7 @@ impl Flow for TableCellFlow { self.block_flow.build_display_list_for_block(state, border_painting_mode) } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); } diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs index 10a87903403f..4d54afbe3869 100644 --- a/components/layout/table_colgroup.rs +++ b/components/layout/table_colgroup.rs @@ -8,7 +8,7 @@ use app_units::Au; use context::LayoutContext; -use display_list_builder::DisplayListBuildState; +use display_list_builder::{DisplayListBuildState, StackingContextCollectionState}; use euclid::Point2D; use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo}; @@ -92,7 +92,7 @@ impl Flow for TableColGroupFlow { // Table columns are invisible. fn build_display_list(&mut self, _: &mut DisplayListBuildState) { } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.base.stacking_context_id = state.current_stacking_context_id; self.base.clip_and_scroll_info = Some(state.current_clip_and_scroll_info); } diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index 070e7da92290..3cb525690a98 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -11,6 +11,7 @@ use block::{BlockFlow, ISizeAndMarginsComputer}; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; use display_list_builder::{DisplayListBuildState, EstablishContainingBlock}; +use display_list_builder::StackingContextCollectionState; use euclid::Point2D; use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow}; use flow_list::MutFlowListIterator; @@ -478,7 +479,7 @@ impl Flow for TableRowFlow { self.block_flow.build_display_list_for_block(state, border_painting_mode); } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); } diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index c3cb764686b0..16de7439e262 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -10,7 +10,7 @@ use app_units::Au; use block::{BlockFlow, ISizeAndMarginsComputer}; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState}; -use display_list_builder::EstablishContainingBlock; +use display_list_builder::{EstablishContainingBlock, StackingContextCollectionState}; use euclid::Point2D; use flow::{Flow, FlowClass, OpaqueFlow}; use fragment::{Fragment, FragmentBorderBoxIterator, Overflow}; @@ -183,7 +183,7 @@ impl Flow for TableRowGroupFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); } diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 1b7db760a095..1d9c2f6566e8 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -18,7 +18,7 @@ use block::{AbsoluteNonReplaced, BlockFlow, FloatNonReplaced, ISizeAndMarginsCom use block::{ISizeConstraintSolution, MarginsMayCollapseFlag}; use context::LayoutContext; use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState}; -use display_list_builder::EstablishContainingBlock; +use display_list_builder::{EstablishContainingBlock, StackingContextCollectionState}; use euclid::Point2D; use floats::FloatKind; use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow}; @@ -457,7 +457,7 @@ impl Flow for TableWrapperFlow { self.block_flow.build_display_list(state); } - fn collect_stacking_contexts(&mut self, state: &mut DisplayListBuildState) { + fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) { self.block_flow.collect_stacking_contexts_for_block(state, EstablishContainingBlock::No); }