mirror of
https://github.com/servo/servo.git
synced 2025-06-23 00:24:35 +01:00
Implement basic overflow computation. Closes #1148.
This adds just 4 ms out of ~120 ms on the rainbow page.
This commit is contained in:
parent
cc76a2188e
commit
5327c9c44f
5 changed files with 65 additions and 20 deletions
|
@ -302,6 +302,7 @@ impl FlowContext for FloatFlow {
|
|||
|
||||
position.size.height = height;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn collapse_margins(&mut self,
|
||||
|
|
|
@ -90,12 +90,12 @@ pub trait FlowContext {
|
|||
fail!("assign_widths not yet implemented")
|
||||
}
|
||||
|
||||
/// Pass 3 of reflow: computes height.
|
||||
/// Pass 3a of reflow: computes height.
|
||||
fn assign_height(&mut self, _ctx: &mut LayoutContext) {
|
||||
fail!("assign_height not yet implemented")
|
||||
}
|
||||
|
||||
/// In-order version of pass 3 of reflow: computes heights with floats present.
|
||||
/// In-order version of pass 3a of reflow: computes heights with floats present.
|
||||
fn assign_height_inorder(&mut self, _ctx: &mut LayoutContext) {
|
||||
fail!("assign_height_inorder not yet implemented")
|
||||
}
|
||||
|
@ -190,6 +190,9 @@ pub trait MutableFlowUtils {
|
|||
/// Removes the last child of this flow and destroys it.
|
||||
fn remove_last(self);
|
||||
|
||||
/// Computes the overflow region for this flow.
|
||||
fn store_overflow(self, _: &mut LayoutContext);
|
||||
|
||||
/// Builds a display list for this flow and its children.
|
||||
fn build_display_list<E:ExtraDisplayListData>(
|
||||
self,
|
||||
|
@ -315,7 +318,15 @@ pub struct FlowData {
|
|||
// layout; maybe combine into a single enum to save space.
|
||||
min_width: Au,
|
||||
pref_width: Au,
|
||||
|
||||
/// The position of the upper left corner of the border box of this flow, relative to the
|
||||
/// containing block.
|
||||
position: Rect<Au>,
|
||||
|
||||
/// The amount of overflow of this flow, relative to the containing block. Must include all the
|
||||
/// pixels of all the display list items for correct invalidation.
|
||||
overflow: Rect<Au>,
|
||||
|
||||
floats_in: FloatContext,
|
||||
floats_out: FloatContext,
|
||||
num_floats: uint,
|
||||
|
@ -353,6 +364,7 @@ impl FlowData {
|
|||
min_width: Au::new(0),
|
||||
pref_width: Au::new(0),
|
||||
position: Au::zero_rect(),
|
||||
overflow: Au::zero_rect(),
|
||||
floats_in: Invalid,
|
||||
floats_out: Invalid,
|
||||
num_floats: 0,
|
||||
|
@ -467,6 +479,17 @@ impl<'self> MutableFlowUtils for &'self mut FlowContext {
|
|||
let _ = mut_base(self).children.pop_back();
|
||||
}
|
||||
|
||||
fn store_overflow(self, _: &mut LayoutContext) {
|
||||
let my_position = mut_base(self).position;
|
||||
let mut overflow = my_position;
|
||||
for kid in mut_base(self).child_iter() {
|
||||
let mut kid_overflow = base(*kid).overflow;
|
||||
kid_overflow = kid_overflow.translate(&my_position.origin);
|
||||
overflow = overflow.union(&kid_overflow)
|
||||
}
|
||||
mut_base(self).overflow = overflow
|
||||
}
|
||||
|
||||
fn build_display_list<E:ExtraDisplayListData>(
|
||||
self,
|
||||
builder: &DisplayListBuilder,
|
||||
|
|
|
@ -138,15 +138,16 @@ impl<'self> PreorderFlowTraversal for AssignWidthsTraversal<'self> {
|
|||
}
|
||||
}
|
||||
|
||||
/// The assign-heights traversal, the last (and most expensive) part of layout computation.
|
||||
/// Determines the final heights for all layout objects. In Gecko this corresponds to
|
||||
/// `FinishAndStoreOverflow`.
|
||||
struct AssignHeightsTraversal<'self>(&'self mut LayoutContext);
|
||||
/// The assign-heights-and-store-overflow traversal, the last (and most expensive) part of layout
|
||||
/// computation. Determines the final heights for all layout objects, computes positions, and
|
||||
/// computes overflow regions. In Gecko this corresponds to `FinishAndStoreOverflow`.
|
||||
struct AssignHeightsAndStoreOverflowTraversal<'self>(&'self mut LayoutContext);
|
||||
|
||||
impl<'self> PostorderFlowTraversal for AssignHeightsTraversal<'self> {
|
||||
impl<'self> PostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'self> {
|
||||
#[inline]
|
||||
fn process(&mut self, flow: &mut FlowContext) -> bool {
|
||||
flow.assign_height(**self);
|
||||
flow.store_overflow(**self);
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -296,6 +297,29 @@ impl LayoutTask {
|
|||
self.stylist.add_stylesheet(sheet, AuthorOrigin);
|
||||
}
|
||||
|
||||
/// Performs layout constraint solving.
|
||||
///
|
||||
/// 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,
|
||||
layout_root: &mut FlowContext,
|
||||
layout_context: &mut LayoutContext) {
|
||||
let _ = layout_root.traverse_postorder(&mut BubbleWidthsTraversal(layout_context));
|
||||
|
||||
// FIXME(kmc): We want to do
|
||||
// for flow in layout_root.traverse_preorder_prune(|f|
|
||||
// f.restyle_damage().lacks(Reflow))
|
||||
// but FloatContext values can't be reused, so we need to recompute them every time.
|
||||
// NOTE: this currently computes borders, so any pruning should separate that operation out.
|
||||
let _ = layout_root.traverse_preorder(&mut AssignWidthsTraversal(layout_context));
|
||||
|
||||
// For now, this is an inorder traversal
|
||||
// FIXME: prune this traversal as well
|
||||
let _ = layout_root.traverse_postorder(&mut
|
||||
AssignHeightsAndStoreOverflowTraversal(layout_context));
|
||||
}
|
||||
|
||||
/// The high-level routine that performs layout tasks.
|
||||
fn handle_reflow(&mut self, data: &Reflow) {
|
||||
// FIXME: Isolate this transmutation into a "bridge" module.
|
||||
|
@ -365,17 +389,7 @@ impl LayoutTask {
|
|||
// Perform the primary layout passes over the flow tree to compute the locations of all
|
||||
// the boxes.
|
||||
do profile(time::LayoutMainCategory, self.profiler_chan.clone()) {
|
||||
let _ = layout_root.traverse_postorder(&mut BubbleWidthsTraversal(&mut layout_ctx));
|
||||
|
||||
// FIXME(kmc): We want to do
|
||||
// for flow in layout_root.traverse_preorder_prune(|f| f.restyle_damage().lacks(Reflow))
|
||||
// but FloatContext values can't be reused, so we need to recompute them every time.
|
||||
// NOTE: this currently computes borders, so any pruning should separate that operation out.
|
||||
let _ = layout_root.traverse_preorder(&mut AssignWidthsTraversal(&mut layout_ctx));
|
||||
|
||||
// For now, this is an inorder traversal
|
||||
// FIXME: prune this traversal as well
|
||||
let _ = layout_root.traverse_postorder(&mut AssignHeightsTraversal(&mut layout_ctx));
|
||||
self.solve_constraints(layout_root, &mut layout_ctx)
|
||||
}
|
||||
|
||||
// Build the display list if necessary, and send it to the renderer.
|
||||
|
|
|
@ -8,9 +8,16 @@ use geom::size::Size2D;
|
|||
|
||||
use std::num::{NumCast, One, Zero};
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct Au(i32);
|
||||
|
||||
// We don't use #[deriving] here for inlining.
|
||||
impl Clone for Au {
|
||||
#[inline]
|
||||
fn clone(&self) -> Au {
|
||||
Au(**self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Au {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Au) -> bool {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 82d56dfc632fe458d126d049fd5abe856170f48d
|
||||
Subproject commit 6e4db1ea746f38fe8156bc285c89ad5c12b124a9
|
Loading…
Add table
Add a link
Reference in a new issue