mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
layout: Add a REPOSITION
restyle damage type.
Separating out `REPOSITION` from `REPAINT` allows us to compute stacking-context-relative positions without rebuilding the display list. This saves a lot of time when responding to script-to-layout queries.
This commit is contained in:
parent
1235f4bff6
commit
65e3db1c0d
6 changed files with 52 additions and 35 deletions
|
@ -51,6 +51,7 @@ use model::{self, IntrinsicISizes, MarginCollapseInfo};
|
|||
use model::{CollapsibleMargins, MaybeAuto, specified, specified_or_none};
|
||||
use rustc_serialize::{Encodable, Encoder};
|
||||
use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW};
|
||||
use script_layout_interface::restyle_damage::REPOSITION;
|
||||
use std::cmp::{max, min};
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
|
@ -2114,6 +2115,8 @@ impl Flow for BlockFlow {
|
|||
flow::mut_base(kid).stacking_relative_position_of_display_port =
|
||||
stacking_relative_position_of_display_port_for_children;
|
||||
}
|
||||
|
||||
self.base.restyle_damage.remove(REPOSITION)
|
||||
}
|
||||
|
||||
fn mark_as_root(&mut self) {
|
||||
|
|
|
@ -42,7 +42,8 @@ use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
|
|||
use multicol::MulticolFlow;
|
||||
use parallel::FlowParallelInfo;
|
||||
use rustc_serialize::{Encodable, Encoder};
|
||||
use script_layout_interface::restyle_damage::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
|
||||
use script_layout_interface::restyle_damage::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW};
|
||||
use script_layout_interface::restyle_damage::{REPAINT, REPOSITION, RestyleDamage};
|
||||
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutNode};
|
||||
use std::{fmt, mem, raw};
|
||||
use std::iter::Zip;
|
||||
|
@ -320,6 +321,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
|
|||
/// Phase 4 of reflow: computes absolute positions.
|
||||
fn compute_absolute_position(&mut self, _: &SharedLayoutContext) {
|
||||
// The default implementation is a no-op.
|
||||
mut_base(self).restyle_damage.remove(REPOSITION)
|
||||
}
|
||||
|
||||
/// Phase 5 of reflow: builds display lists.
|
||||
|
|
|
@ -25,8 +25,8 @@ use gfx_traits::print_tree::PrintTree;
|
|||
use layout_debug;
|
||||
use model::IntrinsicISizesContribution;
|
||||
use range::{Range, RangeIndex};
|
||||
use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW};
|
||||
use script_layout_interface::restyle_damage::{REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT};
|
||||
use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW};
|
||||
use script_layout_interface::restyle_damage::{REPOSITION, RESOLVE_GENERATED_CONTENT};
|
||||
use script_layout_interface::wrapper_traits::PseudoElementType;
|
||||
use std::{fmt, i32, isize, mem};
|
||||
use std::cmp::max;
|
||||
|
@ -1650,6 +1650,8 @@ impl Flow for InlineFlow {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
self.base.restyle_damage.remove(REPOSITION)
|
||||
}
|
||||
|
||||
fn update_late_computed_inline_position_if_necessary(&mut self, _: Au) {}
|
||||
|
|
|
@ -17,7 +17,7 @@ use generated_content::ResolveGeneratedContent;
|
|||
use gfx::display_list::{DisplayItem, StackingContext};
|
||||
use script_layout_interface::restyle_damage::{REFLOW, STORE_OVERFLOW};
|
||||
use style::context::StyleContext;
|
||||
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList, ComputeAbsolutePositions};
|
||||
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
|
||||
use util::opts;
|
||||
|
||||
pub use style::sequential::traverse_dom;
|
||||
|
@ -78,7 +78,6 @@ pub fn build_display_list_for_subtree(flow_root: &mut Flow,
|
|||
root_stacking_context: &mut StackingContext,
|
||||
shared_layout_context: &SharedLayoutContext)
|
||||
-> Vec<DisplayItem> {
|
||||
flow_root.traverse_preorder(&ComputeAbsolutePositions { layout_context: shared_layout_context });
|
||||
let mut children = vec![];
|
||||
flow_root.collect_stacking_contexts(root_stacking_context.id,
|
||||
&mut children);
|
||||
|
|
|
@ -75,7 +75,7 @@ use layout::query::{process_margin_style_query, process_node_overflow_request, p
|
|||
use layout::query::{process_node_geometry_request, process_node_layer_id_request, process_node_scroll_area_request};
|
||||
use layout::query::process_offset_parent_query;
|
||||
use layout::sequential;
|
||||
use layout::traversal::RecalcStyleAndConstructFlows;
|
||||
use layout::traversal::{ComputeAbsolutePositions, RecalcStyleAndConstructFlows};
|
||||
use layout::webrender_helpers::{WebRenderDisplayListConverter, WebRenderFrameBuilder};
|
||||
use layout::wrapper::{LayoutNodeLayoutData, NonOpaqueStyleAndLayoutData};
|
||||
use layout_traits::LayoutThreadFactory;
|
||||
|
@ -89,7 +89,8 @@ use script::layout_wrapper::{ServoLayoutDocument, ServoLayoutNode};
|
|||
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData};
|
||||
use script_layout_interface::message::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow};
|
||||
use script_layout_interface::reporter::CSSErrorReporter;
|
||||
use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, STORE_OVERFLOW};
|
||||
use script_layout_interface::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION};
|
||||
use script_layout_interface::restyle_damage::STORE_OVERFLOW;
|
||||
use script_layout_interface::rpc::{LayoutRPC, MarginStyleResponse, NodeOverflowResponse, OffsetParentResponse};
|
||||
use script_layout_interface::wrapper_traits::LayoutNode;
|
||||
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
|
||||
|
@ -919,6 +920,12 @@ impl LayoutThread {
|
|||
flow::mut_base(layout_root).clip =
|
||||
ClippingRegion::from_rect(&data.page_clip_rect);
|
||||
|
||||
if flow::base(layout_root).restyle_damage.contains(REPOSITION) {
|
||||
layout_root.traverse_preorder(&ComputeAbsolutePositions {
|
||||
layout_context: shared_layout_context
|
||||
});
|
||||
}
|
||||
|
||||
if flow::base(layout_root).restyle_damage.contains(REPAINT) ||
|
||||
rw_data.display_list.is_none() {
|
||||
let mut root_stacking_context = StackingContext::new(StackingContextId::new(0),
|
||||
|
|
|
@ -15,31 +15,36 @@ bitflags! {
|
|||
#[doc = "Currently unused; need to decide how this propagates."]
|
||||
const REPAINT = 0x01,
|
||||
|
||||
#[doc = "The stacking-context-relative position of this node or its descendants has \
|
||||
changed."]
|
||||
#[doc = "Propagates both up and down the flow tree."]
|
||||
const REPOSITION = 0x02,
|
||||
|
||||
#[doc = "Recompute the overflow regions (bounding box of object and all descendants)."]
|
||||
#[doc = "Propagates down the flow tree because the computation is bottom-up."]
|
||||
const STORE_OVERFLOW = 0x02,
|
||||
const STORE_OVERFLOW = 0x04,
|
||||
|
||||
#[doc = "Recompute intrinsic inline_sizes (minimum and preferred)."]
|
||||
#[doc = "Propagates down the flow tree because the computation is"]
|
||||
#[doc = "bottom-up."]
|
||||
const BUBBLE_ISIZES = 0x04,
|
||||
const BUBBLE_ISIZES = 0x08,
|
||||
|
||||
#[doc = "Recompute actual inline-sizes and block-sizes, only taking out-of-flow children \
|
||||
into account. \
|
||||
Propagates up the flow tree because the computation is top-down."]
|
||||
const REFLOW_OUT_OF_FLOW = 0x08,
|
||||
const REFLOW_OUT_OF_FLOW = 0x10,
|
||||
|
||||
#[doc = "Recompute actual inline_sizes and block_sizes."]
|
||||
#[doc = "Propagates up the flow tree because the computation is"]
|
||||
#[doc = "top-down."]
|
||||
const REFLOW = 0x10,
|
||||
const REFLOW = 0x20,
|
||||
|
||||
#[doc = "Re-resolve generated content. \
|
||||
Propagates up the flow tree because the computation is inorder."]
|
||||
const RESOLVE_GENERATED_CONTENT = 0x20,
|
||||
const RESOLVE_GENERATED_CONTENT = 0x40,
|
||||
|
||||
#[doc = "The entire flow needs to be reconstructed."]
|
||||
const RECONSTRUCT_FLOW = 0x40
|
||||
const RECONSTRUCT_FLOW = 0x80
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +68,8 @@ impl TRestyleDamage for RestyleDamage {
|
|||
/// `RestyleDamage::all()` will result in unnecessary sequential resolution
|
||||
/// of generated content.
|
||||
fn rebuild_and_reflow() -> RestyleDamage {
|
||||
REPAINT | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW
|
||||
REPAINT | REPOSITION | STORE_OVERFLOW | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW |
|
||||
RECONSTRUCT_FLOW
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,9 +78,10 @@ impl RestyleDamage {
|
|||
/// returns the damage that we should add to the *parent* of this flow.
|
||||
pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> RestyleDamage {
|
||||
if child_is_absolutely_positioned {
|
||||
self & (REPAINT | STORE_OVERFLOW | REFLOW_OUT_OF_FLOW | RESOLVE_GENERATED_CONTENT)
|
||||
self & (REPAINT | REPOSITION | STORE_OVERFLOW | REFLOW_OUT_OF_FLOW |
|
||||
RESOLVE_GENERATED_CONTENT)
|
||||
} else {
|
||||
self & (REPAINT | STORE_OVERFLOW | REFLOW | REFLOW_OUT_OF_FLOW |
|
||||
self & (REPAINT | REPOSITION | STORE_OVERFLOW | REFLOW | REFLOW_OUT_OF_FLOW |
|
||||
RESOLVE_GENERATED_CONTENT)
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +97,7 @@ impl RestyleDamage {
|
|||
// Absolute children are out-of-flow and therefore insulated from changes.
|
||||
//
|
||||
// FIXME(pcwalton): Au contraire, if the containing block dimensions change!
|
||||
self & REPAINT
|
||||
self & (REPAINT | REPOSITION)
|
||||
}
|
||||
(true, false) => {
|
||||
// Changing the position of an absolutely-positioned block requires us to reflow
|
||||
|
@ -103,7 +110,7 @@ impl RestyleDamage {
|
|||
}
|
||||
_ => {
|
||||
// TODO(pcwalton): Take floatedness into account.
|
||||
self & (REPAINT | REFLOW)
|
||||
self & (REPAINT | REPOSITION | REFLOW)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +122,7 @@ impl fmt::Display for RestyleDamage {
|
|||
|
||||
let to_iter =
|
||||
[ (REPAINT, "Repaint")
|
||||
, (REPOSITION, "Reposition")
|
||||
, (STORE_OVERFLOW, "StoreOverflow")
|
||||
, (BUBBLE_ISIZES, "BubbleISizes")
|
||||
, (REFLOW_OUT_OF_FLOW, "ReflowOutOfFlow")
|
||||
|
@ -163,14 +171,8 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
|||
// FIXME: Test somehow that every property is included.
|
||||
|
||||
add_if_not_equal!(old, new, damage,
|
||||
[
|
||||
REPAINT,
|
||||
STORE_OVERFLOW,
|
||||
BUBBLE_ISIZES,
|
||||
REFLOW_OUT_OF_FLOW,
|
||||
REFLOW,
|
||||
RECONSTRUCT_FLOW
|
||||
], [
|
||||
[REPAINT, REPOSITION, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW,
|
||||
REFLOW, RECONSTRUCT_FLOW], [
|
||||
get_box.float, get_box.display, get_box.position, get_counters.content,
|
||||
get_counters.counter_reset, get_counters.counter_increment,
|
||||
get_inheritedbox._servo_under_display_none,
|
||||
|
@ -191,8 +193,8 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
|||
get_column.column_width, get_column.column_count
|
||||
]) || (new.get_box().display == display::T::inline &&
|
||||
add_if_not_equal!(old, new, damage,
|
||||
[REPAINT, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW, REFLOW,
|
||||
RECONSTRUCT_FLOW], [
|
||||
[REPAINT, REPOSITION, STORE_OVERFLOW, BUBBLE_ISIZES,
|
||||
REFLOW_OUT_OF_FLOW, REFLOW, RECONSTRUCT_FLOW], [
|
||||
// For inline boxes only, border/padding styles are used in flow construction (to decide
|
||||
// whether to create fragments for empty flows).
|
||||
get_border.border_top_width, get_border.border_right_width,
|
||||
|
@ -200,7 +202,8 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
|||
get_padding.padding_top, get_padding.padding_right,
|
||||
get_padding.padding_bottom, get_padding.padding_left
|
||||
])) || add_if_not_equal!(old, new, damage,
|
||||
[ REPAINT, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW, REFLOW ],
|
||||
[REPAINT, REPOSITION, STORE_OVERFLOW, BUBBLE_ISIZES,
|
||||
REFLOW_OUT_OF_FLOW, REFLOW],
|
||||
[get_border.border_top_width, get_border.border_right_width,
|
||||
get_border.border_bottom_width, get_border.border_left_width,
|
||||
get_margin.margin_top, get_margin.margin_right,
|
||||
|
@ -225,11 +228,14 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
|||
get_position.flex_shrink,
|
||||
get_position.align_self
|
||||
]) || add_if_not_equal!(old, new, damage,
|
||||
[ REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW ], [
|
||||
[REPAINT, REPOSITION, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW], [
|
||||
get_position.top, get_position.left,
|
||||
get_position.right, get_position.bottom
|
||||
get_position.right, get_position.bottom,
|
||||
get_effects.opacity,
|
||||
get_effects.transform, get_effects.transform_style, get_effects.transform_origin,
|
||||
get_effects.perspective, get_effects.perspective_origin
|
||||
]) || add_if_not_equal!(old, new, damage,
|
||||
[ REPAINT ], [
|
||||
[REPAINT], [
|
||||
get_color.color, get_background.background_color,
|
||||
get_background.background_image, get_background.background_position,
|
||||
get_background.background_repeat, get_background.background_attachment,
|
||||
|
@ -245,9 +251,7 @@ fn compute_damage(old: &ServoComputedValues, new: &ServoComputedValues) -> Resty
|
|||
get_inheritedtext._servo_text_decorations_in_effect,
|
||||
get_pointing.cursor, get_pointing.pointer_events,
|
||||
get_effects.box_shadow, get_effects.clip, get_inheritedtext.text_shadow, get_effects.filter,
|
||||
get_effects.transform, get_effects.backface_visibility, get_effects.transform_style,
|
||||
get_effects.transform_origin, get_effects.perspective, get_effects.perspective_origin,
|
||||
get_effects.mix_blend_mode, get_effects.opacity, get_inheritedbox.image_rendering,
|
||||
get_effects.mix_blend_mode, get_inheritedbox.image_rendering,
|
||||
|
||||
// Note: May require REFLOW et al. if `visibility: collapse` is implemented.
|
||||
get_inheritedbox.visibility
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue