diff --git a/components/layout/block.rs b/components/layout/block.rs index 1c7925feb0e..5777014c578 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -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) { diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 36b8da6cc48..c8703272fd6 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -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. diff --git a/components/layout/inline.rs b/components/layout/inline.rs index d1d50b22fe4..ec1d223cd36 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -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) {} diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 2479731c69f..d59774c46d5 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -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 { - 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); diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 8425ff52b78..e41d0cd8925 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -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), diff --git a/components/script_layout_interface/restyle_damage.rs b/components/script_layout_interface/restyle_damage.rs index ef33370e064..ff0e26af03f 100644 --- a/components/script_layout_interface/restyle_damage.rs +++ b/components/script_layout_interface/restyle_damage.rs @@ -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