diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index d69353e1f72..7273c73d254 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -164,18 +164,30 @@ impl DisplayList { } } + + /// Creates a new display list which contains a single stacking context. + #[inline] + pub fn new_with_stacking_context(stacking_context: Arc) -> Box { + let mut display_list = box DisplayList::new(); + display_list.positioned_content.push_back( + DisplayItem::StackingContextClass(stacking_context)); + display_list + } + /// Appends all display items from `other` into `self`, preserving stacking order and emptying /// `other` in the process. #[inline] - pub fn append_from(&mut self, other: &mut DisplayList) { - self.background_and_borders.append(&mut other.background_and_borders); - self.block_backgrounds_and_borders.append(&mut other.block_backgrounds_and_borders); - self.floats.append(&mut other.floats); - self.content.append(&mut other.content); - self.positioned_content.append(&mut other.positioned_content); - self.outlines.append(&mut other.outlines); - self.layered_children.append(&mut other.layered_children); - self.layer_info.append(&mut other.layer_info); + pub fn append_from(&mut self, other: &mut Option>) { + if let Some(mut other) = other.take() { + self.background_and_borders.append(&mut other.background_and_borders); + self.block_backgrounds_and_borders.append(&mut other.block_backgrounds_and_borders); + self.floats.append(&mut other.floats); + self.content.append(&mut other.content); + self.positioned_content.append(&mut other.positioned_content); + self.outlines.append(&mut other.outlines); + self.layered_children.append(&mut other.layered_children); + self.layer_info.append(&mut other.layer_info); + } } /// Merges all display items from all non-float stacking levels to the `float` stacking level. diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 6e89c4b0df6..907bb5b129d 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -66,31 +66,6 @@ use util::range::Range; /// The logical width of an insertion point: at the moment, a one-pixel-wide line. const INSERTION_POINT_LOGICAL_WIDTH: Au = Au(1 * AU_PER_PX); -/// The results of display list building for a single flow. -pub enum DisplayListBuildingResult { - None, - StackingContext(Arc), - Normal(Box), -} - -impl DisplayListBuildingResult { - /// Adds the display list items contained within this display list building result to the given - /// display list, preserving stacking order. If this display list building result does not - /// consist of an entire stacking context, it will be emptied. - pub fn add_to(&mut self, display_list: &mut DisplayList) { - match *self { - DisplayListBuildingResult::None => return, - DisplayListBuildingResult::StackingContext(ref mut stacking_context) => { - display_list.positioned_content.push_back( - DisplayItem::StackingContextClass((*stacking_context).clone())) - } - DisplayListBuildingResult::Normal(ref mut source_display_list) => { - display_list.append_from(&mut **source_display_list) - } - } - } -} - pub trait FragmentDisplayListBuilding { /// Adds the display items necessary to paint the background of this fragment to the display /// list if necessary. @@ -1587,7 +1562,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // Add children. for kid in self.base.children.iter_mut() { - flow::mut_base(kid).display_list_building_result.add_to(display_list); + display_list.append_from(&mut flow::mut_base(kid).display_list_building_result); } self.base.build_display_items_for_debugging_tint(display_list, self.fragment.node); @@ -1610,17 +1585,16 @@ impl BlockFlowDisplayListBuilding for BlockFlow { ScrollPolicy::Scrollable }; - DisplayListBuildingResult::StackingContext( - self.fragment.create_stacking_context( - &self.base, - display_list, - scroll_policy, - StackingContextCreationMode::Normal)) + Some(DisplayList::new_with_stacking_context( + self.fragment.create_stacking_context(&self.base, + display_list, + scroll_policy, + StackingContextCreationMode::Normal))) } else { if self.fragment.style.get_box().position != position::T::static_ { display_list.form_pseudo_stacking_context_for_positioned_content(); } - DisplayListBuildingResult::Normal(display_list) + Some(display_list) } } @@ -1655,7 +1629,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { // Add the fragments of our children to the display list we'll use for the inner // stacking context. for kid in self.base.children.iter_mut() { - flow::mut_base(kid).display_list_building_result.add_to(&mut *display_list); + display_list.append_from(&mut flow::mut_base(kid).display_list_building_result); } Some(outer_display_list_for_overflow_scroll) @@ -1678,8 +1652,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { if !self.fragment.flags.contains(HAS_LAYER) && !self.fragment.establishes_stacking_context() { display_list.form_pseudo_stacking_context_for_positioned_content(); - self.base.display_list_building_result = - DisplayListBuildingResult::Normal(display_list); + self.base.display_list_building_result = Some(display_list); return; } @@ -1714,7 +1687,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { }; self.base.display_list_building_result = - DisplayListBuildingResult::StackingContext(stacking_context) + Some(DisplayList::new_with_stacking_context(stacking_context)); } fn build_display_list_for_floating_block(&mut self, @@ -1728,16 +1701,16 @@ impl BlockFlowDisplayListBuilding for BlockFlow { display_list.form_float_pseudo_stacking_context(); self.base.display_list_building_result = if self.fragment.establishes_stacking_context() { - DisplayListBuildingResult::StackingContext( + Some(DisplayList::new_with_stacking_context( self.fragment.create_stacking_context(&self.base, display_list, ScrollPolicy::Scrollable, - StackingContextCreationMode::Normal)) + StackingContextCreationMode::Normal))) } else { if self.fragment.style.get_box().position != position::T::static_ { display_list.form_pseudo_stacking_context_for_positioned_content(); } - DisplayListBuildingResult::Normal(display_list) + Some(display_list) } } @@ -1796,18 +1769,18 @@ impl InlineFlowDisplayListBuilding for InlineFlow { match fragment.specific { SpecificFragmentInfo::InlineBlock(ref mut block_flow) => { let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref); - flow::mut_base(block_flow).display_list_building_result - .add_to(&mut *display_list) + display_list.append_from( + &mut flow::mut_base(block_flow).display_list_building_result) } SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => { let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref); - flow::mut_base(block_flow).display_list_building_result - .add_to(&mut *display_list) + display_list.append_from( + &mut flow::mut_base(block_flow).display_list_building_result) } SpecificFragmentInfo::InlineAbsolute(ref mut block_flow) => { let block_flow = flow_ref::deref_mut(&mut block_flow.flow_ref); - flow::mut_base(block_flow).display_list_building_result - .add_to(&mut *display_list) + display_list.append_from( + &mut flow::mut_base(block_flow).display_list_building_result) } _ => {} } @@ -1833,14 +1806,14 @@ impl InlineFlowDisplayListBuilding for InlineFlow { } self.base.display_list_building_result = if has_stacking_context { - DisplayListBuildingResult::StackingContext( + Some(DisplayList::new_with_stacking_context( self.fragments.fragments[0].create_stacking_context( &self.base, display_list, ScrollPolicy::Scrollable, - StackingContextCreationMode::Normal)) + StackingContextCreationMode::Normal))) } else { - DisplayListBuildingResult::Normal(display_list) + Some(display_list) }; if opts::get().validate_display_list_geometry { diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 8e585032c6e..6a075425fbf 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -28,13 +28,12 @@ use app_units::Au; use block::BlockFlow; use context::LayoutContext; -use display_list_builder::DisplayListBuildingResult; use euclid::{Point2D, Rect, Size2D}; use floats::Floats; use flow_list::{FlowList, FlowListIterator, MutFlowListIterator}; use flow_ref::{self, FlowRef, WeakFlowRef}; use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo}; -use gfx::display_list::ClippingRegion; +use gfx::display_list::{ClippingRegion, DisplayList}; use incremental::{self, RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage}; use inline::InlineFlow; use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo}; @@ -906,7 +905,7 @@ pub struct BaseFlow { pub stacking_relative_position_of_display_port: Rect, /// The results of display list building for this flow. - pub display_list_building_result: DisplayListBuildingResult, + pub display_list_building_result: Option>, /// The writing mode for this flow. pub writing_mode: WritingMode, @@ -1052,7 +1051,7 @@ impl BaseFlow { block_container_writing_mode: writing_mode, block_container_explicit_block_size: None, absolute_cb: ContainingBlockLink::new(), - display_list_building_result: DisplayListBuildingResult::None, + display_list_building_result: None, early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode), late_absolute_position_info: LateAbsolutePositionInfo::new(), clip: ClippingRegion::max(), @@ -1083,11 +1082,8 @@ impl BaseFlow { let bounds = Rect::new(self.stacking_relative_position, position_with_overflow.size); let all_items = match self.display_list_building_result { - DisplayListBuildingResult::None => Vec::new(), - DisplayListBuildingResult::StackingContext(ref stacking_context) => { - stacking_context.display_list.flatten() - } - DisplayListBuildingResult::Normal(ref display_list) => display_list.flatten(), + Some(ref display_list) => display_list.flatten(), + None => Vec::new(), }; for item in &all_items { diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index c86ecdedaff..d4931848f05 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -1084,9 +1084,8 @@ impl LayoutTask { } }; let mut display_list = box DisplayList::new(); - flow::mut_base(flow_ref::deref_mut(layout_root)) - .display_list_building_result - .add_to(&mut *display_list); + display_list.append_from(&mut flow::mut_base(flow_ref::deref_mut(layout_root)) + .display_list_building_result); let origin = Rect::new(Point2D::new(Au(0), Au(0)), root_size); let stacking_context = Arc::new(StackingContext::new(display_list,