mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
layout: Add an option to visualize parallel layout
This commit is contained in:
parent
172db80703
commit
40a3b41758
14 changed files with 216 additions and 88 deletions
|
@ -863,6 +863,7 @@ impl BlockFlow {
|
|||
// At this point, `cur_b` is at the content edge of our box. Now iterate over children.
|
||||
let mut floats = self.base.floats.clone();
|
||||
let mut layers_needed_for_descendants = false;
|
||||
let thread_id = self.base.thread_id;
|
||||
for kid in self.base.child_iter() {
|
||||
if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||
// Assume that the *hypothetical box* for an absolute flow starts immediately
|
||||
|
@ -870,7 +871,8 @@ impl BlockFlow {
|
|||
kid.as_block().hypothetical_position.b = cur_b;
|
||||
kid.place_float_if_applicable(layout_context);
|
||||
if !flow::base(kid).flags.is_float() {
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context,
|
||||
thread_id);
|
||||
}
|
||||
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
||||
|
||||
|
@ -910,7 +912,8 @@ impl BlockFlow {
|
|||
|
||||
// Lay the child out if this was an in-order traversal.
|
||||
let need_to_process_child_floats =
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context,
|
||||
thread_id);
|
||||
|
||||
// Mark flows for layerization if necessary to handle painting order correctly.
|
||||
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
||||
|
@ -1047,8 +1050,9 @@ impl BlockFlow {
|
|||
} else {
|
||||
// We don't need to reflow, but we still need to perform in-order traversals if
|
||||
// necessary.
|
||||
let thread_id = self.base.thread_id;
|
||||
for kid in self.base.child_iter() {
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context, thread_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1650,7 +1654,8 @@ impl Flow for BlockFlow {
|
|||
}
|
||||
|
||||
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
|
||||
layout_context: &'a LayoutContext<'a>)
|
||||
layout_context: &'a LayoutContext<'a>,
|
||||
parent_thread_id: u8)
|
||||
-> bool {
|
||||
if self.base.flags.is_float() {
|
||||
return false
|
||||
|
@ -1662,6 +1667,7 @@ impl Flow for BlockFlow {
|
|||
}
|
||||
|
||||
if self.base.flags.impacted_by_floats() {
|
||||
self.base.thread_id = parent_thread_id;
|
||||
if self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
|
||||
self.assign_block_size(layout_context);
|
||||
// Don't remove the restyle damage; `assign_block_size` decides whether that is
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
use block::BlockFlow;
|
||||
use canvas::canvas_paint_task::CanvasMsg::SendPixelContents;
|
||||
use context::LayoutContext;
|
||||
use flow::{self, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER};
|
||||
use flow::{self, BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER};
|
||||
use fragment::{CoordinateSystem, Fragment, IframeFragmentInfo, ImageFragmentInfo};
|
||||
use fragment::{ScannedTextFragmentInfo, SpecificFragmentInfo};
|
||||
use inline::InlineFlow;
|
||||
|
@ -29,10 +29,9 @@ use gfx::display_list::{BorderRadii, BoxShadowDisplayItem, ClippingRegion};
|
|||
use gfx::display_list::{DisplayItem, DisplayList, DisplayItemMetadata};
|
||||
use gfx::display_list::{GradientDisplayItem};
|
||||
use gfx::display_list::{GradientStop, ImageDisplayItem, LineDisplayItem};
|
||||
use gfx::display_list::TextOrientation;
|
||||
use gfx::display_list::{SolidColorDisplayItem};
|
||||
use gfx::display_list::{StackingContext, TextDisplayItem};
|
||||
use gfx::paint_task::PaintLayer;
|
||||
use gfx::display_list::{OpaqueNode, SolidColorDisplayItem};
|
||||
use gfx::display_list::{StackingContext, TextDisplayItem, TextOrientation};
|
||||
use gfx::paint_task::{PaintLayer, THREAD_TINT_COLORS};
|
||||
use png;
|
||||
use png::PixelsByColorType;
|
||||
use msg::compositor_msg::ScrollPolicy;
|
||||
|
@ -720,7 +719,8 @@ impl FragmentDisplayListBuilding for Fragment {
|
|||
relative_containing_block_size,
|
||||
CoordinateSystem::Self);
|
||||
|
||||
debug!("Fragment::build_display_list at rel={:?}, abs={:?}, dirty={:?}, flow origin={:?}: {:?}",
|
||||
debug!("Fragment::build_display_list at rel={:?}, abs={:?}, dirty={:?}, flow origin={:?}: \
|
||||
{:?}",
|
||||
self.border_box,
|
||||
stacking_relative_border_box,
|
||||
layout_context.shared.dirty,
|
||||
|
@ -1118,6 +1118,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
for kid in self.base.children.iter_mut() {
|
||||
flow::mut_base(kid).display_list_building_result.add_to(display_list);
|
||||
}
|
||||
|
||||
self.base.build_display_items_for_debugging_tint(display_list, self.fragment.node);
|
||||
}
|
||||
|
||||
fn build_display_list_for_static_block(&mut self,
|
||||
|
@ -1192,13 +1194,13 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
|
|||
if self.base.flags.is_float() {
|
||||
// TODO(#2009, pcwalton): This is a pseudo-stacking context. We need to merge `z-index:
|
||||
// auto` kids into the parent stacking context, when that is supported.
|
||||
self.build_display_list_for_floating_block(display_list, layout_context)
|
||||
self.build_display_list_for_floating_block(display_list, layout_context);
|
||||
} else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||
self.build_display_list_for_absolutely_positioned_block(display_list, layout_context)
|
||||
self.build_display_list_for_absolutely_positioned_block(display_list, layout_context);
|
||||
} else {
|
||||
self.build_display_list_for_static_block(display_list,
|
||||
layout_context,
|
||||
BackgroundAndBorderLevel::Block)
|
||||
BackgroundAndBorderLevel::Block);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1246,6 +1248,7 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
debug!("Flow: building display list for {} inline fragments", self.fragments.len());
|
||||
|
||||
let mut display_list = box DisplayList::new();
|
||||
|
||||
for fragment in self.fragments.fragments.iter_mut() {
|
||||
fragment.build_display_list(&mut *display_list,
|
||||
layout_context,
|
||||
|
@ -1270,6 +1273,11 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
|
|||
}
|
||||
}
|
||||
|
||||
if !self.fragments.fragments.is_empty() {
|
||||
self.base.build_display_items_for_debugging_tint(&mut *display_list,
|
||||
self.fragments.fragments[0].node);
|
||||
}
|
||||
|
||||
self.base.display_list_building_result = DisplayListBuildingResult::Normal(display_list);
|
||||
|
||||
if opts::get().validate_display_list_geometry {
|
||||
|
@ -1306,6 +1314,43 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
|
|||
}
|
||||
}
|
||||
|
||||
trait BaseFlowDisplayListBuilding {
|
||||
fn build_display_items_for_debugging_tint(&self,
|
||||
display_list: &mut DisplayList,
|
||||
node: OpaqueNode);
|
||||
}
|
||||
|
||||
impl BaseFlowDisplayListBuilding for BaseFlow {
|
||||
fn build_display_items_for_debugging_tint(&self,
|
||||
display_list: &mut DisplayList,
|
||||
node: OpaqueNode) {
|
||||
if !opts::get().show_debug_parallel_layout {
|
||||
return
|
||||
}
|
||||
|
||||
let thread_id = self.thread_id;
|
||||
let stacking_context_relative_bounds =
|
||||
Rect(self.stacking_relative_position,
|
||||
self.position.size.to_physical(self.writing_mode));
|
||||
|
||||
let mut color = THREAD_TINT_COLORS[thread_id as usize % THREAD_TINT_COLORS.len()];
|
||||
color.a = 1.0;
|
||||
display_list.push(DisplayItem::BorderClass(box BorderDisplayItem {
|
||||
base: BaseDisplayItem::new(stacking_context_relative_bounds.inflate(Au::from_px(2),
|
||||
Au::from_px(2)),
|
||||
DisplayItemMetadata {
|
||||
node: node,
|
||||
pointing: None,
|
||||
},
|
||||
self.clip.clone()),
|
||||
border_widths: SideOffsets2D::new_all_same(Au::from_px(2)),
|
||||
color: SideOffsets2D::new_all_same(color),
|
||||
style: SideOffsets2D::new_all_same(border_style::T::solid),
|
||||
radius: BorderRadii::all_same(Au(0)),
|
||||
}), StackingLevel::Content);
|
||||
}
|
||||
}
|
||||
|
||||
// A helper data structure for gradients.
|
||||
#[derive(Copy)]
|
||||
struct StopRun {
|
||||
|
|
|
@ -202,11 +202,17 @@ pub trait Flow: fmt::Debug + Sync {
|
|||
/// 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.
|
||||
///
|
||||
/// `parent_thread_id` is the thread ID of the parent. This is used for the layout tinting
|
||||
/// debug mode; if the block size of this flow was determined by its parent, we should treat
|
||||
/// it as laid out by its parent.
|
||||
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
|
||||
layout_context: &'a LayoutContext<'a>)
|
||||
layout_context: &'a LayoutContext<'a>,
|
||||
parent_thread_id: u8)
|
||||
-> bool {
|
||||
let impacted = base(self).flags.impacted_by_floats();
|
||||
if impacted {
|
||||
mut_base(self).thread_id = parent_thread_id;
|
||||
self.assign_block_size(layout_context);
|
||||
mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
||||
}
|
||||
|
@ -777,6 +783,9 @@ pub struct BaseFlow {
|
|||
/// The writing mode for this flow.
|
||||
pub writing_mode: WritingMode,
|
||||
|
||||
/// For debugging and profiling, the identifier of the thread that laid out this fragment.
|
||||
pub thread_id: u8,
|
||||
|
||||
/// Various flags for flows, tightly packed to save space.
|
||||
pub flags: FlowFlags,
|
||||
}
|
||||
|
@ -918,6 +927,7 @@ impl BaseFlow {
|
|||
clip: ClippingRegion::max(),
|
||||
flags: flags,
|
||||
writing_mode: writing_mode,
|
||||
thread_id: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,12 +109,11 @@ pub struct Fragment {
|
|||
/// that are part of an inline formatting context.
|
||||
pub inline_context: Option<InlineFragmentContext>,
|
||||
|
||||
/// A debug ID that is consistent for the life of
|
||||
/// this fragment (via transform etc).
|
||||
pub debug_id: u16,
|
||||
|
||||
/// How damaged this fragment is since last reflow.
|
||||
pub restyle_damage: RestyleDamage,
|
||||
|
||||
/// A debug ID that is consistent for the life of this fragment (via transform etc).
|
||||
pub debug_id: u16,
|
||||
}
|
||||
|
||||
unsafe impl Send for Fragment {}
|
||||
|
@ -1667,14 +1666,23 @@ impl Fragment {
|
|||
/// content per CSS 2.1 § 10.3.2.
|
||||
pub fn assign_replaced_inline_size_if_necessary<'a>(&'a mut self, container_inline_size: Au) {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
|
||||
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => return,
|
||||
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
|
||||
SpecificFragmentInfo::Generic |
|
||||
SpecificFragmentInfo::Table |
|
||||
SpecificFragmentInfo::TableCell |
|
||||
SpecificFragmentInfo::TableRow |
|
||||
SpecificFragmentInfo::TableWrapper => return,
|
||||
SpecificFragmentInfo::TableColumn(_) => {
|
||||
panic!("Table column fragments do not have inline_size")
|
||||
}
|
||||
SpecificFragmentInfo::UnscannedText(_) => {
|
||||
panic!("Unscanned text fragments should have been scanned by now!")
|
||||
}
|
||||
SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::InlineBlock(_) |
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) | SpecificFragmentInfo::Iframe(_) => {}
|
||||
SpecificFragmentInfo::Canvas(_) |
|
||||
SpecificFragmentInfo::Image(_) |
|
||||
SpecificFragmentInfo::ScannedText(_) |
|
||||
SpecificFragmentInfo::InlineBlock(_) |
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||
SpecificFragmentInfo::Iframe(_) => {}
|
||||
};
|
||||
|
||||
let style = self.style().clone();
|
||||
|
@ -1703,22 +1711,24 @@ impl Fragment {
|
|||
SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
|
||||
let fragment_inline_size = image_fragment_info.image_inline_size();
|
||||
let fragment_block_size = image_fragment_info.image_block_size();
|
||||
self.border_box.size.inline = image_fragment_info.replaced_image_fragment_info.
|
||||
calculate_replaced_inline_size(style,
|
||||
noncontent_inline_size,
|
||||
container_inline_size,
|
||||
fragment_inline_size,
|
||||
fragment_block_size);
|
||||
self.border_box.size.inline =
|
||||
image_fragment_info.replaced_image_fragment_info
|
||||
.calculate_replaced_inline_size(style,
|
||||
noncontent_inline_size,
|
||||
container_inline_size,
|
||||
fragment_inline_size,
|
||||
fragment_block_size);
|
||||
}
|
||||
SpecificFragmentInfo::Canvas(ref mut canvas_fragment_info) => {
|
||||
let fragment_inline_size = canvas_fragment_info.canvas_inline_size();
|
||||
let fragment_block_size = canvas_fragment_info.canvas_block_size();
|
||||
self.border_box.size.inline = canvas_fragment_info.replaced_image_fragment_info.
|
||||
calculate_replaced_inline_size(style,
|
||||
noncontent_inline_size,
|
||||
container_inline_size,
|
||||
fragment_inline_size,
|
||||
fragment_block_size);
|
||||
self.border_box.size.inline =
|
||||
canvas_fragment_info.replaced_image_fragment_info
|
||||
.calculate_replaced_inline_size(style,
|
||||
noncontent_inline_size,
|
||||
container_inline_size,
|
||||
fragment_inline_size,
|
||||
fragment_block_size);
|
||||
}
|
||||
SpecificFragmentInfo::Iframe(_) => {
|
||||
self.border_box.size.inline = IframeFragmentInfo::calculate_replaced_inline_size(
|
||||
|
@ -1735,14 +1745,23 @@ impl Fragment {
|
|||
/// Ideally, this should follow CSS 2.1 § 10.6.2.
|
||||
pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Au) {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
|
||||
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => return,
|
||||
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have block_size"),
|
||||
SpecificFragmentInfo::Generic |
|
||||
SpecificFragmentInfo::Table |
|
||||
SpecificFragmentInfo::TableCell |
|
||||
SpecificFragmentInfo::TableRow |
|
||||
SpecificFragmentInfo::TableWrapper => return,
|
||||
SpecificFragmentInfo::TableColumn(_) => {
|
||||
panic!("Table column fragments do not have block_size")
|
||||
}
|
||||
SpecificFragmentInfo::UnscannedText(_) => {
|
||||
panic!("Unscanned text fragments should have been scanned by now!")
|
||||
}
|
||||
SpecificFragmentInfo::Canvas(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::InlineBlock(_) |
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) | SpecificFragmentInfo::Iframe(_) => {}
|
||||
SpecificFragmentInfo::Canvas(_) |
|
||||
SpecificFragmentInfo::Image(_) |
|
||||
SpecificFragmentInfo::ScannedText(_) |
|
||||
SpecificFragmentInfo::InlineBlock(_) |
|
||||
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
|
||||
SpecificFragmentInfo::Iframe(_) => {}
|
||||
}
|
||||
|
||||
let style = self.style().clone();
|
||||
|
@ -1752,22 +1771,24 @@ impl Fragment {
|
|||
SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
|
||||
let fragment_inline_size = image_fragment_info.image_inline_size();
|
||||
let fragment_block_size = image_fragment_info.image_block_size();
|
||||
self.border_box.size.block = image_fragment_info.replaced_image_fragment_info.
|
||||
calculate_replaced_block_size(style,
|
||||
noncontent_block_size,
|
||||
containing_block_block_size,
|
||||
fragment_inline_size,
|
||||
fragment_block_size);
|
||||
self.border_box.size.block =
|
||||
image_fragment_info.replaced_image_fragment_info.
|
||||
calculate_replaced_block_size(style,
|
||||
noncontent_block_size,
|
||||
containing_block_block_size,
|
||||
fragment_inline_size,
|
||||
fragment_block_size);
|
||||
}
|
||||
SpecificFragmentInfo::Canvas(ref mut canvas_fragment_info) => {
|
||||
let fragment_inline_size = canvas_fragment_info.canvas_inline_size();
|
||||
let fragment_block_size = canvas_fragment_info.canvas_block_size();
|
||||
self.border_box.size.block = canvas_fragment_info.replaced_image_fragment_info.
|
||||
calculate_replaced_block_size(style,
|
||||
noncontent_block_size,
|
||||
containing_block_block_size,
|
||||
fragment_inline_size,
|
||||
fragment_block_size);
|
||||
self.border_box.size.block =
|
||||
canvas_fragment_info.replaced_image_fragment_info
|
||||
.calculate_replaced_block_size(style,
|
||||
noncontent_block_size,
|
||||
containing_block_block_size,
|
||||
fragment_inline_size,
|
||||
fragment_block_size);
|
||||
}
|
||||
SpecificFragmentInfo::ScannedText(ref info) => {
|
||||
// Scanned text fragments' content block-sizes are calculated by the text run
|
||||
|
@ -1794,14 +1815,16 @@ impl Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
/// Calculates block-size above baseline, depth below baseline, and ascent for this fragment when
|
||||
/// used in an inline formatting context. See CSS 2.1 § 10.8.1.
|
||||
/// Calculates block-size above baseline, depth below baseline, and ascent for this fragment
|
||||
/// when used in an inline formatting context. See CSS 2.1 § 10.8.1.
|
||||
pub fn inline_metrics(&self, layout_context: &LayoutContext) -> InlineMetrics {
|
||||
match self.specific {
|
||||
SpecificFragmentInfo::Image(ref image_fragment_info) => {
|
||||
let computed_block_size = image_fragment_info.replaced_image_fragment_info.computed_block_size();
|
||||
let computed_block_size = image_fragment_info.replaced_image_fragment_info
|
||||
.computed_block_size();
|
||||
InlineMetrics {
|
||||
block_size_above_baseline: computed_block_size + self.border_padding.block_start_end(),
|
||||
block_size_above_baseline: computed_block_size +
|
||||
self.border_padding.block_start_end(),
|
||||
depth_below_baseline: Au(0),
|
||||
ascent: computed_block_size + self.border_padding.block_end,
|
||||
}
|
||||
|
|
|
@ -1301,12 +1301,13 @@ impl Flow for InlineFlow {
|
|||
} // End of `lines.iter_mut()` loop.
|
||||
|
||||
// Assign block sizes for any inline-block descendants.
|
||||
let thread_id = self.base.thread_id;
|
||||
for kid in self.base.child_iter() {
|
||||
if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) ||
|
||||
flow::base(kid).flags.is_float() {
|
||||
continue
|
||||
}
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context, thread_id);
|
||||
}
|
||||
|
||||
self.base.position.size.block = match self.lines.as_slice().last() {
|
||||
|
|
|
@ -79,6 +79,9 @@ impl DomParallelInfo {
|
|||
}
|
||||
}
|
||||
|
||||
pub type FlowTraversalFunction =
|
||||
extern "Rust" fn(UnsafeFlow, &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>);
|
||||
|
||||
/// A parallel top-down DOM traversal.
|
||||
pub trait ParallelPreorderDomTraversal : PreorderDomTraversal {
|
||||
fn run_parallel(&self,
|
||||
|
@ -89,12 +92,8 @@ pub trait ParallelPreorderDomTraversal : PreorderDomTraversal {
|
|||
fn run_parallel_helper(&self,
|
||||
unsafe_node: UnsafeLayoutNode,
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNode>,
|
||||
top_down_func: extern "Rust" fn(UnsafeFlow,
|
||||
&mut WorkerProxy<SharedLayoutContextWrapper,
|
||||
UnsafeLayoutNode>),
|
||||
bottom_up_func: extern "Rust" fn(UnsafeFlow,
|
||||
&mut WorkerProxy<SharedLayoutContextWrapper,
|
||||
UnsafeFlow>)) {
|
||||
top_down_func: FlowTraversalFunction,
|
||||
bottom_up_func: FlowTraversalFunction) {
|
||||
// Get a real layout node.
|
||||
let node: LayoutNode = unsafe {
|
||||
layout_node_from_unsafe_layout_node(&unsafe_node)
|
||||
|
@ -156,11 +155,10 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal {
|
|||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
||||
let layout_context = LayoutContext::new(shared_layout_context);
|
||||
|
||||
let parent =
|
||||
match node.layout_parent_node(layout_context.shared) {
|
||||
None => break,
|
||||
Some(parent) => parent,
|
||||
};
|
||||
let parent = match node.layout_parent_node(layout_context.shared) {
|
||||
None => break,
|
||||
Some(parent) => parent,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let parent_layout_data =
|
||||
|
@ -265,21 +263,23 @@ trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
|
|||
unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>);
|
||||
|
||||
fn should_record_thread_ids(&self) -> bool;
|
||||
|
||||
#[inline(always)]
|
||||
fn run_parallel_helper(&self,
|
||||
unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlow>,
|
||||
top_down_func: extern "Rust" fn(UnsafeFlow,
|
||||
&mut WorkerProxy<SharedLayoutContextWrapper,
|
||||
UnsafeFlow>),
|
||||
bottom_up_func: extern "Rust" fn(UnsafeFlow,
|
||||
&mut WorkerProxy<SharedLayoutContextWrapper,
|
||||
UnsafeFlow>)) {
|
||||
top_down_func: FlowTraversalFunction,
|
||||
bottom_up_func: FlowTraversalFunction) {
|
||||
let mut had_children = false;
|
||||
unsafe {
|
||||
// Get a real flow.
|
||||
let flow: &mut FlowRef = mem::transmute(&unsafe_flow);
|
||||
|
||||
if self.should_record_thread_ids() {
|
||||
flow::mut_base(&mut **flow).thread_id = proxy.worker_index();
|
||||
}
|
||||
|
||||
if self.should_process(&mut **flow) {
|
||||
// Perform the appropriate traversal.
|
||||
self.process(&mut **flow);
|
||||
|
@ -293,7 +293,6 @@ trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
|
|||
data: borrowed_flow_to_unsafe_flow(kid),
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If there were no more children, start assigning block-sizes.
|
||||
|
@ -314,6 +313,10 @@ impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> {
|
|||
assign_inline_sizes,
|
||||
assign_block_sizes_and_store_overflow)
|
||||
}
|
||||
|
||||
fn should_record_thread_ids(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ParallelPostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {}
|
||||
|
@ -327,6 +330,10 @@ impl<'a> ParallelPreorderFlowTraversal for ComputeAbsolutePositions<'a> {
|
|||
compute_absolute_positions,
|
||||
build_display_list)
|
||||
}
|
||||
|
||||
fn should_record_thread_ids(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ParallelPostorderFlowTraversal for BuildDisplayList<'a> {}
|
||||
|
|
|
@ -94,10 +94,11 @@ impl TableRowFlow {
|
|||
// Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of all
|
||||
// cells).
|
||||
let mut max_y = Au(0);
|
||||
let thread_id = self.block_flow.base.thread_id;
|
||||
for kid in self.block_flow.base.child_iter() {
|
||||
kid.place_float_if_applicable(layout_context);
|
||||
if !flow::base(kid).flags.is_float() {
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context, thread_id);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
@ -342,7 +342,8 @@ impl Flow for TableWrapperFlow {
|
|||
}
|
||||
|
||||
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
|
||||
layout_context: &'a LayoutContext<'a>)
|
||||
layout_context: &'a LayoutContext<'a>,
|
||||
parent_thread_id: u8)
|
||||
-> bool {
|
||||
if self.block_flow.base.flags.is_float() {
|
||||
self.block_flow.place_float();
|
||||
|
@ -351,6 +352,7 @@ impl Flow for TableWrapperFlow {
|
|||
|
||||
let impacted = self.block_flow.base.flags.impacted_by_floats();
|
||||
if impacted {
|
||||
self.block_flow.base.thread_id = parent_thread_id;
|
||||
self.assign_block_size(layout_context);
|
||||
}
|
||||
impacted
|
||||
|
|
|
@ -9,7 +9,7 @@ use incremental::RestyleDamage;
|
|||
use parallel::DomParallelInfo;
|
||||
use wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
|
||||
|
||||
use azure::azure_hl::{Color};
|
||||
use azure::azure_hl::Color;
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use gfx;
|
||||
use libc::{c_void, uintptr_t};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue