diff options
author | Glenn Watson <gw@intuitionlibrary.com> | 2014-08-08 13:53:37 +1000 |
---|---|---|
committer | Glenn Watson <gw@intuitionlibrary.com> | 2014-08-11 12:10:28 +1000 |
commit | 4a0e01b4f033940b5d31ad1a47e322b2769ef1a5 (patch) | |
tree | 1e286508e0d54e3aad2e1155d39a252e783b8d77 /src | |
parent | 4062af69ec562c8a3f781a2918bc4134a809b391 (diff) | |
download | servo-4a0e01b4f033940b5d31ad1a47e322b2769ef1a5.tar.gz servo-4a0e01b4f033940b5d31ad1a47e322b2769ef1a5.zip |
Refactor how LayoutContext structure works (reduce TLS lookups + simplify fns used by seq/parallel code paths).
- LayoutContext is renamed to SharedLayoutContext.
- SharedLayoutContext is immutable.
- LayoutContext is a wrapper around SharedLayoutContext + access to local caches (font, style etc).
- Creating a LayoutContext does a single local_data lookup to fetch the cache information.
- Android shares same implementation of context.rs as other platforms.
- LayoutContext can be used from both green thread (parallel layout) and native thread (sequential layout).
- Removes the need for other types (such as FontContext, StyleSharingCandidateCache etc) to be passed around.
Diffstat (limited to 'src')
-rw-r--r-- | src/components/layout/block.rs | 50 | ||||
-rw-r--r-- | src/components/layout/construct.rs | 52 | ||||
-rw-r--r-- | src/components/layout/context.rs | 182 | ||||
-rw-r--r-- | src/components/layout/css/matching.rs | 41 | ||||
-rw-r--r-- | src/components/layout/flow.rs | 12 | ||||
-rw-r--r-- | src/components/layout/fragment.rs | 8 | ||||
-rw-r--r-- | src/components/layout/inline.rs | 8 | ||||
-rw-r--r-- | src/components/layout/layout_task.rs | 74 | ||||
-rw-r--r-- | src/components/layout/parallel.rs | 82 | ||||
-rw-r--r-- | src/components/layout/table.rs | 10 | ||||
-rw-r--r-- | src/components/layout/table_caption.rs | 6 | ||||
-rw-r--r-- | src/components/layout/table_cell.rs | 8 | ||||
-rw-r--r-- | src/components/layout/table_colgroup.rs | 6 | ||||
-rw-r--r-- | src/components/layout/table_row.rs | 8 | ||||
-rw-r--r-- | src/components/layout/table_rowgroup.rs | 8 | ||||
-rw-r--r-- | src/components/layout/table_wrapper.rs | 12 |
16 files changed, 212 insertions, 355 deletions
diff --git a/src/components/layout/block.rs b/src/components/layout/block.rs index 23a402f24c9..e72515088c2 100644 --- a/src/components/layout/block.rs +++ b/src/components/layout/block.rs @@ -402,7 +402,7 @@ fn translate_including_floats(cur_b: &mut Au, delta: Au, floats: &mut Floats) { /// /// Note that flows with position 'fixed' just form a flat list as they all /// have the Root flow as their CB. -struct AbsoluteAssignBSizesTraversal<'a>(&'a mut LayoutContext); +struct AbsoluteAssignBSizesTraversal<'a>(&'a LayoutContext<'a>); impl<'a> PreorderFlowTraversal for AbsoluteAssignBSizesTraversal<'a> { #[inline] @@ -429,7 +429,7 @@ impl<'a> PreorderFlowTraversal for AbsoluteAssignBSizesTraversal<'a> { /// After that, it is up to the normal store-overflow traversal to propagate /// it further up. struct AbsoluteStoreOverflowTraversal<'a>{ - layout_context: &'a mut LayoutContext, + layout_context: &'a LayoutContext<'a>, } impl<'a> PostorderFlowTraversal for AbsoluteStoreOverflowTraversal<'a> { @@ -579,7 +579,7 @@ impl BlockFlow { } /// Compute the used value of inline-size for this Block. - fn compute_used_inline_size(&mut self, ctx: &mut LayoutContext, containing_block_inline_size: Au) { + fn compute_used_inline_size(&mut self, ctx: &LayoutContext, containing_block_inline_size: Au) { let block_type = self.block_type(); match block_type { AbsoluteReplacedType => { @@ -805,8 +805,8 @@ impl BlockFlow { /// `inline(always)` because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - pub fn assign_block_size_block_base(&mut self, - layout_context: &mut LayoutContext, + pub fn assign_block_size_block_base<'a>(&mut self, + layout_context: &'a LayoutContext<'a>, margins_may_collapse: MarginsMayCollapseFlag) { // Our current border-box position. let mut cur_b = Au(0); @@ -949,7 +949,7 @@ impl BlockFlow { let mut block_size = cur_b - block_start_offset; if self.is_root() { let screen_size = LogicalSize::from_physical( - self.fragment.style.writing_mode, layout_context.screen_size); + self.fragment.style.writing_mode, layout_context.shared.screen_size); block_size = Au::max(screen_size.block, block_size) } @@ -1053,7 +1053,7 @@ impl BlockFlow { /// should be calculated using CSS Section 10.6.7 /// /// It does not calculate the block-size of the flow itself. - pub fn assign_block_size_float(&mut self, ctx: &mut LayoutContext) { + pub fn assign_block_size_float<'a>(&mut self, ctx: &'a LayoutContext<'a>) { let mut floats = Floats::new(self.fragment.style.writing_mode); for kid in self.base.child_iter() { flow::mut_base(kid).floats = floats.clone(); @@ -1179,7 +1179,7 @@ impl BlockFlow { /// + y-coordinate of the flow wrt its Containing Block. /// + block-size, vertical margins, and y-coordinate for the flow's box. fn calculate_abs_block_size_and_margins(&mut self, ctx: &LayoutContext) { - let containing_block_block_size = self.containing_block_size(ctx.screen_size).block; + let containing_block_block_size = self.containing_block_size(ctx.shared.screen_size).block; let static_b_offset = self.static_b_offset; // This is the stored content block-size value from assign-block-size @@ -1445,7 +1445,7 @@ impl Flow for BlockFlow { /// any fragments it is responsible for flowing. /// /// TODO(pcwalton): Inline blocks. - fn bubble_inline_sizes(&mut self, _: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, _: &LayoutContext) { let mut flags = self.base.flags; flags.set_has_left_floated_descendants(false); flags.set_has_right_floated_descendants(false); @@ -1489,7 +1489,7 @@ impl Flow for BlockFlow { /// /// Dual fragments consume some inline-size first, and the remainder is assigned to all child (block) /// contexts. - fn assign_inline_sizes(&mut self, layout_context: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, layout_context: &LayoutContext) { debug!("assign_inline_sizes({}): assigning inline_size for flow", if self.is_float() { "float" @@ -1501,7 +1501,7 @@ impl Flow for BlockFlow { debug!("Setting root position"); self.base.position.start = LogicalPoint::zero(self.base.writing_mode); self.base.position.size.inline = LogicalSize::from_physical( - self.base.writing_mode, layout_context.screen_size).inline; + self.base.writing_mode, layout_context.shared.screen_size).inline; self.base.floats = Floats::new(self.base.writing_mode); // The root element is never impacted by floats. @@ -1559,7 +1559,7 @@ impl Flow for BlockFlow { /// /// This is called on child flows by the parent. Hence, we can assume that `assign_block-size` has /// already been called on the child (because of the bottom-up traversal). - fn assign_block_size_for_inorder_child_if_necessary(&mut self, layout_context: &mut LayoutContext) + fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self, layout_context: &'a LayoutContext<'a>) -> bool { if self.is_float() { self.place_float(); @@ -1573,7 +1573,7 @@ impl Flow for BlockFlow { impacted } - fn assign_block_size(&mut self, ctx: &mut LayoutContext) { + fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { // Assign block-size for fragment if it is an image fragment. self.fragment.assign_replaced_block_size_if_necessary(); @@ -1794,7 +1794,7 @@ pub trait ISizeAndMarginsComputer { fn compute_inline_size_constraint_inputs(&self, block: &mut BlockFlow, parent_flow_inline_size: Au, - ctx: &mut LayoutContext) + ctx: &LayoutContext) -> ISizeConstraintInput { let containing_block_inline_size = self.containing_block_inline_size(block, parent_flow_inline_size, ctx); let computed_inline_size = self.initial_computed_inline_size(block, parent_flow_inline_size, ctx); @@ -1864,7 +1864,7 @@ pub trait ISizeAndMarginsComputer { fn initial_computed_inline_size(&self, block: &mut BlockFlow, parent_flow_inline_size: Au, - ctx: &mut LayoutContext) + ctx: &LayoutContext) -> MaybeAuto { MaybeAuto::from_style(block.fragment().style().content_inline_size(), self.containing_block_inline_size(block, parent_flow_inline_size, ctx)) @@ -1873,7 +1873,7 @@ pub trait ISizeAndMarginsComputer { fn containing_block_inline_size(&self, _: &mut BlockFlow, parent_flow_inline_size: Au, - _: &mut LayoutContext) + _: &LayoutContext) -> Au { parent_flow_inline_size } @@ -1883,7 +1883,7 @@ pub trait ISizeAndMarginsComputer { /// CSS Section 10.4: Minimum and Maximum inline-sizes fn compute_used_inline_size(&self, block: &mut BlockFlow, - ctx: &mut LayoutContext, + ctx: &LayoutContext, parent_flow_inline_size: Au) { let mut input = self.compute_inline_size_constraint_inputs(block, parent_flow_inline_size, ctx); @@ -2127,8 +2127,8 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced { ISizeConstraintSolution::for_absolute_flow(inline_start, inline_end, inline_size, margin_inline_start, margin_inline_end) } - fn containing_block_inline_size(&self, block: &mut BlockFlow, _: Au, ctx: &mut LayoutContext) -> Au { - block.containing_block_size(ctx.screen_size).inline + fn containing_block_inline_size(&self, block: &mut BlockFlow, _: Au, ctx: &LayoutContext) -> Au { + block.containing_block_size(ctx.shared.screen_size).inline } fn set_flow_x_coord_if_necessary(&self, @@ -2241,9 +2241,9 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { fn initial_computed_inline_size(&self, block: &mut BlockFlow, _: Au, - ctx: &mut LayoutContext) + ctx: &LayoutContext) -> MaybeAuto { - let containing_block_inline_size = block.containing_block_size(ctx.screen_size).inline; + let containing_block_inline_size = block.containing_block_size(ctx.shared.screen_size).inline; let fragment = block.fragment(); fragment.assign_replaced_inline_size_if_necessary(containing_block_inline_size, None); // For replaced absolute flow, the rest of the constraint solving will @@ -2251,8 +2251,8 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced { Specified(fragment.content_inline_size()) } - fn containing_block_inline_size(&self, block: &mut BlockFlow, _: Au, ctx: &mut LayoutContext) -> Au { - block.containing_block_size(ctx.screen_size).inline + fn containing_block_inline_size(&self, block: &mut BlockFlow, _: Au, ctx: &LayoutContext) -> Au { + block.containing_block_size(ctx.shared.screen_size).inline } fn set_flow_x_coord_if_necessary(&self, block: &mut BlockFlow, solution: ISizeConstraintSolution) { @@ -2291,7 +2291,7 @@ impl ISizeAndMarginsComputer for BlockReplaced { fn initial_computed_inline_size(&self, block: &mut BlockFlow, parent_flow_inline_size: Au, - _: &mut LayoutContext) + _: &LayoutContext) -> MaybeAuto { let fragment = block.fragment(); fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, None); @@ -2347,7 +2347,7 @@ impl ISizeAndMarginsComputer for FloatReplaced { fn initial_computed_inline_size(&self, block: &mut BlockFlow, parent_flow_inline_size: Au, - _: &mut LayoutContext) + _: &LayoutContext) -> MaybeAuto { let fragment = block.fragment(); fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, None); diff --git a/src/components/layout/construct.rs b/src/components/layout/construct.rs index a780c073f17..db6084a1c02 100644 --- a/src/components/layout/construct.rs +++ b/src/components/layout/construct.rs @@ -47,7 +47,6 @@ use wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode}; use wrapper::{Before, BeforeBlock, After, AfterBlock, Normal}; use gfx::display_list::OpaqueNode; -use gfx::font_context::FontContext; use script::dom::element::{HTMLIFrameElementTypeId, HTMLImageElementTypeId}; use script::dom::element::{HTMLObjectElementTypeId}; use script::dom::element::{HTMLTableColElementTypeId, HTMLTableDataCellElementTypeId}; @@ -184,47 +183,20 @@ enum WhitespaceStrippingMode { } /// An object that knows how to create flows. -pub struct FlowConstructor<'a> { +pub struct FlowConstructor<'a, 'b> { /// The layout context. - pub layout_context: &'a mut LayoutContext, - - /// An optional font context. If this is `None`, then we fetch the font context from the - /// layout context. - /// - /// FIXME(pcwalton): This is pretty bogus and is basically just a workaround for libgreen - /// having slow TLS. - pub font_context: Option<Box<FontContext>>, + pub layout_context: &'b LayoutContext<'b>, } -impl<'a> FlowConstructor<'a> { +impl<'a, 'b> FlowConstructor<'a, 'b> { /// Creates a new flow constructor. - pub fn new(layout_context: &'a mut LayoutContext, font_context: Option<Box<FontContext>>) - -> FlowConstructor<'a> { + pub fn new<'b>(layout_context: &'b LayoutContext) + -> FlowConstructor<'a, 'b> { FlowConstructor { layout_context: layout_context, - font_context: font_context, } } - fn font_context<'a>(&'a mut self) -> &'a mut FontContext { - match self.font_context { - Some(ref mut font_context) => { - let font_context: &mut FontContext = &mut **font_context; - font_context - } - None => self.layout_context.font_context(), - } - } - - /// Destroys this flow constructor and retrieves the font context. - pub fn unwrap_font_context(self) -> Option<Box<FontContext>> { - let FlowConstructor { - font_context, - .. - } = self; - font_context - } - /// Builds the `ImageFragmentInfo` for the given image. This is out of line to guide inlining. fn build_fragment_info_for_image(&mut self, node: &ThreadSafeLayoutNode, url: Option<Url>) -> SpecificFragmentInfo { @@ -233,7 +205,7 @@ impl<'a> FlowConstructor<'a> { Some(url) => { // FIXME(pcwalton): The fact that image fragments store the cache within them makes // little sense to me. - ImageFragment(ImageFragmentInfo::new(node, url, self.layout_context.image_cache.clone())) + ImageFragment(ImageFragmentInfo::new(node, url, self.layout_context.shared.image_cache.clone())) } } } @@ -293,11 +265,11 @@ impl<'a> FlowConstructor<'a> { } let mut inline_flow = box InlineFlow::from_fragments((*node).clone(), fragments); - let (ascent, descent) = inline_flow.compute_minimum_ascent_and_descent(self.font_context(), &**node.style()); + let (ascent, descent) = inline_flow.compute_minimum_ascent_and_descent(self.layout_context.font_context(), &**node.style()); inline_flow.minimum_block_size_above_baseline = ascent; inline_flow.minimum_depth_below_baseline = descent; let mut inline_flow = inline_flow as Box<Flow>; - TextRunScanner::new().scan_for_runs(self.font_context(), inline_flow); + TextRunScanner::new().scan_for_runs(self.layout_context.font_context(), inline_flow); let mut inline_flow = FlowRef::new(inline_flow); inline_flow.finish(self.layout_context); @@ -797,7 +769,7 @@ impl<'a> FlowConstructor<'a> { } } -impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { +impl<'a, 'b> PostorderNodeMutTraversal for FlowConstructor<'a, 'b> { // Construct Flow based on 'display', 'position', and 'float' values. // // CSS 2.1 Section 9.7 @@ -1039,7 +1011,7 @@ pub trait FlowConstructionUtils { /// /// All flows must be finished at some point, or they will not have their intrinsic inline-sizes /// properly computed. (This is not, however, a memory safety problem.) - fn finish(&mut self, context: &mut LayoutContext); + fn finish(&mut self, context: &LayoutContext); } impl FlowConstructionUtils for FlowRef { @@ -1066,8 +1038,8 @@ impl FlowConstructionUtils for FlowRef { /// properly computed. (This is not, however, a memory safety problem.) /// /// This must not be public because only the layout constructor can do this. - fn finish(&mut self, context: &mut LayoutContext) { - if !context.opts.bubble_inline_sizes_separately { + fn finish(&mut self, context: &LayoutContext) { + if !context.shared.opts.bubble_inline_sizes_separately { self.get_mut().bubble_inline_sizes(context) } } diff --git a/src/components/layout/context.rs b/src/components/layout/context.rs index 0a58e3a761a..936314dcb63 100644 --- a/src/components/layout/context.rs +++ b/src/components/layout/context.rs @@ -10,8 +10,6 @@ use geom::{Rect, Size2D}; use gfx::display_list::OpaqueNode; use gfx::font_context::FontContext; use gfx::font_cache_task::FontCacheTask; -#[cfg(not(target_os="android"))] -use green::task::GreenTask; use script::layout_interface::LayoutChan; use servo_msg::constellation_msg::ConstellationChan; use servo_net::local_image_cache::LocalImageCache; @@ -19,42 +17,37 @@ use servo_util::geometry::Au; use servo_util::opts::Opts; use sync::{Arc, Mutex}; use std::mem; -#[cfg(not(target_os="android"))] -use std::ptr; -#[cfg(not(target_os="android"))] -use std::rt::local::Local; -#[cfg(not(target_os="android"))] -use std::rt::task::Task; use style::Stylist; use url::Url; -#[cfg(not(target_os="android"))] -#[thread_local] -static mut FONT_CONTEXT: *mut FontContext = 0 as *mut FontContext; - -#[cfg(target_os="android")] -local_data_key!(font_context: *mut FontContext) - -#[cfg(not(target_os="android"))] -#[thread_local] -static mut APPLICABLE_DECLARATIONS_CACHE: *mut ApplicableDeclarationsCache = - 0 as *mut ApplicableDeclarationsCache; - -#[cfg(target_os="android")] -local_data_key!(applicable_declarations_cache: *mut ApplicableDeclarationsCache) - -#[cfg(not(target_os="android"))] -#[thread_local] -static mut STYLE_SHARING_CANDIDATE_CACHE: *mut StyleSharingCandidateCache = - 0 as *mut StyleSharingCandidateCache; +struct LocalLayoutContext { + font_context: FontContext, + applicable_declarations_cache: ApplicableDeclarationsCache, + style_sharing_candidate_cache: StyleSharingCandidateCache, +} -#[cfg(target_os="android")] -local_data_key!(style_sharing_candidate_cache: *mut StyleSharingCandidateCache) +local_data_key!(local_context_key: *mut LocalLayoutContext) + +fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> *mut LocalLayoutContext { + let maybe_context = local_context_key.get(); + + let context = match maybe_context { + None => { + let context = box LocalLayoutContext { + font_context: FontContext::new(shared_layout_context.font_cache_task.clone()), + applicable_declarations_cache: ApplicableDeclarationsCache::new(), + style_sharing_candidate_cache: StyleSharingCandidateCache::new(), + }; + local_context_key.replace(Some(unsafe { mem::transmute(context) })); + local_context_key.get().unwrap() + }, + Some(context) => context + }; + + *context +} -/// Data shared by all layout workers. -#[allow(raw_pointer_deriving)] -#[deriving(Clone)] -pub struct LayoutContext { +pub struct SharedLayoutContext { /// The local image cache. pub image_cache: Arc<Mutex<LocalImageCache>>, @@ -88,126 +81,43 @@ pub struct LayoutContext { pub dirty: Rect<Au>, } -#[cfg(not(target_os="android"))] -impl LayoutContext { - pub fn font_context<'a>(&'a mut self) -> &'a mut FontContext { - // Sanity check. - { - let mut task = Local::borrow(None::<Task>); - match task.maybe_take_runtime::<GreenTask>() { - Some(green) => { - task.put_runtime(green); - fail!("can't call this on a green task!") - } - None => {} - } - } - - unsafe { - if FONT_CONTEXT == ptr::mut_null() { - let context = box FontContext::new(self.font_cache_task.clone()); - FONT_CONTEXT = mem::transmute(context) - } - mem::transmute(FONT_CONTEXT) - } - } - - pub fn applicable_declarations_cache<'a>(&'a self) -> &'a mut ApplicableDeclarationsCache { - // Sanity check. - { - let mut task = Local::borrow(None::<Task>); - match task.maybe_take_runtime::<GreenTask>() { - Some(green) => { - task.put_runtime(green); - fail!("can't call this on a green task!") - } - None => {} - } - } +pub struct LayoutContext<'a> { + pub shared: &'a SharedLayoutContext, + cached_local_layout_context: *mut LocalLayoutContext, +} - unsafe { - if APPLICABLE_DECLARATIONS_CACHE == ptr::mut_null() { - let cache = box ApplicableDeclarationsCache::new(); - APPLICABLE_DECLARATIONS_CACHE = mem::transmute(cache) - } - mem::transmute(APPLICABLE_DECLARATIONS_CACHE) - } - } +impl<'a> LayoutContext<'a> { + pub fn new(shared_layout_context: &'a SharedLayoutContext) -> LayoutContext<'a> { - pub fn style_sharing_candidate_cache<'a>(&'a self) -> &'a mut StyleSharingCandidateCache { - // Sanity check. - { - let mut task = Local::borrow(None::<Task>); - match task.maybe_take_runtime::<GreenTask>() { - Some(green) => { - task.put_runtime(green); - fail!("can't call this on a green task!") - } - None => {} - } - } + let local_context = create_or_get_local_context(shared_layout_context); - unsafe { - if STYLE_SHARING_CANDIDATE_CACHE == ptr::mut_null() { - let cache = box StyleSharingCandidateCache::new(); - STYLE_SHARING_CANDIDATE_CACHE = mem::transmute(cache) - } - mem::transmute(STYLE_SHARING_CANDIDATE_CACHE) + LayoutContext { + shared: shared_layout_context, + cached_local_layout_context: local_context, } } -} - -// On Android, we don't have the __tls_* functions emitted by rustc, so we -// need to use the slower local_data functions. -// Making matters worse, the local_data functions are very particular about -// enforcing the lifetimes associated with objects that they hold onto, -// which causes us some trouble we work around as below. -#[cfg(target_os="android")] -impl LayoutContext { - pub fn font_context<'a>(&'a mut self) -> &'a mut FontContext { + #[inline(always)] + pub fn font_context<'a>(&'a self) -> &'a mut FontContext { unsafe { - let opt = font_context.replace(None); - let mut context; - match opt { - Some(c) => context = mem::transmute(c), - None => { - context = mem::transmute(box FontContext::new(self.font_cache_task.clone())) - } - } - font_context.replace(Some(context)); - mem::transmute(context) + let cached_context = &*self.cached_local_layout_context; + mem::transmute(&cached_context.font_context) } } + #[inline(always)] pub fn applicable_declarations_cache<'a>(&'a self) -> &'a mut ApplicableDeclarationsCache { unsafe { - let opt = applicable_declarations_cache.replace(None); - let mut cache; - match opt { - Some(c) => cache = mem::transmute(c), - None => { - cache = mem::transmute(box ApplicableDeclarationsCache::new()); - } - } - applicable_declarations_cache.replace(Some(cache)); - mem::transmute(cache) + let cached_context = &*self.cached_local_layout_context; + mem::transmute(&cached_context.applicable_declarations_cache) } } + #[inline(always)] pub fn style_sharing_candidate_cache<'a>(&'a self) -> &'a mut StyleSharingCandidateCache { unsafe { - let opt = style_sharing_candidate_cache.replace(None); - let mut cache; - match opt { - Some(c) => cache = mem::transmute(c), - None => { - cache = mem::transmute(box StyleSharingCandidateCache::new()); - } - } - style_sharing_candidate_cache.replace(Some(cache)); - mem::transmute(cache) + let cached_context = &*self.cached_local_layout_context; + mem::transmute(&cached_context.style_sharing_candidate_cache) } } } - diff --git a/src/components/layout/css/matching.rs b/src/components/layout/css/matching.rs index f6104195dab..3c7ee0d9a4c 100644 --- a/src/components/layout/css/matching.rs +++ b/src/components/layout/css/matching.rs @@ -11,7 +11,6 @@ use extra::LayoutAuxMethods; use util::{LayoutDataAccess, LayoutDataWrapper}; use wrapper::{LayoutElement, LayoutNode, PostorderNodeMutTraversal, ThreadSafeLayoutNode}; -use gfx::font_context::FontContext; use servo_util::atom::Atom; use servo_util::cache::{Cache, LRUCache, SimpleHashCache}; use servo_util::namespace::Null; @@ -283,13 +282,9 @@ pub trait MatchMethods { /// sequentially. fn recalc_style_for_subtree(&self, stylist: &Stylist, - layout_context: &mut LayoutContext, - mut font_context: Box<FontContext>, + layout_context: &LayoutContext, applicable_declarations: &mut ApplicableDeclarations, - applicable_declarations_cache: &mut ApplicableDeclarationsCache, - style_sharing_candidate_cache: &mut StyleSharingCandidateCache, - parent: Option<LayoutNode>) - -> Box<FontContext>; + parent: Option<LayoutNode>); fn match_node(&self, stylist: &Stylist, @@ -462,18 +457,14 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { fn recalc_style_for_subtree(&self, stylist: &Stylist, - layout_context: &mut LayoutContext, - mut font_context: Box<FontContext>, + layout_context: &LayoutContext, applicable_declarations: &mut ApplicableDeclarations, - applicable_declarations_cache: &mut ApplicableDeclarationsCache, - style_sharing_candidate_cache: &mut StyleSharingCandidateCache, - parent: Option<LayoutNode>) - -> Box<FontContext> { - self.initialize_layout_data(layout_context.layout_chan.clone()); + parent: Option<LayoutNode>) { + self.initialize_layout_data(layout_context.shared.layout_chan.clone()); // First, check to see whether we can share a style with someone. let sharing_result = unsafe { - self.share_style_if_possible(style_sharing_candidate_cache, parent.clone()) + self.share_style_if_possible(layout_context.style_sharing_candidate_cache(), parent.clone()) }; // Otherwise, match and cascade selectors. @@ -486,34 +477,30 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { unsafe { self.cascade_node(parent, applicable_declarations, - applicable_declarations_cache) + layout_context.applicable_declarations_cache()) } applicable_declarations.clear(); // Add ourselves to the LRU cache. if shareable { - style_sharing_candidate_cache.insert_if_possible(self) + layout_context.style_sharing_candidate_cache().insert_if_possible(self) } } - StyleWasShared(index) => style_sharing_candidate_cache.touch(index), + StyleWasShared(index) => layout_context.style_sharing_candidate_cache().touch(index), } for kid in self.children() { - font_context = kid.recalc_style_for_subtree(stylist, - layout_context, - font_context, - applicable_declarations, - applicable_declarations_cache, - style_sharing_candidate_cache, - Some(self.clone())) + kid.recalc_style_for_subtree(stylist, + layout_context, + applicable_declarations, + Some(self.clone())) } // Construct flows. let layout_node = ThreadSafeLayoutNode::new(self); - let mut flow_constructor = FlowConstructor::new(layout_context, Some(font_context)); + let mut flow_constructor = FlowConstructor::new(layout_context); flow_constructor.process(&layout_node); - flow_constructor.unwrap_font_context().unwrap() } unsafe fn cascade_node(&self, diff --git a/src/components/layout/flow.rs b/src/components/layout/flow.rs index 6f124ca81f1..e401a1f75c6 100644 --- a/src/components/layout/flow.rs +++ b/src/components/layout/flow.rs @@ -149,24 +149,24 @@ pub trait Flow: fmt::Show + ToString + Share { /// this flow, all child flows have had their minimum and preferred inline-sizes set. This function /// must decide minimum/preferred inline-sizes based on its children's inline-sizes and the dimensions of /// any boxes it is responsible for flowing. - fn bubble_inline_sizes(&mut self, _ctx: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, _ctx: &LayoutContext) { fail!("bubble_inline_sizes not yet implemented") } /// Pass 2 of reflow: computes inline-size. - fn assign_inline_sizes(&mut self, _ctx: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, _ctx: &LayoutContext) { fail!("assign_inline_sizes not yet implemented") } /// Pass 3a of reflow: computes block-size. - fn assign_block_size(&mut self, _ctx: &mut LayoutContext) { + fn assign_block_size<'a>(&mut self, _ctx: &'a LayoutContext<'a>) { fail!("assign_block_size not yet implemented") } /// Assigns block-sizes in-order; or, if this is a float, places the float. The default /// implementation simply assigns block-sizes if this flow is impacted by floats. Returns true if /// this child was impacted by floats or false otherwise. - fn assign_block_size_for_inorder_child_if_necessary(&mut self, layout_context: &mut LayoutContext) + fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self, layout_context: &'a LayoutContext<'a>) -> bool { let impacted = base(&*self).flags.impacted_by_floats(); if impacted { @@ -365,7 +365,7 @@ pub trait MutableFlowUtils { // Mutators /// Computes the overflow region for this flow. - fn store_overflow(self, _: &mut LayoutContext); + fn store_overflow(self, _: &LayoutContext); /// Builds the display lists for this flow. fn build_display_list(self, layout_context: &LayoutContext); @@ -963,7 +963,7 @@ impl<'a> MutableFlowUtils for &'a mut Flow { /// Assumption: This is called in a bottom-up traversal, so kids' overflows have /// already been set. /// Assumption: Absolute descendants have had their overflow calculated. - fn store_overflow(self, _: &mut LayoutContext) { + fn store_overflow(self, _: &LayoutContext) { let my_position = mut_base(self).position; let mut overflow = my_position; diff --git a/src/components/layout/fragment.rs b/src/components/layout/fragment.rs index ab004a3a17d..66ccb6b2d86 100644 --- a/src/components/layout/fragment.rs +++ b/src/components/layout/fragment.rs @@ -660,7 +660,7 @@ impl Fragment { Some(ref image_url) => image_url, }; - let mut holder = ImageHolder::new(image_url.clone(), layout_context.image_cache.clone()); + let mut holder = ImageHolder::new(image_url.clone(), layout_context.shared.image_cache.clone()); let image = match holder.get_image() { None => { // No image data at all? Do nothing. @@ -860,7 +860,7 @@ impl Fragment { absolute_fragment_bounds, self); debug!("Fragment::build_display_list: dirty={}, flow_origin={}", - layout_context.dirty, + layout_context.shared.dirty, flow_origin); let mut accumulator = ChildDisplayListAccumulator::new(self.style(), @@ -871,7 +871,7 @@ impl Fragment { return accumulator } - if !absolute_fragment_bounds.intersects(&layout_context.dirty) { + if !absolute_fragment_bounds.intersects(&layout_context.shared.dirty) { debug!("Fragment::build_display_list: Did not intersect..."); return accumulator } @@ -1431,7 +1431,7 @@ impl Fragment { iframe_fragment.pipeline_id, iframe_fragment.subpage_id); let msg = FrameRectMsg(iframe_fragment.pipeline_id, iframe_fragment.subpage_id, rect); - let ConstellationChan(ref chan) = layout_context.constellation_chan; + let ConstellationChan(ref chan) = layout_context.shared.constellation_chan; chan.send(msg) } } diff --git a/src/components/layout/inline.rs b/src/components/layout/inline.rs index e3aabadff35..89449ca5571 100644 --- a/src/components/layout/inline.rs +++ b/src/components/layout/inline.rs @@ -932,7 +932,7 @@ impl InlineFlow { // FIXME(#2795): Get the real container size let container_size = Size2D::zero(); if !abs_rect.to_physical(self.base.writing_mode, container_size) - .intersects(&layout_context.dirty) { + .intersects(&layout_context.shared.dirty) { return } @@ -1090,7 +1090,7 @@ impl Flow for InlineFlow { self } - fn bubble_inline_sizes(&mut self, _: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, _: &LayoutContext) { let writing_mode = self.base.writing_mode; for kid in self.base.child_iter() { flow::mut_base(kid).floats = Floats::new(writing_mode); @@ -1115,7 +1115,7 @@ impl Flow for InlineFlow { /// Recursively (top-down) determines the actual inline-size of child contexts and fragments. When called /// on this context, the context has had its inline-size set by the parent context. - fn assign_inline_sizes(&mut self, _: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, _: &LayoutContext) { // Initialize content fragment inline-sizes if they haven't been initialized already. // // TODO: Combine this with `LineBreaker`'s walk in the fragment list, or put this into `Fragment`. @@ -1144,7 +1144,7 @@ impl Flow for InlineFlow { } /// Calculate and set the block-size of this flow. See CSS 2.1 § 10.6.1. - fn assign_block_size(&mut self, _: &mut LayoutContext) { + fn assign_block_size(&mut self, _: &LayoutContext) { debug!("assign_block_size_inline: assigning block_size for flow"); // Divide the fragments into lines. diff --git a/src/components/layout/layout_task.rs b/src/components/layout/layout_task.rs index 83809aa137e..0edb9436771 100644 --- a/src/components/layout/layout_task.rs +++ b/src/components/layout/layout_task.rs @@ -5,12 +5,11 @@ //! The layout task. Performs layout on the DOM, builds display lists and sends them to be //! rendered. -use css::matching::{ApplicableDeclarations, ApplicableDeclarationsCache, MatchMethods}; -use css::matching::{StyleSharingCandidateCache}; +use css::matching::{ApplicableDeclarations, MatchMethods}; use css::select::new_stylist; use css::node_style::StyledNode; use construct::{FlowConstructionResult, NoConstructionResult}; -use context::LayoutContext; +use context::{LayoutContext, SharedLayoutContext}; use flow::{Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils}; use flow::{PreorderFlowTraversal, PostorderFlowTraversal}; use flow; @@ -27,7 +26,6 @@ use geom::rect::Rect; use geom::size::Size2D; use gfx::display_list::{ClipDisplayItemClass, ContentStackingLevel, DisplayItem}; use gfx::display_list::{DisplayItemIterator, DisplayList, OpaqueNode}; -use gfx::font_context::FontContext; use gfx::render_task::{RenderInitMsg, RenderChan, RenderLayer}; use gfx::{render_task, color}; use layout_traits; @@ -104,7 +102,7 @@ pub struct LayoutTask { pub stylist: Box<Stylist>, /// The workers that we use for parallel operation. - pub parallel_traversal: Option<WorkQueue<*mut LayoutContext,UnsafeFlow>>, + pub parallel_traversal: Option<WorkQueue<*const SharedLayoutContext,UnsafeFlow>>, /// The channel on which messages can be sent to the time profiler. pub time_profiler_chan: TimeProfilerChan, @@ -178,7 +176,7 @@ impl PreorderFlowTraversal for FlowTreeVerificationTraversal { /// The bubble-inline-sizes traversal, the first part of layout computation. This computes preferred /// and intrinsic inline-sizes and bubbles them up the tree. pub struct BubbleISizesTraversal<'a> { - pub layout_context: &'a mut LayoutContext, + pub layout_context: &'a LayoutContext<'a>, } impl<'a> PostorderFlowTraversal for BubbleISizesTraversal<'a> { @@ -199,7 +197,7 @@ impl<'a> PostorderFlowTraversal for BubbleISizesTraversal<'a> { /// The assign-inline-sizes traversal. In Gecko this corresponds to `Reflow`. pub struct AssignISizesTraversal<'a> { - pub layout_context: &'a mut LayoutContext, + pub layout_context: &'a LayoutContext<'a>, } impl<'a> PreorderFlowTraversal for AssignISizesTraversal<'a> { @@ -214,7 +212,7 @@ impl<'a> PreorderFlowTraversal for AssignISizesTraversal<'a> { /// computation. Determines the final block-sizes for all layout objects, computes positions, and /// computes overflow regions. In Gecko this corresponds to `FinishAndStoreOverflow`. pub struct AssignBSizesAndStoreOverflowTraversal<'a> { - pub layout_context: &'a mut LayoutContext, + pub layout_context: &'a LayoutContext<'a>, } impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflowTraversal<'a> { @@ -237,7 +235,7 @@ impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflowTraversal<'a> { /// The display list construction traversal. pub struct BuildDisplayListTraversal<'a> { - layout_context: &'a LayoutContext, + layout_context: &'a LayoutContext<'a>, } impl<'a> BuildDisplayListTraversal<'a> { @@ -330,7 +328,7 @@ impl LayoutTask { let local_image_cache = Arc::new(Mutex::new(LocalImageCache::new(image_cache_task.clone()))); let screen_size = Size2D(Au(0), Au(0)); let parallel_traversal = if opts.layout_threads != 1 { - Some(WorkQueue::new("LayoutWorker", opts.layout_threads, ptr::mut_null())) + Some(WorkQueue::new("LayoutWorker", opts.layout_threads, ptr::null())) } else { None }; @@ -365,8 +363,8 @@ impl LayoutTask { } // Create a layout context for use in building display lists, hit testing, &c. - fn build_layout_context(&self, reflow_root: &LayoutNode, url: &Url) -> LayoutContext { - LayoutContext { + fn build_shared_layout_context(&self, reflow_root: &LayoutNode, url: &Url) -> SharedLayoutContext { + SharedLayoutContext { image_cache: self.local_image_cache.clone(), screen_size: self.screen_size.clone(), constellation_chan: self.constellation_chan.clone(), @@ -542,10 +540,10 @@ impl LayoutTask { /// This corresponds to `Reflow()` in Gecko and `layout()` in WebKit/Blink and should be /// benchmarked against those two. It is marked `#[inline(never)]` to aid profiling. #[inline(never)] - fn solve_constraints(&mut self, + fn solve_constraints<'a>(&mut self, layout_root: &mut Flow, - layout_context: &mut LayoutContext) { - if layout_context.opts.bubble_inline_sizes_separately { + layout_context: &'a LayoutContext<'a>) { + if layout_context.shared.opts.bubble_inline_sizes_separately { let mut traversal = BubbleISizesTraversal { layout_context: layout_context, }; @@ -580,10 +578,10 @@ impl LayoutTask { #[inline(never)] fn solve_constraints_parallel(&mut self, layout_root: &mut FlowRef, - layout_context: &mut LayoutContext) { - if layout_context.opts.bubble_inline_sizes_separately { + shared_layout_context: &SharedLayoutContext) { + if shared_layout_context.opts.bubble_inline_sizes_separately { let mut traversal = BubbleISizesTraversal { - layout_context: layout_context, + layout_context: &LayoutContext::new(shared_layout_context), }; layout_root.get_mut().traverse_postorder(&mut traversal); } @@ -595,7 +593,7 @@ impl LayoutTask { // operation out. parallel::traverse_flow_tree_preorder(layout_root, self.time_profiler_chan.clone(), - layout_context, + shared_layout_context, traversal); } } @@ -654,17 +652,7 @@ impl LayoutTask { self.screen_size = current_screen_size; // Create a layout context for use throughout the following passes. - let mut layout_ctx = self.build_layout_context(node, &data.url); - - // Create a font context, if this is sequential. - // - // FIXME(pcwalton): This is a pretty bogus thing to do. Essentially this is a workaround - // for libgreen having slow TLS. - let mut font_context_opt = if self.parallel_traversal.is_none() { - Some(box FontContext::new(layout_ctx.font_cache_task.clone())) - } else { - None - }; + let mut shared_layout_ctx = self.build_shared_layout_context(node, &data.url); let mut layout_root = profile(time::LayoutStyleRecalcCategory, self.time_profiler_chan.clone(), @@ -672,19 +660,15 @@ impl LayoutTask { // Perform CSS selector matching and flow construction. match self.parallel_traversal { None => { + let layout_ctx = LayoutContext::new(&shared_layout_ctx); let mut applicable_declarations = ApplicableDeclarations::new(); - let mut applicable_declarations_cache = ApplicableDeclarationsCache::new(); - let mut style_sharing_candidate_cache = StyleSharingCandidateCache::new(); - drop(node.recalc_style_for_subtree(&*self.stylist, - &mut layout_ctx, - font_context_opt.take_unwrap(), - &mut applicable_declarations, - &mut applicable_declarations_cache, - &mut style_sharing_candidate_cache, - None)) + node.recalc_style_for_subtree(&*self.stylist, + &layout_ctx, + &mut applicable_declarations, + None) } Some(ref mut traversal) => { - parallel::recalc_style_for_subtree(node, &mut layout_ctx, traversal) + parallel::recalc_style_for_subtree(node, &mut shared_layout_ctx, traversal) } } @@ -710,11 +694,12 @@ impl LayoutTask { match self.parallel_traversal { None => { // Sequential mode. - self.solve_constraints(layout_root.get_mut(), &mut layout_ctx) + let layout_ctx = LayoutContext::new(&shared_layout_ctx); + self.solve_constraints(layout_root.get_mut(), &layout_ctx) } Some(_) => { // Parallel mode. - self.solve_constraints_parallel(&mut layout_root, &mut layout_ctx) + self.solve_constraints_parallel(&mut layout_root, &mut shared_layout_ctx) } } }); @@ -725,11 +710,12 @@ impl LayoutTask { profile(time::LayoutDispListBuildCategory, self.time_profiler_chan.clone(), || { // FIXME(#2795): Get the real container size let container_size = Size2D::zero(); - layout_ctx.dirty = flow::base(layout_root.get()).position.to_physical( + shared_layout_ctx.dirty = flow::base(layout_root.get()).position.to_physical( writing_mode, container_size); match self.parallel_traversal { None => { + let layout_ctx = LayoutContext::new(&shared_layout_ctx); let mut traversal = BuildDisplayListTraversal { layout_context: &layout_ctx, }; @@ -738,7 +724,7 @@ impl LayoutTask { Some(ref mut traversal) => { parallel::build_display_list_for_subtree(&mut layout_root, self.time_profiler_chan.clone(), - &mut layout_ctx, + &mut shared_layout_ctx, traversal); } } diff --git a/src/components/layout/parallel.rs b/src/components/layout/parallel.rs index aa184cafda6..a2786e8ba91 100644 --- a/src/components/layout/parallel.rs +++ b/src/components/layout/parallel.rs @@ -8,7 +8,7 @@ use css::matching::{ApplicableDeclarations, CannotShare, MatchMethods, StyleWasShared}; use construct::FlowConstructor; -use context::LayoutContext; +use context::{LayoutContext, SharedLayoutContext}; use extra::LayoutAuxMethods; use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal}; use flow; @@ -116,7 +116,7 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { /// fetch-and-subtract the parent's children count. fn run_parallel(&mut self, mut unsafe_flow: UnsafeFlow, - _: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { + _: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { loop { unsafe { // Get a real flow. @@ -160,17 +160,17 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal { trait ParallelPreorderFlowTraversal : PreorderFlowTraversal { fn run_parallel(&mut self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>); + proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>); #[inline(always)] fn run_parallel_helper(&mut self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>, + proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>, top_down_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*mut LayoutContext, + &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>), bottom_up_func: extern "Rust" fn(UnsafeFlow, - &mut WorkerProxy<*mut LayoutContext, + &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>)) { let mut had_children = false; unsafe { @@ -203,7 +203,7 @@ impl<'a> ParallelPostorderFlowTraversal for BubbleISizesTraversal<'a> {} impl<'a> ParallelPreorderFlowTraversal for AssignISizesTraversal<'a> { fn run_parallel(&mut self, unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { + proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { self.run_parallel_helper(unsafe_flow, proxy, assign_inline_sizes, @@ -214,8 +214,9 @@ impl<'a> ParallelPreorderFlowTraversal for AssignISizesTraversal<'a> { impl<'a> ParallelPostorderFlowTraversal for AssignBSizesAndStoreOverflowTraversal<'a> {} fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeLayoutNode>) { - let layout_context = unsafe { &mut **proxy.user_data() }; + proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>) { + let shared_layout_context = unsafe { &**proxy.user_data() }; + let layout_context = LayoutContext::new(shared_layout_context); // Get a real layout node. let node: LayoutNode = unsafe { @@ -226,11 +227,11 @@ fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode, // // FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML // parser. - node.initialize_layout_data(layout_context.layout_chan.clone()); + node.initialize_layout_data(layout_context.shared.layout_chan.clone()); // Get the parent node. let opaque_node: OpaqueNode = OpaqueNodeMethods::from_layout_node(&node); - let parent_opt = if opaque_node == layout_context.reflow_root { + let parent_opt = if opaque_node == layout_context.shared.reflow_root { None } else { node.parent_node() @@ -250,7 +251,7 @@ fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode, if node.is_element() { // Perform the CSS selector matching. - let stylist = unsafe { &*layout_context.stylist }; + let stylist = unsafe { &*layout_context.shared.stylist }; node.match_node(stylist, &mut applicable_declarations, &mut shareable); } @@ -302,14 +303,12 @@ fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode, } // If we got here, we're a leaf. Start construction of flows for this node. - construct_flows(unsafe_layout_node, proxy) + construct_flows(unsafe_layout_node, &layout_context) } fn construct_flows(mut unsafe_layout_node: UnsafeLayoutNode, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeLayoutNode>) { + layout_context: &LayoutContext) { loop { - let layout_context = unsafe { &mut **proxy.user_data() }; - // Get a real layout node. let node: LayoutNode = unsafe { layout_node_from_unsafe_layout_node(&unsafe_layout_node) @@ -317,7 +316,7 @@ fn construct_flows(mut unsafe_layout_node: UnsafeLayoutNode, // Construct flows for this node. { - let mut flow_constructor = FlowConstructor::new(layout_context, None); + let mut flow_constructor = FlowConstructor::new(layout_context); flow_constructor.process(&ThreadSafeLayoutNode::new(&node)); } @@ -340,7 +339,7 @@ fn construct_flows(mut unsafe_layout_node: UnsafeLayoutNode, // If this is the reflow root, we're done. let opaque_node: OpaqueNode = OpaqueNodeMethods::from_layout_node(&node); - if layout_context.reflow_root == opaque_node { + if layout_context.shared.reflow_root == opaque_node { break } @@ -376,25 +375,27 @@ fn construct_flows(mut unsafe_layout_node: UnsafeLayoutNode, } fn assign_inline_sizes(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { - let layout_context = unsafe { &mut **proxy.user_data() }; + proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { + let shared_layout_context = unsafe { &**proxy.user_data() }; + let layout_context = LayoutContext::new(shared_layout_context); let mut assign_inline_sizes_traversal = AssignISizesTraversal { - layout_context: layout_context, + layout_context: &layout_context, }; assign_inline_sizes_traversal.run_parallel(unsafe_flow, proxy) } fn assign_block_sizes_and_store_overflow(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { - let layout_context = unsafe { &mut **proxy.user_data() }; + proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { + let shared_layout_context = unsafe { &**proxy.user_data() }; + let layout_context = LayoutContext::new(shared_layout_context); let mut assign_block_sizes_traversal = AssignBSizesAndStoreOverflowTraversal { - layout_context: layout_context, + layout_context: &layout_context, }; assign_block_sizes_traversal.run_parallel(unsafe_flow, proxy) } fn compute_absolute_position(unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { + proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { let mut had_descendants = false; unsafe { // Get a real flow. @@ -448,8 +449,9 @@ fn compute_absolute_position(unsafe_flow: UnsafeFlow, } fn build_display_list(mut unsafe_flow: UnsafeFlow, - proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeFlow>) { - let layout_context = unsafe { &mut **proxy.user_data() }; + proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) { + let shared_layout_context = unsafe { &**proxy.user_data() }; + let layout_context = LayoutContext::new(shared_layout_context); loop { unsafe { @@ -457,7 +459,7 @@ fn build_display_list(mut unsafe_flow: UnsafeFlow, let flow: &mut FlowRef = mem::transmute(&unsafe_flow); // Build display lists. - flow.get_mut().build_display_list(layout_context); + flow.get_mut().build_display_list(&layout_context); { let base = flow::mut_base(flow.get_mut()); @@ -506,9 +508,9 @@ fn build_display_list(mut unsafe_flow: UnsafeFlow, } pub fn recalc_style_for_subtree(root_node: &LayoutNode, - layout_context: &mut LayoutContext, - queue: &mut WorkQueue<*mut LayoutContext,UnsafeLayoutNode>) { - queue.data = layout_context as *mut _; + shared_layout_context: &SharedLayoutContext, + queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeLayoutNode>) { + queue.data = shared_layout_context as *const _; // Enqueue the root node. queue.push(WorkUnit { @@ -518,14 +520,14 @@ pub fn recalc_style_for_subtree(root_node: &LayoutNode, queue.run(); - queue.data = ptr::mut_null() + queue.data = ptr::null() } pub fn traverse_flow_tree_preorder(root: &mut FlowRef, time_profiler_chan: TimeProfilerChan, - layout_context: &mut LayoutContext, - queue: &mut WorkQueue<*mut LayoutContext,UnsafeFlow>) { - queue.data = layout_context as *mut _; + shared_layout_context: &SharedLayoutContext, + queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) { + queue.data = shared_layout_context as *const _; profile(time::LayoutParallelWarmupCategory, time_profiler_chan, || { queue.push(WorkUnit { @@ -536,14 +538,14 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef, queue.run(); - queue.data = ptr::mut_null() + queue.data = ptr::null() } pub fn build_display_list_for_subtree(root: &mut FlowRef, time_profiler_chan: TimeProfilerChan, - layout_context: &mut LayoutContext, - queue: &mut WorkQueue<*mut LayoutContext,UnsafeFlow>) { - queue.data = layout_context as *mut _; + shared_layout_context: &SharedLayoutContext, + queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) { + queue.data = shared_layout_context as *const _; profile(time::LayoutParallelWarmupCategory, time_profiler_chan, || { queue.push(WorkUnit { @@ -554,6 +556,6 @@ pub fn build_display_list_for_subtree(root: &mut FlowRef, queue.run(); - queue.data = ptr::mut_null() + queue.data = ptr::null() } diff --git a/src/components/layout/table.rs b/src/components/layout/table.rs index db6993c2a5e..98569d68c95 100644 --- a/src/components/layout/table.rs +++ b/src/components/layout/table.rs @@ -125,7 +125,7 @@ impl TableFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - fn assign_block_size_table_base(&mut self, layout_context: &mut LayoutContext) { + fn assign_block_size_table_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { self.block_flow.assign_block_size_block_base(layout_context, MarginsMayNotCollapse); } @@ -164,7 +164,7 @@ impl Flow for TableFlow { /// table layout calculation. /// The maximum min/pref inline-sizes of each column are set from the rows for the automatic /// table layout calculation. - fn bubble_inline_sizes(&mut self, _: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, _: &LayoutContext) { let mut min_inline_size = Au(0); let mut pref_inline_size = Au(0); let mut did_first_row = false; @@ -235,7 +235,7 @@ impl Flow for TableFlow { /// Recursively (top-down) determines the actual inline-size of child contexts and fragments. When /// called on this context, the context has had its inline-size set by the parent context. - fn assign_inline_sizes(&mut self, ctx: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, ctx: &LayoutContext) { debug!("assign_inline_sizes({}): assigning inline_size for flow", "table"); // The position was set to the containing block by the flow's parent. @@ -282,7 +282,7 @@ impl Flow for TableFlow { self.block_flow.propagate_assigned_inline_size_to_children(inline_start_content_edge, content_inline_size, Some(self.col_inline_sizes.clone())); } - fn assign_block_size(&mut self, ctx: &mut LayoutContext) { + fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { debug!("assign_block_size: assigning block_size for table"); self.assign_block_size_table_base(ctx); } @@ -309,7 +309,7 @@ impl ISizeAndMarginsComputer for InternalTable { /// CSS Section 10.4: Minimum and Maximum inline-sizes fn compute_used_inline_size(&self, block: &mut BlockFlow, - ctx: &mut LayoutContext, + ctx: &LayoutContext, parent_flow_inline_size: Au) { let input = self.compute_inline_size_constraint_inputs(block, parent_flow_inline_size, ctx); let solution = self.solve_inline_size_constraints(block, &input); diff --git a/src/components/layout/table_caption.rs b/src/components/layout/table_caption.rs index 9ad0e017813..8c1dba3e7ca 100644 --- a/src/components/layout/table_caption.rs +++ b/src/components/layout/table_caption.rs @@ -47,16 +47,16 @@ impl Flow for TableCaptionFlow { &mut self.block_flow } - fn bubble_inline_sizes(&mut self, ctx: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, ctx: &LayoutContext) { self.block_flow.bubble_inline_sizes(ctx); } - fn assign_inline_sizes(&mut self, ctx: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, ctx: &LayoutContext) { debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_caption"); self.block_flow.assign_inline_sizes(ctx); } - fn assign_block_size(&mut self, ctx: &mut LayoutContext) { + fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { debug!("assign_block_size: assigning block_size for table_caption"); self.block_flow.assign_block_size(ctx); } diff --git a/src/components/layout/table_cell.rs b/src/components/layout/table_cell.rs index 57bc806f7fc..0011cd29fbc 100644 --- a/src/components/layout/table_cell.rs +++ b/src/components/layout/table_cell.rs @@ -45,7 +45,7 @@ impl TableCellFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - fn assign_block_size_table_cell_base(&mut self, layout_context: &mut LayoutContext) { + fn assign_block_size_table_cell_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { self.block_flow.assign_block_size_block_base(layout_context, MarginsMayNotCollapse) } @@ -69,7 +69,7 @@ impl Flow for TableCellFlow { } /// Minimum/preferred inline-sizes set by this function are used in automatic table layout calculation. - fn bubble_inline_sizes(&mut self, ctx: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, ctx: &LayoutContext) { self.block_flow.bubble_inline_sizes(ctx); let specified_inline_size = MaybeAuto::from_style(self.block_flow.fragment.style().content_inline_size(), Au::new(0)).specified_or_zero(); @@ -85,7 +85,7 @@ impl Flow for TableCellFlow { /// Recursively (top-down) determines the actual inline-size of child contexts and fragments. When /// called on this context, the context has had its inline-size set by the parent table row. - fn assign_inline_sizes(&mut self, ctx: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, ctx: &LayoutContext) { debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_cell"); // The position was set to the column inline-size by the parent flow, table row flow. @@ -104,7 +104,7 @@ impl Flow for TableCellFlow { None); } - fn assign_block_size(&mut self, ctx: &mut LayoutContext) { + fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { debug!("assign_block_size: assigning block_size for table_cell"); self.assign_block_size_table_cell_base(ctx); } diff --git a/src/components/layout/table_colgroup.rs b/src/components/layout/table_colgroup.rs index a27cff86deb..270f55970b2 100644 --- a/src/components/layout/table_colgroup.rs +++ b/src/components/layout/table_colgroup.rs @@ -52,7 +52,7 @@ impl Flow for TableColGroupFlow { self } - fn bubble_inline_sizes(&mut self, _: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, _: &LayoutContext) { for fragment in self.cols.iter() { // get the specified value from inline-size property let inline_size = MaybeAuto::from_style(fragment.style().content_inline_size(), @@ -70,11 +70,11 @@ impl Flow for TableColGroupFlow { /// Table column inline-sizes are assigned in table flow and propagated to table row or rowgroup flow. /// Therefore, table colgroup flow does not need to assign its inline-size. - fn assign_inline_sizes(&mut self, _ctx: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, _ctx: &LayoutContext) { } /// Table column do not have block-size. - fn assign_block_size(&mut self, _ctx: &mut LayoutContext) { + fn assign_block_size(&mut self, _ctx: &LayoutContext) { } } diff --git a/src/components/layout/table_row.rs b/src/components/layout/table_row.rs index 6e8f5bfcfd7..101f00eb5cc 100644 --- a/src/components/layout/table_row.rs +++ b/src/components/layout/table_row.rs @@ -75,7 +75,7 @@ impl TableRowFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - fn assign_block_size_table_row_base(&mut self, layout_context: &mut LayoutContext) { + fn assign_block_size_table_row_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { let (block_start_offset, _, _) = self.initialize_offsets(); let /* mut */ cur_y = block_start_offset; @@ -165,7 +165,7 @@ impl Flow for TableRowFlow { /// responsible for flowing. /// Min/pref inline-sizes set by this function are used in automatic table layout calculation. /// The specified column inline-sizes of children cells are used in fixed table layout calculation. - fn bubble_inline_sizes(&mut self, _: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, _: &LayoutContext) { let mut min_inline_size = Au(0); let mut pref_inline_size = Au(0); /* find the specified inline_sizes from child table-cell contexts */ @@ -194,7 +194,7 @@ impl Flow for TableRowFlow { /// Recursively (top-down) determines the actual inline-size of child contexts and fragments. When called /// on this context, the context has had its inline-size set by the parent context. - fn assign_inline_sizes(&mut self, ctx: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, ctx: &LayoutContext) { debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_row"); // The position was set to the containing block by the flow's parent. @@ -208,7 +208,7 @@ impl Flow for TableRowFlow { self.block_flow.propagate_assigned_inline_size_to_children(inline_start_content_edge, Au(0), Some(self.col_inline_sizes.clone())); } - fn assign_block_size(&mut self, ctx: &mut LayoutContext) { + fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { debug!("assign_block_size: assigning block_size for table_row"); self.assign_block_size_table_row_base(ctx); } diff --git a/src/components/layout/table_rowgroup.rs b/src/components/layout/table_rowgroup.rs index b39bee19596..48f9d376af3 100644 --- a/src/components/layout/table_rowgroup.rs +++ b/src/components/layout/table_rowgroup.rs @@ -74,7 +74,7 @@ impl TableRowGroupFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - fn assign_block_size_table_rowgroup_base(&mut self, layout_context: &mut LayoutContext) { + fn assign_block_size_table_rowgroup_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { let (block_start_offset, _, _) = self.initialize_offsets(); let mut cur_y = block_start_offset; @@ -133,7 +133,7 @@ impl Flow for TableRowGroupFlow { /// Min/pref inline-sizes set by this function are used in automatic table layout calculation. /// Also, this function finds the specified column inline-sizes from the first row. /// Those are used in fixed table layout calculation - fn bubble_inline_sizes(&mut self, _: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, _: &LayoutContext) { let mut min_inline_size = Au(0); let mut pref_inline_size = Au(0); @@ -175,7 +175,7 @@ impl Flow for TableRowGroupFlow { /// Recursively (top-down) determines the actual inline-size of child contexts and fragments. When /// called on this context, the context has had its inline-size set by the parent context. - fn assign_inline_sizes(&mut self, ctx: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, ctx: &LayoutContext) { debug!("assign_inline_sizes({}): assigning inline_size for flow", "table_rowgroup"); // The position was set to the containing block by the flow's parent. @@ -191,7 +191,7 @@ impl Flow for TableRowGroupFlow { self.block_flow.propagate_assigned_inline_size_to_children(inline_start_content_edge, content_inline_size, Some(self.col_inline_sizes.clone())); } - fn assign_block_size(&mut self, ctx: &mut LayoutContext) { + fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { debug!("assign_block_size: assigning block_size for table_rowgroup"); self.assign_block_size_table_rowgroup_base(ctx); } diff --git a/src/components/layout/table_wrapper.rs b/src/components/layout/table_wrapper.rs index 5d431e18c4e..2084ef52bdc 100644 --- a/src/components/layout/table_wrapper.rs +++ b/src/components/layout/table_wrapper.rs @@ -100,7 +100,7 @@ impl TableWrapperFlow { /// inline(always) because this is only ever called by in-order or non-in-order top-level /// methods #[inline(always)] - fn assign_block_size_table_wrapper_base(&mut self, layout_context: &mut LayoutContext) { + fn assign_block_size_table_wrapper_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) { self.block_flow.assign_block_size_block_base(layout_context, MarginsMayNotCollapse); } @@ -129,7 +129,7 @@ impl Flow for TableWrapperFlow { min/pref inline_sizes based on child context inline_sizes and dimensions of any fragments it is responsible for flowing. */ - fn bubble_inline_sizes(&mut self, ctx: &mut LayoutContext) { + fn bubble_inline_sizes(&mut self, ctx: &LayoutContext) { // get column inline-sizes info from table flow for kid in self.block_flow.base.child_iter() { assert!(kid.is_table_caption() || kid.is_table()); @@ -147,7 +147,7 @@ impl Flow for TableWrapperFlow { /// /// Dual fragments consume some inline-size first, and the remainder is assigned to all child (block) /// contexts. - fn assign_inline_sizes(&mut self, ctx: &mut LayoutContext) { + fn assign_inline_sizes(&mut self, ctx: &LayoutContext) { debug!("assign_inline_sizes({}): assigning inline_size for flow", if self.is_float() { "floated table_wrapper" @@ -178,7 +178,7 @@ impl Flow for TableWrapperFlow { self.block_flow.propagate_assigned_inline_size_to_children(inline_start_content_edge, content_inline_size, assigned_col_inline_sizes); } - fn assign_block_size(&mut self, ctx: &mut LayoutContext) { + fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) { if self.is_float() { debug!("assign_block_size_float: assigning block_size for floated table_wrapper"); self.block_flow.assign_block_size_float(ctx); @@ -208,7 +208,7 @@ struct TableWrapper; impl TableWrapper { fn compute_used_inline_size_table_wrapper(&self, table_wrapper: &mut TableWrapperFlow, - ctx: &mut LayoutContext, + ctx: &LayoutContext, parent_flow_inline_size: Au) { let input = self.compute_inline_size_constraint_inputs_table_wrapper(table_wrapper, parent_flow_inline_size, @@ -223,7 +223,7 @@ impl TableWrapper { fn compute_inline_size_constraint_inputs_table_wrapper(&self, table_wrapper: &mut TableWrapperFlow, parent_flow_inline_size: Au, - ctx: &mut LayoutContext) + ctx: &LayoutContext) -> ISizeConstraintInput { let mut input = self.compute_inline_size_constraint_inputs(&mut table_wrapper.block_flow, parent_flow_inline_size, |