aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout_2020')
-rw-r--r--components/layout_2020/flexbox/layout.rs88
-rw-r--r--components/layout_2020/flexbox/mod.rs25
-rw-r--r--components/layout_2020/flow/inline/mod.rs18
-rw-r--r--components/layout_2020/flow/mod.rs49
-rw-r--r--components/layout_2020/flow/root.rs1
-rw-r--r--components/layout_2020/formatting_contexts.rs101
-rw-r--r--components/layout_2020/fragment_tree/fragment.rs1
-rw-r--r--components/layout_2020/layout_box_base.rs54
-rw-r--r--components/layout_2020/lib.rs2
-rw-r--r--components/layout_2020/positioned.rs5
-rw-r--r--components/layout_2020/table/layout.rs23
-rw-r--r--components/layout_2020/taffy/layout.rs9
12 files changed, 216 insertions, 160 deletions
diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs
index 77076898f57..880847617f6 100644
--- a/components/layout_2020/flexbox/layout.rs
+++ b/components/layout_2020/flexbox/layout.rs
@@ -25,16 +25,13 @@ use style::values::generics::length::LengthPercentageOrNormal;
use style::values::specified::align::AlignFlags;
use super::geom::{FlexAxis, FlexRelativeRect, FlexRelativeSides, FlexRelativeVec2};
-use super::{
- CachedBlockSizeContribution, FlexContainer, FlexContainerConfig, FlexItemBox, FlexLevelBox,
-};
+use super::{FlexContainer, FlexContainerConfig, FlexItemBox, FlexLevelBox};
use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
-use crate::formatting_contexts::{
- Baselines, IndependentFormattingContextContents, IndependentLayout,
-};
+use crate::formatting_contexts::{Baselines, IndependentFormattingContextContents};
use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags};
use crate::geom::{AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, Size, Sizes};
+use crate::layout_box_base::CacheableLayoutResult;
use crate::positioned::{
AbsolutelyPositionedBox, PositioningContext, PositioningContextLength, relative_adjustement,
};
@@ -650,8 +647,10 @@ impl FlexContainer {
layout_context: &LayoutContext,
positioning_context: &mut PositioningContext,
containing_block: &ContainingBlock,
- ) -> IndependentLayout {
- let depends_on_block_constraints = self.config.flex_direction == FlexDirection::Column;
+ depends_on_block_constraints: bool,
+ ) -> CacheableLayoutResult {
+ let depends_on_block_constraints =
+ depends_on_block_constraints || self.config.flex_direction == FlexDirection::Column;
let mut flex_context = FlexContext {
config: self.config.clone(),
@@ -985,13 +984,14 @@ impl FlexContainer {
.or(all_baselines.last),
};
- IndependentLayout {
+ CacheableLayoutResult {
fragments,
content_block_size,
content_inline_size_for_table: None,
baselines,
depends_on_block_constraints,
specific_layout_info: None,
+ collapsible_margins_in_children: CollapsedBlockMargins::zero(),
}
}
@@ -1950,29 +1950,23 @@ impl FlexItem<'_> {
}
}
- let cache = self.box_.block_content_size_cache.borrow_mut().take();
- let layout = if let Some(cache) = cache.filter(|cache| {
- cache.compatible_with_item_as_containing_block(&item_as_containing_block)
- }) {
- positioning_context = cache.positioning_context;
- cache.layout
- } else {
- non_replaced.layout(
- flex_context.layout_context,
- &mut positioning_context,
- &item_as_containing_block,
- containing_block,
- )
- };
- let IndependentLayout {
+ let layout = non_replaced.layout_with_caching(
+ flex_context.layout_context,
+ &mut positioning_context,
+ &item_as_containing_block,
+ containing_block,
+ &independent_formatting_context.base,
+ flex_axis == FlexAxis::Column ||
+ self.stretches_to_line() ||
+ self.depends_on_block_constraints,
+ );
+ let CacheableLayoutResult {
fragments,
content_block_size,
baselines: content_box_baselines,
depends_on_block_constraints,
..
} = layout;
- let depends_on_block_constraints = depends_on_block_constraints ||
- (flex_axis == FlexAxis::Row && self.stretches_to_line());
let has_child_which_depends_on_block_constraints = fragments.iter().any(|fragment| {
fragment.base().is_some_and(|base|
@@ -2693,37 +2687,17 @@ impl FlexItemBox {
},
style,
};
- let content_block_size = || {
- if let Some(cache) = &*self.block_content_size_cache.borrow() {
- if inline_size == cache.containing_block_inline_size {
- return cache.layout.content_block_size;
- } else {
- #[cfg(feature = "tracing")]
- tracing::warn!(
- name: "NonReplaced cache miss",
- cached = ?cache.containing_block_inline_size,
- required = ?inline_size,
- );
- }
- } else {
- #[cfg(feature = "tracing")]
- tracing::warn!(name: "NonReplaced no cache", required = ?inline_size);
- }
-
- let layout = non_replaced.layout(
- flex_context.layout_context,
- &mut positioning_context,
- &item_as_containing_block,
- flex_context.containing_block,
- );
- let content_block_size = layout.content_block_size;
- *self.block_content_size_cache.borrow_mut() =
- Some(CachedBlockSizeContribution {
- containing_block_inline_size: item_as_containing_block.size.inline,
- layout,
- positioning_context,
- });
- content_block_size
+ let mut content_block_size = || {
+ non_replaced
+ .layout_with_caching(
+ flex_context.layout_context,
+ &mut positioning_context,
+ &item_as_containing_block,
+ flex_context.containing_block,
+ &self.independent_formatting_context.base,
+ false, /* depends_on_block_constraints */
+ )
+ .content_block_size
};
match intrinsic_sizing_mode {
IntrinsicSizingMode::Contribution => {
diff --git a/components/layout_2020/flexbox/mod.rs b/components/layout_2020/flexbox/mod.rs
index fbe2786d078..46d7a2387a8 100644
--- a/components/layout_2020/flexbox/mod.rs
+++ b/components/layout_2020/flexbox/mod.rs
@@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-use app_units::Au;
use geom::{FlexAxis, MainStartCrossStart};
use servo_arc::Arc as ServoArc;
use style::logical_geometry::WritingMode;
@@ -13,15 +12,15 @@ use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap;
use style::values::computed::{AlignContent, JustifyContent};
use style::values::specified::align::AlignFlags;
+use crate::PropagatedBoxTreeData;
use crate::cell::ArcRefCell;
use crate::construct_modern::{ModernContainerBuilder, ModernItemKind};
use crate::context::LayoutContext;
use crate::dom::{LayoutBox, NodeExt};
use crate::dom_traversal::{NodeAndStyleInfo, NonReplacedContents};
-use crate::formatting_contexts::{IndependentFormattingContext, IndependentLayout};
+use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragment_tree::BaseFragmentInfo;
-use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
-use crate::{ContainingBlock, PropagatedBoxTreeData};
+use crate::positioned::AbsolutelyPositionedBox;
mod geom;
mod layout;
@@ -146,7 +145,6 @@ pub(crate) enum FlexLevelBox {
pub(crate) struct FlexItemBox {
independent_formatting_context: IndependentFormattingContext,
- block_content_size_cache: ArcRefCell<Option<CachedBlockSizeContribution>>,
}
impl std::fmt::Debug for FlexItemBox {
@@ -159,7 +157,6 @@ impl FlexItemBox {
fn new(independent_formatting_context: IndependentFormattingContext) -> Self {
Self {
independent_formatting_context,
- block_content_size_cache: Default::default(),
}
}
@@ -171,19 +168,3 @@ impl FlexItemBox {
self.independent_formatting_context.base_fragment_info()
}
}
-
-struct CachedBlockSizeContribution {
- containing_block_inline_size: Au,
- layout: IndependentLayout,
- positioning_context: PositioningContext,
-}
-
-impl CachedBlockSizeContribution {
- fn compatible_with_item_as_containing_block(
- &self,
- item_as_containing_block: &ContainingBlock,
- ) -> bool {
- item_as_containing_block.size.inline == self.containing_block_inline_size &&
- !item_as_containing_block.size.block.is_definite()
- }
-}
diff --git a/components/layout_2020/flow/inline/mod.rs b/components/layout_2020/flow/inline/mod.rs
index a43a9333040..e9007ce2e45 100644
--- a/components/layout_2020/flow/inline/mod.rs
+++ b/components/layout_2020/flow/inline/mod.rs
@@ -109,15 +109,17 @@ use unicode_bidi::{BidiInfo, Level};
use webrender_api::FontInstanceKey;
use xi_unicode::linebreak_property;
-use super::IndependentFormattingContextContents;
use super::float::{Clear, PlacementAmongFloats};
+use super::{
+ CacheableLayoutResult, IndependentFloatOrAtomicLayoutResult,
+ IndependentFormattingContextContents,
+};
use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
+use crate::flow::CollapsibleWithParentStartMargin;
use crate::flow::float::{FloatBox, SequentialLayoutState};
-use crate::flow::{CollapsibleWithParentStartMargin, FlowLayout};
use crate::formatting_contexts::{
- Baselines, IndependentFormattingContext, IndependentLayoutResult,
- IndependentNonReplacedContents,
+ Baselines, IndependentFormattingContext, IndependentNonReplacedContents,
};
use crate::fragment_tree::{
BoxFragment, CollapsedBlockMargins, CollapsedMargin, Fragment, FragmentFlags,
@@ -1585,7 +1587,7 @@ impl InlineFormattingContext {
containing_block: &ContainingBlock,
sequential_layout_state: Option<&mut SequentialLayoutState>,
collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin,
- ) -> FlowLayout {
+ ) -> CacheableLayoutResult {
let first_line_inline_start = if self.has_first_formatted_line {
containing_block
.style
@@ -1697,12 +1699,14 @@ impl InlineFormattingContext {
content_block_size == Au::zero() &&
collapsible_with_parent_start_margin.0;
- FlowLayout {
+ CacheableLayoutResult {
fragments: layout.fragments,
content_block_size,
collapsible_margins_in_children,
baselines: layout.baselines,
depends_on_block_constraints: layout.depends_on_block_constraints,
+ content_inline_size_for_table: None,
+ specific_layout_info: None,
}
}
@@ -1922,7 +1926,7 @@ impl IndependentFormattingContext {
// We need to know the inline size of the atomic before deciding whether to do the line break.
let mut child_positioning_context = PositioningContext::new_for_style(self.style())
.unwrap_or_else(|| PositioningContext::new_for_subtree(true));
- let IndependentLayoutResult {
+ let IndependentFloatOrAtomicLayoutResult {
mut fragment,
baselines,
pbm_sums,
diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs
index 58e7310d6cd..8f38e0d4b23 100644
--- a/components/layout_2020/flow/mod.rs
+++ b/components/layout_2020/flow/mod.rs
@@ -26,7 +26,7 @@ use crate::flow::float::{
};
use crate::formatting_contexts::{
Baselines, IndependentFormattingContext, IndependentFormattingContextContents,
- IndependentLayout, IndependentLayoutResult, IndependentNonReplacedContents,
+ IndependentNonReplacedContents,
};
use crate::fragment_tree::{
BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, CollapsedMargin, Fragment, FragmentFlags,
@@ -35,7 +35,7 @@ use crate::geom::{
AuOrAuto, LogicalRect, LogicalSides, LogicalSides1D, LogicalVec2, PhysicalPoint, PhysicalRect,
PhysicalSides, Size, Sizes, ToLogical, ToLogicalWithContainingBlock,
};
-use crate::layout_box_base::LayoutBoxBase;
+use crate::layout_box_base::{CacheableLayoutResult, LayoutBoxBase};
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
use crate::replaced::ReplacedContents;
use crate::sizing::{self, ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
@@ -219,18 +219,6 @@ impl BlockLevelBox {
}
}
-pub(crate) struct FlowLayout {
- pub fragments: Vec<Fragment>,
- pub content_block_size: Au,
- pub collapsible_margins_in_children: CollapsedBlockMargins,
- /// The offset of the baselines in this layout in the content area, if there were some. This is
- /// used to propagate inflow baselines to the ancestors of `display: inline-block` elements
- /// and table content.
- pub baselines: Baselines,
- /// Whether or not this layout depends on the block size of its containing block.
- pub depends_on_block_constraints: bool,
-}
-
#[derive(Clone, Copy)]
pub(crate) struct CollapsibleWithParentStartMargin(bool);
@@ -362,7 +350,8 @@ impl BlockFormattingContext {
layout_context: &LayoutContext,
positioning_context: &mut PositioningContext,
containing_block: &ContainingBlock,
- ) -> IndependentLayout {
+ depends_on_block_constraints: bool,
+ ) -> CacheableLayoutResult {
let mut sequential_layout_state = if self.contains_floats || !layout_context.use_rayon {
Some(SequentialLayoutState::new(containing_block.size.inline))
} else {
@@ -395,15 +384,17 @@ impl BlockFormattingContext {
sequential_layout_state.calculate_clearance(Clear::Both, &CollapsedMargin::zero())
});
- IndependentLayout {
+ CacheableLayoutResult {
fragments: flow_layout.fragments,
content_block_size: flow_layout.content_block_size +
flow_layout.collapsible_margins_in_children.end.solve() +
clearance.unwrap_or_default(),
content_inline_size_for_table: None,
baselines: flow_layout.baselines,
- depends_on_block_constraints: flow_layout.depends_on_block_constraints,
+ depends_on_block_constraints: depends_on_block_constraints ||
+ flow_layout.depends_on_block_constraints,
specific_layout_info: None,
+ collapsible_margins_in_children: CollapsedBlockMargins::zero(),
}
}
@@ -573,7 +564,7 @@ impl BlockContainer {
sequential_layout_state: Option<&mut SequentialLayoutState>,
collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin,
ignore_block_margins_for_stretch: LogicalSides1D<bool>,
- ) -> FlowLayout {
+ ) -> CacheableLayoutResult {
match self {
BlockContainer::BlockLevelBoxes(child_boxes) => layout_block_level_children(
layout_context,
@@ -627,7 +618,7 @@ fn layout_block_level_children(
mut sequential_layout_state: Option<&mut SequentialLayoutState>,
collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin,
ignore_block_margins_for_stretch: LogicalSides1D<bool>,
-) -> FlowLayout {
+) -> CacheableLayoutResult {
let mut placement_state =
PlacementState::new(collapsible_with_parent_start_margin, containing_block);
@@ -660,12 +651,14 @@ fn layout_block_level_children(
});
let (content_block_size, collapsible_margins_in_children, baselines) = placement_state.finish();
- FlowLayout {
+ CacheableLayoutResult {
fragments,
content_block_size,
collapsible_margins_in_children,
baselines,
depends_on_block_constraints,
+ content_inline_size_for_table: None,
+ specific_layout_info: None,
}
}
@@ -1150,6 +1143,7 @@ impl IndependentNonReplacedContents {
positioning_context,
&containing_block_for_children,
containing_block,
+ false, /* depends_on_block_constraints */
);
let inline_size = layout
@@ -1299,7 +1293,7 @@ impl IndependentNonReplacedContents {
)
};
- let compute_block_size = |layout: &IndependentLayout| {
+ let compute_block_size = |layout: &CacheableLayoutResult| {
content_box_sizes.block.resolve(
Direction::Block,
Size::FitContent,
@@ -1335,6 +1329,7 @@ impl IndependentNonReplacedContents {
style,
},
containing_block,
+ false, /* depends_on_block_constraints */
);
content_size = LogicalVec2 {
@@ -1398,6 +1393,7 @@ impl IndependentNonReplacedContents {
style,
},
containing_block,
+ false, /* depends_on_block_constraints */
);
let inline_size = if let Some(inline_size) = layout.content_inline_size_for_table {
@@ -2162,6 +2158,12 @@ fn block_size_is_zero_or_intrinsic(size: &StyleSize, containing_block: &Containi
}
}
+pub(crate) struct IndependentFloatOrAtomicLayoutResult {
+ pub fragment: BoxFragment,
+ pub baselines: Option<Baselines>,
+ pub pbm_sums: LogicalSides<Au>,
+}
+
impl IndependentFormattingContext {
pub(crate) fn layout_in_flow_block_level(
&self,
@@ -2196,7 +2198,7 @@ impl IndependentFormattingContext {
layout_context: &LayoutContext,
child_positioning_context: &mut PositioningContext,
containing_block: &ContainingBlock,
- ) -> IndependentLayoutResult {
+ ) -> IndependentFloatOrAtomicLayoutResult {
let style = self.style();
let container_writing_mode = containing_block.style.writing_mode;
let layout_style = self.layout_style();
@@ -2280,6 +2282,7 @@ impl IndependentFormattingContext {
child_positioning_context,
&containing_block_for_children,
containing_block,
+ false, /* depends_on_block_constraints */
);
let inline_size = independent_layout
.content_inline_size_for_table
@@ -2330,7 +2333,7 @@ impl IndependentFormattingContext {
CollapsedBlockMargins::zero(),
);
- IndependentLayoutResult {
+ IndependentFloatOrAtomicLayoutResult {
fragment,
baselines,
pbm_sums,
diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs
index 5b7cf077bab..4fb33bf71d4 100644
--- a/components/layout_2020/flow/root.rs
+++ b/components/layout_2020/flow/root.rs
@@ -365,6 +365,7 @@ impl BoxTree {
layout_context,
&mut positioning_context,
&(&initial_containing_block).into(),
+ false, /* depends_on_block_constraints */
);
let mut root_fragments = independent_layout.fragments.into_iter().collect::<Vec<_>>();
diff --git a/components/layout_2020/formatting_contexts.rs b/components/layout_2020/formatting_contexts.rs
index 96b78bf6eef..573e9100cec 100644
--- a/components/layout_2020/formatting_contexts.rs
+++ b/components/layout_2020/formatting_contexts.rs
@@ -12,11 +12,10 @@ use crate::dom::NodeExt;
use crate::dom_traversal::{Contents, NodeAndStyleInfo};
use crate::flexbox::FlexContainer;
use crate::flow::BlockFormattingContext;
-use crate::fragment_tree::{
- BaseFragmentInfo, BoxFragment, Fragment, FragmentFlags, SpecificLayoutInfo,
+use crate::fragment_tree::{BaseFragmentInfo, FragmentFlags};
+use crate::layout_box_base::{
+ CacheableLayoutResult, CacheableLayoutResultAndInputs, LayoutBoxBase,
};
-use crate::geom::LogicalSides;
-use crate::layout_box_base::LayoutBoxBase;
use crate::positioned::PositioningContext;
use crate::replaced::ReplacedContents;
use crate::sizing::{self, ComputeInlineContentSizes, InlineContentSizesResult};
@@ -68,35 +67,6 @@ impl Baselines {
}
}
-pub(crate) struct IndependentLayout {
- pub fragments: Vec<Fragment>,
-
- /// <https://drafts.csswg.org/css2/visudet.html#root-height>
- pub content_block_size: Au,
-
- /// If a table has collapsed columns, it can become smaller than what the parent
- /// formatting context decided. This is the resulting inline content size.
- /// This is None for non-table layouts and for tables without collapsed columns.
- pub content_inline_size_for_table: Option<Au>,
-
- /// The offset of the last inflow baseline of this layout in the content area, if
- /// there was one. This is used to propagate baselines to the ancestors of `display:
- /// inline-block`.
- pub baselines: Baselines,
-
- /// Whether or not this layout depends on the containing block size.
- pub depends_on_block_constraints: bool,
-
- /// Additional information of this layout that could be used by Javascripts and devtools.
- pub specific_layout_info: Option<SpecificLayoutInfo>,
-}
-
-pub(crate) struct IndependentLayoutResult {
- pub fragment: BoxFragment,
- pub baselines: Option<Baselines>,
- pub pbm_sums: LogicalSides<Au>,
-}
-
impl IndependentFormattingContext {
pub fn construct<'dom, Node: NodeExt<'dom>>(
context: &LayoutContext,
@@ -255,17 +225,20 @@ impl IndependentNonReplacedContents {
positioning_context: &mut PositioningContext,
containing_block_for_children: &ContainingBlock,
containing_block: &ContainingBlock,
- ) -> IndependentLayout {
+ depends_on_block_constraints: bool,
+ ) -> CacheableLayoutResult {
match self {
IndependentNonReplacedContents::Flow(bfc) => bfc.layout(
layout_context,
positioning_context,
containing_block_for_children,
+ depends_on_block_constraints,
),
IndependentNonReplacedContents::Flex(fc) => fc.layout(
layout_context,
positioning_context,
containing_block_for_children,
+ depends_on_block_constraints,
),
IndependentNonReplacedContents::Grid(fc) => fc.layout(
layout_context,
@@ -278,10 +251,70 @@ impl IndependentNonReplacedContents {
positioning_context,
containing_block_for_children,
containing_block,
+ depends_on_block_constraints,
),
}
}
+ #[cfg_attr(
+ feature = "tracing",
+ tracing::instrument(
+ name = "IndependentNonReplacedContents::layout_with_caching",
+ skip_all,
+ fields(servo_profiling = true),
+ level = "trace",
+ )
+ )]
+ pub fn layout_with_caching(
+ &self,
+ layout_context: &LayoutContext,
+ positioning_context: &mut PositioningContext,
+ containing_block_for_children: &ContainingBlock,
+ containing_block: &ContainingBlock,
+ base: &LayoutBoxBase,
+ depends_on_block_constraints: bool,
+ ) -> CacheableLayoutResult {
+ if let Some(cache) = base.cached_layout_result.borrow().as_ref() {
+ if cache.containing_block_for_children_size.inline ==
+ containing_block_for_children.size.inline &&
+ (cache.containing_block_for_children_size.block ==
+ containing_block_for_children.size.block ||
+ !(cache.result.depends_on_block_constraints ||
+ depends_on_block_constraints))
+ {
+ positioning_context.append(cache.positioning_context.clone());
+ return cache.result.clone();
+ }
+ #[cfg(feature = "tracing")]
+ tracing::debug!(
+ name: "NonReplaced cache miss",
+ cached = ?cache.containing_block_for_children_size,
+ required = ?containing_block_for_children.size,
+ );
+ }
+
+ let mut child_positioning_context = PositioningContext::new_for_subtree(
+ positioning_context.collects_for_nearest_positioned_ancestor(),
+ );
+
+ let result = self.layout(
+ layout_context,
+ &mut child_positioning_context,
+ containing_block_for_children,
+ containing_block,
+ depends_on_block_constraints,
+ );
+
+ *base.cached_layout_result.borrow_mut() = Some(CacheableLayoutResultAndInputs {
+ result: result.clone(),
+ positioning_context: child_positioning_context.clone(),
+ containing_block_for_children_size: containing_block_for_children.size.clone(),
+ });
+ positioning_context.append(child_positioning_context);
+
+ result
+ }
+
#[inline]
pub(crate) fn layout_style<'a>(&'a self, base: &'a LayoutBoxBase) -> LayoutStyle<'a> {
match self {
diff --git a/components/layout_2020/fragment_tree/fragment.rs b/components/layout_2020/fragment_tree/fragment.rs
index ba52f28bc3b..fbc95ce3d5a 100644
--- a/components/layout_2020/fragment_tree/fragment.rs
+++ b/components/layout_2020/fragment_tree/fragment.rs
@@ -45,6 +45,7 @@ pub(crate) enum Fragment {
IFrame(ArcRefCell<IFrameFragment>),
}
+#[derive(Clone)]
pub(crate) struct CollapsedBlockMargins {
pub collapsed_through: bool,
pub start: CollapsedMargin,
diff --git a/components/layout_2020/layout_box_base.rs b/components/layout_2020/layout_box_base.rs
index 0de9987bde7..bb2d37698f1 100644
--- a/components/layout_2020/layout_box_base.rs
+++ b/components/layout_2020/layout_box_base.rs
@@ -2,15 +2,20 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use std::fmt::{Debug, Formatter};
+
+use app_units::Au;
use atomic_refcell::AtomicRefCell;
use servo_arc::Arc;
use style::properties::ComputedValues;
-use crate::ConstraintSpace;
use crate::context::LayoutContext;
-use crate::fragment_tree::BaseFragmentInfo;
+use crate::formatting_contexts::Baselines;
+use crate::fragment_tree::{BaseFragmentInfo, CollapsedBlockMargins, Fragment, SpecificLayoutInfo};
use crate::geom::SizeConstraint;
+use crate::positioned::PositioningContext;
use crate::sizing::{ComputeInlineContentSizes, InlineContentSizesResult};
+use crate::{ConstraintSpace, ContainingBlockSize};
/// A box tree node that handles containing information about style and the original DOM
/// node or pseudo-element that it is based on. This also handles caching of layout values
@@ -18,12 +23,12 @@ use crate::sizing::{ComputeInlineContentSizes, InlineContentSizesResult};
/// passes.
///
/// In the future, this will hold layout results to support incremental layout.
-#[derive(Debug)]
pub(crate) struct LayoutBoxBase {
pub base_fragment_info: BaseFragmentInfo,
pub style: Arc<ComputedValues>,
pub cached_inline_content_size:
AtomicRefCell<Option<(SizeConstraint, InlineContentSizesResult)>>,
+ pub cached_layout_result: AtomicRefCell<Option<CacheableLayoutResultAndInputs>>,
}
impl LayoutBoxBase {
@@ -32,6 +37,7 @@ impl LayoutBoxBase {
base_fragment_info,
style,
cached_inline_content_size: AtomicRefCell::default(),
+ cached_layout_result: AtomicRefCell::default(),
}
}
@@ -58,3 +64,45 @@ impl LayoutBoxBase {
result
}
}
+
+impl Debug for LayoutBoxBase {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
+ f.debug_struct("LayoutBoxBase").finish()
+ }
+}
+
+#[derive(Clone)]
+pub(crate) struct CacheableLayoutResult {
+ pub fragments: Vec<Fragment>,
+
+ /// <https://drafts.csswg.org/css2/visudet.html#root-height>
+ pub content_block_size: Au,
+
+ /// If this layout is for a block container, this tracks the collapsable size
+ /// of start and end margins and whether or not the block container collapsed through.
+ pub collapsible_margins_in_children: CollapsedBlockMargins,
+
+ /// The contents of a table may force it to become wider than what we would expect
+ /// from 'width' and 'min-width'. This is the resulting inline content size,
+ /// or None for non-table layouts.
+ pub content_inline_size_for_table: Option<Au>,
+
+ /// The offset of the last inflow baseline of this layout in the content area, if
+ /// there was one. This is used to propagate baselines to the ancestors of `display:
+ /// inline-block`.
+ pub baselines: Baselines,
+
+ /// Whether or not this layout depends on the containing block size.
+ pub depends_on_block_constraints: bool,
+
+ /// Additional information of this layout that could be used by Javascripts and devtools.
+ pub specific_layout_info: Option<SpecificLayoutInfo>,
+}
+
+pub(crate) struct CacheableLayoutResultAndInputs {
+ pub result: CacheableLayoutResult,
+
+ pub containing_block_for_children_size: ContainingBlockSize,
+
+ pub positioning_context: PositioningContext,
+}
diff --git a/components/layout_2020/lib.rs b/components/layout_2020/lib.rs
index 780d670c541..640f9ff938b 100644
--- a/components/layout_2020/lib.rs
+++ b/components/layout_2020/lib.rs
@@ -112,7 +112,7 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for IndefiniteContainingBlock {
}
}
-#[derive(Debug)]
+#[derive(Clone, Debug)]
pub(crate) struct ContainingBlockSize {
inline: Au,
block: SizeConstraint,
diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs
index 8b10a79b59c..238eb1e3b2a 100644
--- a/components/layout_2020/positioned.rs
+++ b/components/layout_2020/positioned.rs
@@ -41,6 +41,7 @@ pub(crate) struct AbsolutelyPositionedBox {
pub context: IndependentFormattingContext,
}
+#[derive(Clone)]
pub(crate) struct PositioningContext {
for_nearest_positioned_ancestor: Option<Vec<HoistedAbsolutelyPositionedBox>>,
@@ -50,6 +51,7 @@ pub(crate) struct PositioningContext {
for_nearest_containing_block_for_all_descendants: Vec<HoistedAbsolutelyPositionedBox>,
}
+#[derive(Clone)]
pub(crate) struct HoistedAbsolutelyPositionedBox {
absolutely_positioned_box: ArcRefCell<AbsolutelyPositionedBox>,
@@ -299,7 +301,7 @@ impl PositioningContext {
.push(box_)
}
- fn is_empty(&self) -> bool {
+ pub(crate) fn is_empty(&self) -> bool {
self.for_nearest_containing_block_for_all_descendants
.is_empty() &&
self.for_nearest_positioned_ancestor
@@ -627,6 +629,7 @@ impl HoistedAbsolutelyPositionedBox {
&mut positioning_context,
&containing_block_for_children,
containing_block,
+ false, /* depends_on_block_constraints */
);
let inline_size = if let Some(inline_size) =
diff --git a/components/layout_2020/table/layout.rs b/components/layout_2020/table/layout.rs
index 29014ae171c..ed35cff6049 100644
--- a/components/layout_2020/table/layout.rs
+++ b/components/layout_2020/table/layout.rs
@@ -29,7 +29,7 @@ use super::{
TableLayoutStyle, TableSlot, TableSlotCell, TableSlotCoordinates, TableTrack, TableTrackGroup,
};
use crate::context::LayoutContext;
-use crate::formatting_contexts::{Baselines, IndependentLayout};
+use crate::formatting_contexts::Baselines;
use crate::fragment_tree::{
BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, ExtraBackground, Fragment, FragmentFlags,
PositioningFragment, SpecificLayoutInfo,
@@ -38,6 +38,7 @@ use crate::geom::{
LogicalRect, LogicalSides, LogicalSides1D, LogicalVec2, PhysicalPoint, PhysicalRect,
PhysicalSides, PhysicalVec, Size, SizeConstraint, ToLogical, ToLogicalWithContainingBlock,
};
+use crate::layout_box_base::CacheableLayoutResult;
use crate::positioned::{PositioningContext, PositioningContextLength, relative_adjustement};
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
use crate::style_ext::{
@@ -51,7 +52,7 @@ use crate::{
/// the table. Note that this is only done for slots that are not
/// covered by spans or empty.
struct CellLayout {
- layout: IndependentLayout,
+ layout: CacheableLayoutResult,
padding: LogicalSides<Au>,
border: LogicalSides<Au>,
positioning_context: PositioningContext,
@@ -1137,6 +1138,7 @@ impl<'a> TableLayout<'a> {
layout_context,
&mut positioning_context,
&containing_block_for_children,
+ false, /* depends_on_block_constraints */
);
Some(CellLayout {
@@ -1539,13 +1541,15 @@ impl<'a> TableLayout<'a> {
positioning_context: &mut PositioningContext,
containing_block_for_children: &ContainingBlock,
containing_block_for_table: &ContainingBlock,
- ) -> IndependentLayout {
+ depends_on_block_constraints: bool,
+ ) -> CacheableLayoutResult {
let table_writing_mode = containing_block_for_children.style.writing_mode;
self.compute_border_collapse(table_writing_mode);
let layout_style = self.table.layout_style(Some(&self));
- let depends_on_block_constraints = layout_style
- .content_box_sizes_and_padding_border_margin(&containing_block_for_table.into())
- .depends_on_block_constraints;
+ let depends_on_block_constraints = depends_on_block_constraints ||
+ layout_style
+ .content_box_sizes_and_padding_border_margin(&containing_block_for_table.into())
+ .depends_on_block_constraints;
self.pbm = layout_style
.padding_border_margin_with_writing_mode_and_containing_block_inline_size(
@@ -1579,13 +1583,14 @@ impl<'a> TableLayout<'a> {
let offset_from_wrapper = -self.pbm.padding - self.pbm.border;
let mut current_block_offset = offset_from_wrapper.block_start;
- let mut table_layout = IndependentLayout {
+ let mut table_layout = CacheableLayoutResult {
fragments: Vec::new(),
content_block_size: Zero::zero(),
content_inline_size_for_table: None,
baselines: Baselines::default(),
depends_on_block_constraints,
specific_layout_info: Some(SpecificLayoutInfo::TableWrapper),
+ collapsible_margins_in_children: CollapsedBlockMargins::zero(),
};
table_layout
@@ -2664,12 +2669,14 @@ impl Table {
positioning_context: &mut PositioningContext,
containing_block_for_children: &ContainingBlock,
containing_block_for_table: &ContainingBlock,
- ) -> IndependentLayout {
+ depends_on_block_constraints: bool,
+ ) -> CacheableLayoutResult {
TableLayout::new(self).layout(
layout_context,
positioning_context,
containing_block_for_children,
containing_block_for_table,
+ depends_on_block_constraints,
)
}
}
diff --git a/components/layout_2020/taffy/layout.rs b/components/layout_2020/taffy/layout.rs
index 1e58464629f..6c1b931599c 100644
--- a/components/layout_2020/taffy/layout.rs
+++ b/components/layout_2020/taffy/layout.rs
@@ -18,7 +18,6 @@ use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
use crate::formatting_contexts::{
Baselines, IndependentFormattingContext, IndependentFormattingContextContents,
- IndependentLayout,
};
use crate::fragment_tree::{
BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags, SpecificLayoutInfo,
@@ -27,6 +26,7 @@ use crate::geom::{
LogicalSides, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, Size,
SizeConstraint, Sizes,
};
+use crate::layout_box_base::CacheableLayoutResult;
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
use crate::style_ext::{ComputedValuesExt, LayoutStyle};
@@ -264,6 +264,7 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
&mut child_positioning_context,
&content_box_size_override,
containing_block,
+ false, /* depends_on_block_constraints */
);
// Store layout data on child for later access
@@ -425,7 +426,7 @@ impl TaffyContainer {
positioning_context: &mut PositioningContext,
content_box_size_override: &ContainingBlock,
containing_block: &ContainingBlock,
- ) -> IndependentLayout {
+ ) -> CacheableLayoutResult {
let mut container_ctx = TaffyContainerContext {
layout_context,
positioning_context,
@@ -643,7 +644,7 @@ impl TaffyContainer {
})
.collect();
- IndependentLayout {
+ CacheableLayoutResult {
fragments,
content_block_size: Au::from_f32_px(output.size.height) - pbm.padding_border_sums.block,
content_inline_size_for_table: None,
@@ -654,8 +655,8 @@ impl TaffyContainer {
// "true" is a safe default as it will prevent Servo from performing optimizations based
// on the assumption that the node's size does not depend on block constraints.
depends_on_block_constraints: true,
-
specific_layout_info: container_ctx.specific_layout_info,
+ collapsible_margins_in_children: CollapsedBlockMargins::zero(),
}
}