Skip to content

Commit

Permalink
auto merge of #4994 : pcwalton/servo/layout-tinting, r=pcwalton
Browse files Browse the repository at this point in the history
  • Loading branch information
bors-servo committed Feb 21, 2015
2 parents d326e75 + 40a3b41 commit d26345f
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 88 deletions.
12 changes: 12 additions & 0 deletions components/gfx/display_list/mod.rs
Expand Up @@ -766,6 +766,18 @@ impl<T> BorderRadii<T> where T: PartialEq + Zero {
}
}

impl<T> BorderRadii<T> where T: PartialEq + Zero + Clone {
/// Returns a set of border radii that all have the given value.
pub fn all_same(value: T) -> BorderRadii<T> {
BorderRadii {
top_left: value.clone(),
top_right: value.clone(),
bottom_right: value.clone(),
bottom_left: value.clone(),
}
}
}

/// Paints a line segment.
#[derive(Clone)]
pub struct LineDisplayItem {
Expand Down
23 changes: 14 additions & 9 deletions components/gfx/paint_task.rs
Expand Up @@ -571,18 +571,11 @@ impl WorkerThread {
if opts::get().show_debug_parallel_paint {
// Overlay a transparent solid color to identify the thread that
// painted this tile.
let colors = [Color { r: 6.0/255.0, g: 153.0/255.0, b: 198.0/255.0, a: 0.7 },
Color { r: 255.0/255.0, g: 212.0/255.0, b: 83.0/255.0, a: 0.7 },
Color { r: 116.0/255.0, g: 29.0/255.0, b: 109.0/255.0, a: 0.7 },
Color { r: 204.0/255.0, g: 158.0/255.0, b: 199.0/255.0, a: 0.7 },
Color { r: 242.0/255.0, g: 46.0/255.0, b: 121.0/255.0, a: 0.7 },
Color { r: 116.0/255.0, g: 203.0/255.0, b: 196.0/255.0, a: 0.7 },
Color { r: 255.0/255.0, g: 249.0/255.0, b: 201.0/255.0, a: 0.7 },
Color { r: 137.0/255.0, g: 196.0/255.0, b: 78.0/255.0, a: 0.7 }];
let color = THREAD_TINT_COLORS[thread_id % THREAD_TINT_COLORS.len()];
paint_context.draw_solid_color(&Rect(Point2D(Au(0), Au(0)),
Size2D(Au::from_px(size.width as isize),
Au::from_px(size.height as isize))),
colors[thread_id % colors.len()]);
color);
}
}

Expand Down Expand Up @@ -639,3 +632,15 @@ enum MsgToWorkerThread {
enum MsgFromWorkerThread {
PaintedTile(Box<LayerBuffer>),
}

pub static THREAD_TINT_COLORS: [Color; 8] = [
Color { r: 6.0/255.0, g: 153.0/255.0, b: 198.0/255.0, a: 0.7 },
Color { r: 255.0/255.0, g: 212.0/255.0, b: 83.0/255.0, a: 0.7 },
Color { r: 116.0/255.0, g: 29.0/255.0, b: 109.0/255.0, a: 0.7 },
Color { r: 204.0/255.0, g: 158.0/255.0, b: 199.0/255.0, a: 0.7 },
Color { r: 242.0/255.0, g: 46.0/255.0, b: 121.0/255.0, a: 0.7 },
Color { r: 116.0/255.0, g: 203.0/255.0, b: 196.0/255.0, a: 0.7 },
Color { r: 255.0/255.0, g: 249.0/255.0, b: 201.0/255.0, a: 0.7 },
Color { r: 137.0/255.0, g: 196.0/255.0, b: 78.0/255.0, a: 0.7 },
];

14 changes: 10 additions & 4 deletions components/layout/block.rs
Expand Up @@ -863,14 +863,16 @@ 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
// after the block-end border edge of the previous flow.
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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
63 changes: 54 additions & 9 deletions components/layout/display_list_builder.rs
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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,
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
12 changes: 11 additions & 1 deletion components/layout/flow.rs
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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,
}
Expand Down Expand Up @@ -918,6 +927,7 @@ impl BaseFlow {
clip: ClippingRegion::max(),
flags: flags,
writing_mode: writing_mode,
thread_id: 0,
}
}

Expand Down

0 comments on commit d26345f

Please sign in to comment.