diff options
Diffstat (limited to 'components/layout')
-rw-r--r-- | components/layout/block.rs | 63 | ||||
-rw-r--r-- | components/layout/context.rs | 7 | ||||
-rw-r--r-- | components/layout/display_list_builder.rs | 36 | ||||
-rw-r--r-- | components/layout/flow.rs | 25 | ||||
-rw-r--r-- | components/layout/inline.rs | 14 | ||||
-rw-r--r-- | components/layout/layout_task.rs | 94 | ||||
-rw-r--r-- | components/layout/list_item.rs | 4 | ||||
-rw-r--r-- | components/layout/multicol.rs | 4 | ||||
-rw-r--r-- | components/layout/table.rs | 4 | ||||
-rw-r--r-- | components/layout/table_caption.rs | 8 | ||||
-rw-r--r-- | components/layout/table_cell.rs | 8 | ||||
-rw-r--r-- | components/layout/table_row.rs | 4 | ||||
-rw-r--r-- | components/layout/table_rowgroup.rs | 4 | ||||
-rw-r--r-- | components/layout/table_wrapper.rs | 4 | ||||
-rw-r--r-- | components/layout/traversal.rs | 2 |
15 files changed, 224 insertions, 57 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs index c77c9266345..dccee7cfe27 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -43,6 +43,7 @@ use flow::{CLEARS_LEFT, CLEARS_RIGHT}; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo}; use incremental::{REFLOW, REFLOW_OUT_OF_FLOW}; use layout_debug; +use layout_task::DISPLAY_PORT_SIZE_FACTOR; use model::{IntrinsicISizes, MarginCollapseInfo}; use model::{MaybeAuto, CollapsibleMargins, specified, specified_or_none}; use wrapper::ThreadSafeLayoutNode; @@ -59,7 +60,7 @@ use style::computed_values::{position, text_align}; use style::properties::ComputedValues; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::computed::{LengthOrPercentageOrNone}; -use util::geometry::{Au, MAX_AU}; +use util::geometry::{Au, MAX_AU, MAX_RECT}; use util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode}; use util::opts; @@ -377,7 +378,9 @@ impl Iterator for CandidateBSizeIterator { Some(max_block_size) if self.candidate_value > max_block_size => { CandidateBSizeIteratorStatus::TryingMax } - _ if self.candidate_value < self.min_block_size => CandidateBSizeIteratorStatus::TryingMin, + _ if self.candidate_value < self.min_block_size => { + CandidateBSizeIteratorStatus::TryingMin + } _ => CandidateBSizeIteratorStatus::Found, } } @@ -718,13 +721,16 @@ impl BlockFlow { return } - let (block_start_margin_value, block_end_margin_value) = match self.base.collapsible_margins { - CollapsibleMargins::CollapseThrough(_) => panic!("Margins unexpectedly collapsed through root flow."), - CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => { - (block_start_margin.collapse(), block_end_margin.collapse()) - } - CollapsibleMargins::None(block_start, block_end) => (block_start, block_end), - }; + let (block_start_margin_value, block_end_margin_value) = + match self.base.collapsible_margins { + CollapsibleMargins::CollapseThrough(_) => { + panic!("Margins unexpectedly collapsed through root flow.") + } + CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => { + (block_start_margin.collapse(), block_end_margin.collapse()) + } + CollapsibleMargins::None(block_start, block_end) => (block_start, block_end), + }; // Shift all kids down (or up, if margins are negative) if necessary. if block_start_margin_value != Au(0) { @@ -757,7 +763,8 @@ impl BlockFlow { pub fn assign_block_size_block_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>, margins_may_collapse: MarginsMayCollapseFlag) { - let _scope = layout_debug_scope!("assign_block_size_block_base {:x}", self.base.debug_id()); + let _scope = layout_debug_scope!("assign_block_size_block_base {:x}", + self.base.debug_id()); if self.base.restyle_damage.contains(REFLOW) { // Our current border-box position. @@ -1661,13 +1668,14 @@ impl Flow for BlockFlow { } } - fn compute_absolute_position(&mut self) { + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { // FIXME (mbrubeck): Get the real container size, taking the container writing mode into // account. Must handle vertical writing modes. let container_size = Size2D(self.base.block_container_inline_size, Au(0)); if self.is_root() { - self.base.clip = ClippingRegion::max() + self.base.clip = ClippingRegion::max(); + self.base.stacking_relative_position_of_display_port = MAX_RECT; } if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) { @@ -1761,7 +1769,8 @@ impl Flow for BlockFlow { let relative_offset = relative_offset.to_physical(self.base.writing_mode); let origin_for_children; let clip_in_child_coordinate_system; - if self.fragment.establishes_stacking_context() { + let is_stacking_context = self.fragment.establishes_stacking_context(); + if is_stacking_context { // We establish a stacking context, so the position of our children is vertically // correct, but has to be adjusted to accommodate horizontal margins. (Note the // calculation involving `position` below and recall that inline-direction flow @@ -1771,11 +1780,31 @@ impl Flow for BlockFlow { let margin = self.fragment.margin.to_physical(self.base.writing_mode); origin_for_children = Point2D(-margin.left, Au(0)) + relative_offset; clip_in_child_coordinate_system = - self.base.clip.translate(&-self.base.stacking_relative_position) + self.base.clip.translate(&-self.base.stacking_relative_position); } else { origin_for_children = self.base.stacking_relative_position + relative_offset; - clip_in_child_coordinate_system = self.base.clip.clone() + clip_in_child_coordinate_system = self.base.clip.clone(); } + + let stacking_relative_position_of_display_port_for_children = + if (is_stacking_context && self.will_get_layer()) || self.is_root() { + let visible_rect = + match layout_context.shared.visible_rects.get(&self.layer_id(0)) { + Some(visible_rect) => *visible_rect, + None => Rect(Point2D::zero(), layout_context.shared.screen_size), + }; + + let screen_size = layout_context.shared.screen_size; + visible_rect.inflate(screen_size.width * DISPLAY_PORT_SIZE_FACTOR, + screen_size.height * DISPLAY_PORT_SIZE_FACTOR) + } else if is_stacking_context { + self.base + .stacking_relative_position_of_display_port + .translate(&-self.base.stacking_relative_position) + } else { + self.base.stacking_relative_position_of_display_port + }; + let stacking_relative_border_box = self.fragment .stacking_relative_border_box(&self.base.stacking_relative_position, @@ -1820,7 +1849,9 @@ impl Flow for BlockFlow { } flow::mut_base(kid).absolute_position_info = absolute_position_info_for_children; - flow::mut_base(kid).clip = clip.clone() + flow::mut_base(kid).clip = clip.clone(); + flow::mut_base(kid).stacking_relative_position_of_display_port = + stacking_relative_position_of_display_port_for_children; } } diff --git a/components/layout/context.rs b/components/layout/context.rs index 9a7550fd2d6..e83f4453b04 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -12,17 +12,21 @@ use geom::{Rect, Size2D}; use gfx::display_list::OpaqueNode; use gfx::font_cache_task::FontCacheTask; use gfx::font_context::FontContext; +use msg::compositor_msg::LayerId; use msg::constellation_msg::ConstellationChan; use net_traits::image::base::Image; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageState}; use script::layout_interface::{Animation, LayoutChan, ReflowGoal}; use std::boxed; use std::cell::Cell; +use std::collections::HashMap; +use std::collections::hash_state::DefaultState; use std::ptr; use std::sync::Arc; use std::sync::mpsc::{channel, Sender}; use style::selector_matching::Stylist; use url::Url; +use util::fnv::FnvHasher; use util::geometry::Au; use util::opts; @@ -99,6 +103,9 @@ pub struct SharedLayoutContext { /// sent. pub new_animations_sender: Sender<Animation>, + /// The visible rects for each layer, as reported to us by the compositor. + pub visible_rects: Arc<HashMap<LayerId, Rect<Au>, DefaultState<FnvHasher>>>, + /// Why is this reflow occurring pub goal: ReflowGoal, } diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs index 3c615ed0e9d..aac8a7c2317 100644 --- a/components/layout/display_list_builder.rs +++ b/components/layout/display_list_builder.rs @@ -176,6 +176,8 @@ pub trait FragmentDisplayListBuilding { /// * `relative_containing_block_size`: The size of the containing block that /// `position: relative` makes use of. /// * `clip`: The region to clip the display items to. + /// * `stacking_relative_display_port`: The position and size of the display port with respect + /// to the nearest ancestor stacking context. fn build_display_list(&mut self, display_list: &mut DisplayList, layout_context: &LayoutContext, @@ -184,7 +186,8 @@ pub trait FragmentDisplayListBuilding { relative_containing_block_mode: WritingMode, border_painting_mode: BorderPaintingMode, background_and_border_level: BackgroundAndBorderLevel, - clip: &ClippingRegion); + clip: &ClippingRegion, + stacking_relative_display_port: &Rect<Au>); /// Sends the size and position of this iframe fragment to the constellation. This is out of /// line to guide inlining. @@ -866,7 +869,8 @@ impl FragmentDisplayListBuilding for Fragment { relative_containing_block_mode: WritingMode, border_painting_mode: BorderPaintingMode, background_and_border_level: BackgroundAndBorderLevel, - clip: &ClippingRegion) { + clip: &ClippingRegion, + stacking_relative_display_port: &Rect<Au>) { if self.style().get_inheritedbox().visibility != visibility::T::visible { return } @@ -888,6 +892,11 @@ impl FragmentDisplayListBuilding for Fragment { stacking_relative_flow_origin, self); + if !stacking_relative_border_box.intersects(stacking_relative_display_port) { + debug!("Fragment::build_display_list: outside display port"); + return + } + if !stacking_relative_border_box.intersects(&layout_context.shared.dirty) { debug!("Fragment::build_display_list: Did not intersect..."); return @@ -1076,7 +1085,8 @@ impl FragmentDisplayListBuilding for Fragment { let (sender, receiver) = channel::<Vec<u8>>(); let canvas_data = match canvas_fragment_info.renderer { Some(ref renderer) => { - renderer.lock().unwrap().send(CanvasMsg::Common(CanvasCommonMsg::SendPixelContents(sender))).unwrap(); + renderer.lock().unwrap().send(CanvasMsg::Common( + CanvasCommonMsg::SendPixelContents(sender))).unwrap(); receiver.recv().unwrap() }, None => repeat(0xFFu8).take(width * height * 4).collect(), @@ -1364,6 +1374,7 @@ pub trait BlockFlowDisplayListBuilding { display_list: Box<DisplayList>, layout_context: &LayoutContext, border_painting_mode: BorderPaintingMode); + fn will_get_layer(&self) -> bool; } impl BlockFlowDisplayListBuilding for BlockFlow { @@ -1386,7 +1397,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow { self.base.absolute_position_info.relative_containing_block_mode, border_painting_mode, background_border_level, - &clip); + &clip, + &self.base.stacking_relative_position_of_display_port); // Add children. for kid in self.base.children.iter_mut() { @@ -1422,6 +1434,11 @@ impl BlockFlowDisplayListBuilding for BlockFlow { } } + fn will_get_layer(&self) -> bool { + self.base.absolute_position_info.layers_needed_for_positioned_flows || + self.base.flags.contains(NEEDS_LAYER) + } + fn build_display_list_for_absolutely_positioned_block( &mut self, mut display_list: Box<DisplayList>, @@ -1432,8 +1449,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow { border_painting_mode, BackgroundAndBorderLevel::RootOfStackingContext); - if !self.base.absolute_position_info.layers_needed_for_positioned_flows && - !self.base.flags.contains(NEEDS_LAYER) { + if !self.will_get_layer() { // We didn't need a layer. self.base.display_list_building_result = DisplayListBuildingResult::StackingContext(self.fragment.create_stacking_context( @@ -1524,7 +1540,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow { .relative_containing_block_mode, BorderPaintingMode::Separate, BackgroundAndBorderLevel::Content, - &self.base.clip); + &self.base.clip, + &self.base.stacking_relative_position_of_display_port); has_stacking_context = fragment.establishes_stacking_context(); match fragment.specific { @@ -1597,7 +1614,10 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow { .relative_containing_block_mode, BorderPaintingMode::Separate, BackgroundAndBorderLevel::Content, - &self.block_flow.base.clip); + &self.block_flow.base.clip, + &self.block_flow + .base + .stacking_relative_position_of_display_port); } // Draw the rest of the block. diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 57edf9ccd45..11d1c017db6 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -271,7 +271,7 @@ pub trait Flow: fmt::Debug + Sync { } /// Phase 4 of reflow: computes absolute positions. - fn compute_absolute_position(&mut self) { + fn compute_absolute_position(&mut self, _: &LayoutContext) { // The default implementation is a no-op. } @@ -859,6 +859,12 @@ pub struct BaseFlow { /// The clipping region for this flow and its descendants, in layer coordinates. pub clip: ClippingRegion, + /// The stacking-relative position of the display port. + /// + /// FIXME(pcwalton): This might be faster as an Arc, since this varies only + /// per-stacking-context. + pub stacking_relative_position_of_display_port: Rect<Au>, + /// The results of display list building for this flow. pub display_list_building_result: DisplayListBuildingResult, @@ -909,10 +915,18 @@ impl Encodable for BaseFlow { FlowClass::Block => c.as_immutable_block().encode(e), FlowClass::Inline => c.as_immutable_inline().encode(e), FlowClass::Table => c.as_immutable_table().encode(e), - FlowClass::TableWrapper => c.as_immutable_table_wrapper().encode(e), - FlowClass::TableRowGroup => c.as_immutable_table_rowgroup().encode(e), - FlowClass::TableRow => c.as_immutable_table_row().encode(e), - FlowClass::TableCell => c.as_immutable_table_cell().encode(e), + FlowClass::TableWrapper => { + c.as_immutable_table_wrapper().encode(e) + } + FlowClass::TableRowGroup => { + c.as_immutable_table_rowgroup().encode(e) + } + FlowClass::TableRow => { + c.as_immutable_table_row().encode(e) + } + FlowClass::TableCell => { + c.as_immutable_table_cell().encode(e) + } _ => { Ok(()) } // TODO: Support captions } }) @@ -1024,6 +1038,7 @@ impl BaseFlow { display_list_building_result: DisplayListBuildingResult::None, absolute_position_info: AbsolutePositionInfo::new(writing_mode), clip: ClippingRegion::max(), + stacking_relative_position_of_display_port: Rect::zero(), flags: flags, writing_mode: writing_mode, thread_id: 0, diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 07a3068d65b..2ac426776a0 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -1464,7 +1464,7 @@ impl Flow for InlineFlow { self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); } - fn compute_absolute_position(&mut self) { + fn compute_absolute_position(&mut self, _: &LayoutContext) { // First, gather up the positions of all the containing blocks (if any). let mut containing_block_positions = Vec::new(); let container_size = Size2D(self.base.block_container_inline_size, Au(0)); @@ -1504,14 +1504,18 @@ impl Flow for InlineFlow { let block_flow = info.flow_ref.as_block(); block_flow.base.absolute_position_info = self.base.absolute_position_info; block_flow.base.stacking_relative_position = - stacking_relative_border_box.origin + stacking_relative_border_box.origin; + block_flow.base.stacking_relative_position_of_display_port = + self.base.stacking_relative_position_of_display_port; } SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => { flow::mut_base(&mut *info.flow_ref).clip = clip; let block_flow = info.flow_ref.as_block(); block_flow.base.absolute_position_info = self.base.absolute_position_info; block_flow.base.stacking_relative_position = - stacking_relative_border_box.origin + stacking_relative_border_box.origin; + block_flow.base.stacking_relative_position_of_display_port = + self.base.stacking_relative_position_of_display_port; } SpecificFragmentInfo::InlineAbsolute(ref mut info) => { @@ -1528,7 +1532,9 @@ impl Flow for InlineFlow { stacking_relative_position + *padding_box_origin; block_flow.base.stacking_relative_position = - stacking_relative_border_box.origin + stacking_relative_border_box.origin; + block_flow.base.stacking_relative_position_of_display_port = + self.base.stacking_relative_position_of_display_port; } _ => {} } diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 7b30e10e727..0bf583627d1 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -11,12 +11,12 @@ use animation; use construct::ConstructionResult; use context::{SharedLayoutContext, SharedLayoutContextWrapper}; use css::node_style::StyledNode; +use data::{LayoutDataAccess, LayoutDataWrapper}; use display_list_builder::ToGfxColor; use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use flow_ref::FlowRef; use fragment::{Fragment, FragmentBorderBoxIterator}; use incremental::{LayoutDamageComputation, REFLOW, REFLOW_ENTIRE_DOCUMENT, REPAINT}; -use data::{LayoutDataAccess, LayoutDataWrapper}; use layout_debug; use opaque_node::OpaqueNodeMethods; use parallel::{self, UnsafeFlow}; @@ -39,7 +39,7 @@ use gfx::paint_task::Msg as PaintMsg; use gfx::paint_task::{PaintChan, PaintLayer}; use layout_traits::{LayoutControlMsg, LayoutTaskFactory}; use log; -use msg::compositor_msg::{Epoch, ScrollPolicy}; +use msg::compositor_msg::{Epoch, LayerId, ScrollPolicy}; use msg::constellation_msg::Msg as ConstellationMsg; use msg::constellation_msg::{ConstellationChan, Failure, PipelineExitType, PipelineId}; use profile_traits::mem::{self, Report, ReportsChan}; @@ -57,6 +57,8 @@ use script_traits::{ConstellationControlMsg, OpaqueScriptLayoutChannel}; use script_traits::{ScriptControlChan, StylesheetLoadResponder}; use std::borrow::ToOwned; use std::cell::Cell; +use std::collections::HashMap; +use std::collections::hash_state::DefaultState; use std::mem::transmute; use std::ops::{Deref, DerefMut}; use std::ptr; @@ -69,6 +71,7 @@ use style::selector_matching::Stylist; use style::stylesheets::{Origin, Stylesheet, CSSRuleIteratorExt}; use url::Url; use util::cursor::Cursor; +use util::fnv::FnvHasher; use util::geometry::{Au, MAX_RECT}; use util::logical_geometry::LogicalPoint; use util::mem::HeapSizeOf; @@ -77,6 +80,12 @@ use util::task::spawn_named_with_send_on_failure; use util::task_state; use util::workqueue::WorkQueue; +/// The number of screens of data we're allowed to generate display lists for in each direction. +pub const DISPLAY_PORT_SIZE_FACTOR: i32 = 8; + +/// The number of screens we have to traverse before we decide to generate new display lists. +const DISPLAY_PORT_THRESHOLD_SIZE_FACTOR: i32 = 4; + /// Mutable data belonging to the LayoutTask. /// /// This needs to be protected by a mutex so we can do fast RPCs. @@ -125,8 +134,12 @@ pub struct LayoutTaskData { /// sent. pub new_animations_sender: Sender<Animation>, - /// A counter for epoch messages + /// A counter for epoch messages. epoch: Epoch, + + /// The position and size of the visible rect for each layer. We do not build display lists + /// for any areas more than `DISPLAY_PORT_SIZE_FACTOR` screens away from this area. + pub visible_rects: Arc<HashMap<LayerId, Rect<Au>, DefaultState<FnvHasher>>>, } /// Information needed by the layout task. @@ -330,6 +343,7 @@ impl LayoutTask { content_box_response: Rect::zero(), content_boxes_response: Vec::new(), running_animations: Vec::new(), + visible_rects: Arc::new(HashMap::with_hash_state(Default::default())), new_animations_receiver: new_animations_receiver, new_animations_sender: new_animations_sender, epoch: Epoch(0), @@ -365,6 +379,7 @@ impl LayoutTask { url: (*url).clone(), reflow_root: reflow_root.map(|node| OpaqueNodeMethods::from_layout_node(node)), dirty: Rect::zero(), + visible_rects: rw_data.visible_rects.clone(), generation: rw_data.generation, new_animations_sender: rw_data.new_animations_sender.clone(), goal: goal, @@ -406,6 +421,10 @@ impl LayoutTask { match port_to_read { PortToRead::Pipeline => { match self.pipeline_port.recv().unwrap() { + LayoutControlMsg::SetVisibleRects(new_visible_rects) => { + self.handle_request_helper(Msg::SetVisibleRects(new_visible_rects), + possibly_locked_rw_data) + } LayoutControlMsg::TickAnimations => { self.handle_request_helper(Msg::TickAnimations, possibly_locked_rw_data) } @@ -509,6 +528,9 @@ impl LayoutTask { || self.handle_reflow(&*data, possibly_locked_rw_data)); }, Msg::TickAnimations => self.tick_all_animations(possibly_locked_rw_data), + Msg::SetVisibleRects(new_visible_rects) => { + self.set_visible_rects(new_visible_rects, possibly_locked_rw_data); + } Msg::ReapLayoutData(dead_layout_data) => { unsafe { self.handle_reap_layout_data(dead_layout_data) @@ -964,6 +986,64 @@ impl LayoutTask { chan.send(ConstellationControlMsg::ReflowComplete(self.id, data.id)).unwrap(); } + fn set_visible_rects<'a>(&'a self, + new_visible_rects: Vec<(LayerId, Rect<Au>)>, + possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) + -> bool { + let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + + // First, determine if we need to regenerate the display lists. This will happen if the + // layers have moved more than `DISPLAY_PORT_THRESHOLD_SIZE_FACTOR` away from their last + // positions. + let mut must_regenerate_display_lists = false; + let mut old_visible_rects = HashMap::with_hash_state(Default::default()); + let inflation_amount = + Size2D(rw_data.screen_size.width * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR, + rw_data.screen_size.height * DISPLAY_PORT_THRESHOLD_SIZE_FACTOR); + for &(ref layer_id, ref new_visible_rect) in new_visible_rects.iter() { + match rw_data.visible_rects.get(layer_id) { + None => { + old_visible_rects.insert(*layer_id, *new_visible_rect); + } + Some(old_visible_rect) => { + old_visible_rects.insert(*layer_id, *old_visible_rect); + + if !old_visible_rect.inflate(inflation_amount.width, inflation_amount.height) + .intersects(new_visible_rect) { + must_regenerate_display_lists = true; + } + } + } + } + + if !must_regenerate_display_lists { + // Update `visible_rects` in case there are new layers that were discovered. + rw_data.visible_rects = Arc::new(old_visible_rects); + return true + } + + debug!("regenerating display lists!"); + for &(ref layer_id, ref new_visible_rect) in new_visible_rects.iter() { + old_visible_rects.insert(*layer_id, *new_visible_rect); + } + rw_data.visible_rects = Arc::new(old_visible_rects); + + // Regenerate the display lists. + let reflow_info = Reflow { + goal: ReflowGoal::ForDisplay, + page_clip_rect: MAX_RECT, + }; + + let mut layout_context = self.build_shared_layout_context(&*rw_data, + false, + None, + &self.url, + reflow_info.goal); + + self.perform_post_main_layout_passes(&reflow_info, &mut *rw_data, &mut layout_context); + true + } + fn tick_all_animations<'a>(&'a self, possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { @@ -1045,7 +1125,15 @@ impl LayoutTask { } }); + self.perform_post_main_layout_passes(data, rw_data, layout_context); + } + + fn perform_post_main_layout_passes<'a>(&'a self, + data: &Reflow, + rw_data: &mut LayoutTaskData, + layout_context: &mut SharedLayoutContext) { // Build the display list if necessary, and send it to the painter. + let mut root_flow = (*rw_data.root_flow.as_ref().unwrap()).clone(); self.compute_abs_pos_and_build_display_list(data, &mut root_flow, &mut *layout_context, diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs index c348986c69c..1840cc1fbde 100644 --- a/components/layout/list_item.rs +++ b/components/layout/list_item.rs @@ -117,8 +117,8 @@ impl Flow for ListItemFlow { } } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn place_float_if_applicable<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs index f33b2774a40..1ce84a365f1 100644 --- a/components/layout/multicol.rs +++ b/components/layout/multicol.rs @@ -63,8 +63,8 @@ impl Flow for MulticolFlow { self.block_flow.assign_block_size(ctx); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table.rs b/components/layout/table.rs index 3c9b832b190..9bb86eb9129 100644 --- a/components/layout/table.rs +++ b/components/layout/table.rs @@ -503,8 +503,8 @@ impl Flow for TableFlow { self.block_flow.assign_block_size_for_table_like_flow(layout_context, vertical_spacing) } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn generated_containing_block_size(&self, flow: OpaqueFlow) -> LogicalSize<Au> { diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs index 628b90c41c5..ab98e9b3261 100644 --- a/components/layout/table_caption.rs +++ b/components/layout/table_caption.rs @@ -59,13 +59,13 @@ impl Flow for TableCaptionFlow { self.block_flow.assign_inline_sizes(ctx); } - fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { + fn assign_block_size<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { debug!("assign_block_size: assigning block_size for table_caption"); - self.block_flow.assign_block_size(ctx); + self.block_flow.assign_block_size(layout_context); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs index 54ebe61c212..d44de741e60 100644 --- a/components/layout/table_cell.rs +++ b/components/layout/table_cell.rs @@ -160,13 +160,13 @@ impl Flow for TableCellFlow { |_, _, _, _, _, _| {}); } - fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { + fn assign_block_size<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { debug!("assign_block_size: assigning block_size for table_cell"); - self.assign_block_size_table_cell_base(ctx); + self.assign_block_size_table_cell_base(layout_context); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs index b3a1ee93e91..ee9411a0513 100644 --- a/components/layout/table_row.rs +++ b/components/layout/table_row.rs @@ -403,8 +403,8 @@ impl Flow for TableRowFlow { self.assign_block_size_table_row_base(layout_context); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs index 088103188c7..2c76c30c832 100644 --- a/components/layout/table_rowgroup.rs +++ b/components/layout/table_rowgroup.rs @@ -203,8 +203,8 @@ impl Flow for TableRowGroupFlow { self.spacing.vertical) } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) { diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs index 592ad213f93..8f77e97dfd0 100644 --- a/components/layout/table_wrapper.rs +++ b/components/layout/table_wrapper.rs @@ -381,8 +381,8 @@ impl Flow for TableWrapperFlow { MarginsMayCollapseFlag::MarginsMayNotCollapse); } - fn compute_absolute_position(&mut self) { - self.block_flow.compute_absolute_position() + fn compute_absolute_position(&mut self, layout_context: &LayoutContext) { + self.block_flow.compute_absolute_position(layout_context) } fn place_float_if_applicable<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 39169787cad..6106456876b 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -364,7 +364,7 @@ pub struct ComputeAbsolutePositions<'a> { impl<'a> PreorderFlowTraversal for ComputeAbsolutePositions<'a> { #[inline] fn process(&self, flow: &mut Flow) { - flow.compute_absolute_position(); + flow.compute_absolute_position(self.layout_context); } } |