mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
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.
This commit is contained in:
parent
4062af69ec
commit
4a0e01b4f0
16 changed files with 215 additions and 358 deletions
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
struct LocalLayoutContext {
|
||||
font_context: FontContext,
|
||||
applicable_declarations_cache: ApplicableDeclarationsCache,
|
||||
style_sharing_candidate_cache: StyleSharingCandidateCache,
|
||||
}
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
local_data_key!(font_context: *mut FontContext)
|
||||
local_data_key!(local_context_key: *mut LocalLayoutContext)
|
||||
|
||||
#[cfg(not(target_os="android"))]
|
||||
#[thread_local]
|
||||
static mut APPLICABLE_DECLARATIONS_CACHE: *mut ApplicableDeclarationsCache =
|
||||
0 as *mut ApplicableDeclarationsCache;
|
||||
fn create_or_get_local_context(shared_layout_context: &SharedLayoutContext) -> *mut LocalLayoutContext {
|
||||
let maybe_context = local_context_key.get();
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
local_data_key!(applicable_declarations_cache: *mut ApplicableDeclarationsCache)
|
||||
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
|
||||
};
|
||||
|
||||
#[cfg(not(target_os="android"))]
|
||||
#[thread_local]
|
||||
static mut STYLE_SHARING_CANDIDATE_CACHE: *mut StyleSharingCandidateCache =
|
||||
0 as *mut StyleSharingCandidateCache;
|
||||
*context
|
||||
}
|
||||
|
||||
#[cfg(target_os="android")]
|
||||
local_data_key!(style_sharing_candidate_cache: *mut StyleSharingCandidateCache)
|
||||
|
||||
/// 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 => {}
|
||||
pub struct LayoutContext<'a> {
|
||||
pub shared: &'a SharedLayoutContext,
|
||||
cached_local_layout_context: *mut LocalLayoutContext,
|
||||
}
|
||||
|
||||
impl<'a> LayoutContext<'a> {
|
||||
pub fn new(shared_layout_context: &'a SharedLayoutContext) -> LayoutContext<'a> {
|
||||
|
||||
let local_context = create_or_get_local_context(shared_layout_context);
|
||||
|
||||
LayoutContext {
|
||||
shared: shared_layout_context,
|
||||
cached_local_layout_context: local_context,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn font_context<'a>(&'a self) -> &'a mut FontContext {
|
||||
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)
|
||||
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 {
|
||||
// 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 APPLICABLE_DECLARATIONS_CACHE == ptr::mut_null() {
|
||||
let cache = box ApplicableDeclarationsCache::new();
|
||||
APPLICABLE_DECLARATIONS_CACHE = mem::transmute(cache)
|
||||
}
|
||||
mem::transmute(APPLICABLE_DECLARATIONS_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 {
|
||||
// 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 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)
|
||||
let cached_context = &*self.cached_local_layout_context;
|
||||
mem::transmute(&cached_context.style_sharing_candidate_cache)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
kid.recalc_style_for_subtree(stylist,
|
||||
layout_context,
|
||||
font_context,
|
||||
applicable_declarations,
|
||||
applicable_declarations_cache,
|
||||
style_sharing_candidate_cache,
|
||||
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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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(),
|
||||
node.recalc_style_for_subtree(&*self.stylist,
|
||||
&layout_ctx,
|
||||
&mut applicable_declarations,
|
||||
&mut applicable_declarations_cache,
|
||||
&mut style_sharing_candidate_cache,
|
||||
None))
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue