diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-01-13 10:59:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-13 09:59:59 +0000 |
commit | de780dcde418759156fb93470fac2c89228425ab (patch) | |
tree | aba9ac581530a5c56bfbd4320fd3eddb2c7e741f /components | |
parent | c936dd6c4e80ac6e6f188fe629cc999f121e452d (diff) | |
download | servo-de780dcde418759156fb93470fac2c89228425ab.tar.gz servo-de780dcde418759156fb93470fac2c89228425ab.zip |
layout: Make `Fragment` hold `ArcRefCell` inside (#34923)
Push the interior mutability into enum variants of `Fragment`, so that
they can be cloned. This saves memory in the `Fragment` tree as the
`Fragment` enum is now a relatively wee 16 bytes and the interior parts
can be a variety of sizes. Before, every `Fragment` was the size of the
biggest kind (`BoxFragment` - 248 bytes).
This a step on the way toward incremental layout.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Oriol Brufau <obrufau@igalia.com>
Diffstat (limited to 'components')
18 files changed, 259 insertions, 235 deletions
diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs index 641a256d92f..aa6e22602f8 100644 --- a/components/layout_2020/display_list/mod.rs +++ b/components/layout_2020/display_list/mod.rs @@ -246,6 +246,7 @@ impl Fragment { ) { match self { Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => { + let box_fragment = &*box_fragment.borrow(); match box_fragment.style.get_inherited_box().visibility { Visibility::Visible => BuilderForBoxFragment::new( box_fragment, @@ -259,6 +260,7 @@ impl Fragment { }, Fragment::AbsoluteOrFixedPositioned(_) => {}, Fragment::Positioning(positioning_fragment) => { + let positioning_fragment = positioning_fragment.borrow(); if let Some(style) = positioning_fragment.style.as_ref() { let rect = positioning_fragment .rect @@ -272,65 +274,74 @@ impl Fragment { ); } }, - Fragment::Image(image) => match image.style.get_inherited_box().visibility { - Visibility::Visible => { - builder.is_contentful = true; - - let image_rendering = image - .style - .get_inherited_box() - .image_rendering - .to_webrender(); - let rect = image - .rect - .translate(containing_block.origin.to_vector()) - .to_webrender(); - let clip = image - .clip - .translate(containing_block.origin.to_vector()) - .to_webrender(); - let common = builder.common_properties(clip, &image.style); - - if let Some(image_key) = image.image_key { - builder.wr().push_image( - &common, - rect, - image_rendering, - wr::AlphaType::PremultipliedAlpha, - image_key, - wr::ColorF::WHITE, - ); - } - }, - Visibility::Hidden => (), - Visibility::Collapse => (), + Fragment::Image(image) => { + let image = image.borrow(); + match image.style.get_inherited_box().visibility { + Visibility::Visible => { + builder.is_contentful = true; + + let image_rendering = image + .style + .get_inherited_box() + .image_rendering + .to_webrender(); + let rect = image + .rect + .translate(containing_block.origin.to_vector()) + .to_webrender(); + let clip = image + .clip + .translate(containing_block.origin.to_vector()) + .to_webrender(); + let common = builder.common_properties(clip, &image.style); + + if let Some(image_key) = image.image_key { + builder.wr().push_image( + &common, + rect, + image_rendering, + wr::AlphaType::PremultipliedAlpha, + image_key, + wr::ColorF::WHITE, + ); + } + }, + Visibility::Hidden => (), + Visibility::Collapse => (), + } }, - Fragment::IFrame(iframe) => match iframe.style.get_inherited_box().visibility { - Visibility::Visible => { - builder.is_contentful = true; - let rect = iframe.rect.translate(containing_block.origin.to_vector()); - - let common = builder.common_properties(rect.to_webrender(), &iframe.style); - builder.wr().push_iframe( - rect.to_webrender(), - common.clip_rect, - &wr::SpaceAndClipInfo { - spatial_id: common.spatial_id, - clip_chain_id: common.clip_chain_id, - }, - iframe.pipeline_id.into(), - true, - ); - }, - Visibility::Hidden => (), - Visibility::Collapse => (), + Fragment::IFrame(iframe) => { + let iframe = iframe.borrow(); + match iframe.style.get_inherited_box().visibility { + Visibility::Visible => { + builder.is_contentful = true; + let rect = iframe.rect.translate(containing_block.origin.to_vector()); + + let common = builder.common_properties(rect.to_webrender(), &iframe.style); + builder.wr().push_iframe( + rect.to_webrender(), + common.clip_rect, + &wr::SpaceAndClipInfo { + spatial_id: common.spatial_id, + clip_chain_id: common.clip_chain_id, + }, + iframe.pipeline_id.into(), + true, + ); + }, + Visibility::Hidden => (), + Visibility::Collapse => (), + } }, - Fragment::Text(t) => match t.parent_style.get_inherited_box().visibility { - Visibility::Visible => { - self.build_display_list_for_text_fragment(t, builder, containing_block) - }, - Visibility::Hidden => (), - Visibility::Collapse => (), + Fragment::Text(text) => { + let text = &*text.borrow(); + match text.parent_style.get_inherited_box().visibility { + Visibility::Visible => { + self.build_display_list_for_text_fragment(text, builder, containing_block) + }, + Visibility::Hidden => (), + Visibility::Collapse => (), + } }, } } diff --git a/components/layout_2020/display_list/stacking_context.rs b/components/layout_2020/display_list/stacking_context.rs index 76235bca453..b338b46e130 100644 --- a/components/layout_2020/display_list/stacking_context.rs +++ b/components/layout_2020/display_list/stacking_context.rs @@ -31,7 +31,6 @@ use wr::{ClipChainId, SpatialTreeItemKey, StickyOffsetBounds}; use super::clip_path::build_clip_path_clip_chain_if_necessary; use super::DisplayList; -use crate::cell::ArcRefCell; use crate::display_list::conversions::{FilterToWebRender, ToWebRender}; use crate::display_list::{BuilderForBoxFragment, DisplayListBuilder}; use crate::fragment_tree::{ @@ -142,8 +141,7 @@ impl DisplayList { let mut root_stacking_context = StackingContext::create_root(&self.wr, debug); for fragment in &fragment_tree.root_fragments { - fragment.borrow_mut().build_stacking_context_tree( - fragment, + fragment.build_stacking_context_tree( self, &containing_block_info, &mut root_stacking_context, @@ -260,7 +258,7 @@ pub(crate) enum StackingContextContent { clip_chain_id: wr::ClipChainId, section: StackingContextSection, containing_block: PhysicalRect<Au>, - fragment: ArcRefCell<Fragment>, + fragment: Fragment, is_hit_test_for_scrollable_overflow: bool, }, @@ -296,7 +294,7 @@ impl StackingContextContent { builder.current_scroll_node_id = *scroll_node_id; builder.current_reference_frame_scroll_node_id = *reference_frame_scroll_node_id; builder.current_clip_chain_id = *clip_chain_id; - fragment.borrow().build_display_list( + fragment.build_display_list( builder, containing_block, *section, @@ -632,13 +630,11 @@ impl StackingContext { else { debug_panic!("Expected a fragment, not a stacking container"); }; - let fragment = fragment.borrow(); - let box_fragment = match &*fragment { + let box_fragment = match fragment { Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => box_fragment, - _ => { - debug_panic!("Expected a box-generated fragment"); - }, + _ => debug_panic!("Expected a box-generated fragment"), }; + let box_fragment = &*box_fragment.borrow(); // The `StackingContextFragment` we found is for the root DOM element: debug_assert_eq!( @@ -849,16 +845,17 @@ pub(crate) enum StackingContextBuildMode { impl Fragment { pub(crate) fn build_stacking_context_tree( - &mut self, - fragment_ref: &ArcRefCell<Fragment>, + &self, display_list: &mut DisplayList, containing_block_info: &ContainingBlockInfo, stacking_context: &mut StackingContext, mode: StackingContextBuildMode, ) { let containing_block = containing_block_info.get_containing_block_for_fragment(self); + let fragment_clone = self.clone(); match self { Fragment::Box(fragment) | Fragment::Float(fragment) => { + let fragment = fragment.borrow(); if mode == StackingContextBuildMode::SkipHoisted && fragment.style.clone_position().is_absolutely_positioned() { @@ -876,7 +873,7 @@ impl Fragment { } fragment.build_stacking_context_tree( - fragment_ref, + fragment_clone, display_list, containing_block, containing_block_info, @@ -890,8 +887,7 @@ impl Fragment { None => unreachable!("Found hoisted box with missing fragment."), }; - fragment_ref.borrow_mut().build_stacking_context_tree( - fragment_ref, + fragment_ref.build_stacking_context_tree( display_list, containing_block_info, stacking_context, @@ -899,6 +895,7 @@ impl Fragment { ); }, Fragment::Positioning(fragment) => { + let fragment = fragment.borrow(); fragment.build_stacking_context_tree( display_list, containing_block, @@ -917,7 +914,7 @@ impl Fragment { .scroll_node_id, clip_chain_id: containing_block.clip_chain_id, containing_block: containing_block.rect, - fragment: fragment_ref.clone(), + fragment: fragment_clone, is_hit_test_for_scrollable_overflow: false, }); }, @@ -971,8 +968,8 @@ impl BoxFragment { } fn build_stacking_context_tree( - &mut self, - fragment: &ArcRefCell<Fragment>, + &self, + fragment: Fragment, display_list: &mut DisplayList, containing_block: &ContainingBlock, containing_block_info: &ContainingBlockInfo, @@ -988,8 +985,8 @@ impl BoxFragment { } fn build_stacking_context_tree_maybe_creating_reference_frame( - &mut self, - fragment: &ArcRefCell<Fragment>, + &self, + fragment: Fragment, display_list: &mut DisplayList, containing_block: &ContainingBlock, containing_block_info: &ContainingBlockInfo, @@ -1052,8 +1049,8 @@ impl BoxFragment { } fn build_stacking_context_tree_maybe_creating_stacking_context( - &mut self, - fragment: &ArcRefCell<Fragment>, + &self, + fragment: Fragment, display_list: &mut DisplayList, containing_block: &ContainingBlock, containing_block_info: &ContainingBlockInfo, @@ -1128,8 +1125,8 @@ impl BoxFragment { } fn build_stacking_context_tree_for_children( - &mut self, - fragment: &ArcRefCell<Fragment>, + &self, + fragment: Fragment, display_list: &mut DisplayList, containing_block: &ContainingBlock, containing_block_info: &ContainingBlockInfo, @@ -1273,8 +1270,7 @@ impl BoxFragment { }; for child in &self.children { - child.borrow_mut().build_stacking_context_tree( - child, + child.build_stacking_context_tree( display_list, &new_containing_block_info, stacking_context, @@ -1381,7 +1377,7 @@ impl BoxFragment { } fn build_sticky_frame_if_necessary( - &mut self, + &self, display_list: &mut DisplayList, parent_scroll_node_id: &ScrollTreeNodeId, containing_block_rect: &PhysicalRect<Au>, @@ -1411,7 +1407,7 @@ impl BoxFragment { offsets.bottom.map(|v| v.to_used_value(scroll_frame_height)), offsets.left.map(|v| v.to_used_value(scroll_frame_width)), ); - self.resolved_sticky_insets = Some(offsets); + *self.resolved_sticky_insets.borrow_mut() = Some(offsets); if scroll_frame_size.is_none() { return None; @@ -1610,8 +1606,7 @@ impl PositioningFragment { containing_block_info.new_for_non_absolute_descendants(&new_containing_block); for child in &self.children { - child.borrow_mut().build_stacking_context_tree( - child, + child.build_stacking_context_tree( display_list, &new_containing_block_info, stacking_context, diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs index 79d35c7e5f9..579bca2615a 100644 --- a/components/layout_2020/flexbox/layout.rs +++ b/components/layout_2020/flexbox/layout.rs @@ -947,7 +947,7 @@ impl FlexContainer { // per flex item, in the original order. let (fragment, mut child_positioning_context) = flex_item_fragments.next().unwrap(); - let fragment = Fragment::Box(fragment); + let fragment = Fragment::Box(ArcRefCell::new(fragment)); child_positioning_context.adjust_static_position_of_hoisted_fragments( &fragment, PositioningContextLength::zero(), diff --git a/components/layout_2020/flow/inline/line.rs b/components/layout_2020/flow/inline/line.rs index f67efc14f05..202dbf508bf 100644 --- a/components/layout_2020/flow/inline/line.rs +++ b/components/layout_2020/flow/inline/line.rs @@ -292,9 +292,9 @@ impl LineItemLayout<'_, '_> { // We do not know the actual physical position of a logically laid out inline element, until // we know the width of the containing inline block. This step converts the logical rectangle // into a physical one based on the inline formatting context width. - if let Some(content_rect) = fragment.content_rect_mut() { + fragment.mutate_content_rect(|content_rect| { *content_rect = logical_rect.as_physical(Some(self.layout.containing_block)) - } + }); fragment }) @@ -436,7 +436,7 @@ impl LineItemLayout<'_, '_> { .into_iter() .map(|(mut fragment, logical_rect)| { let is_float = matches!(fragment, Fragment::Float(_)); - if let Some(content_rect) = fragment.content_rect_mut() { + fragment.mutate_content_rect(|content_rect| { if is_float { content_rect.origin -= pbm_sums.start_offset().to_physical_size(ifc_writing_mode); @@ -446,7 +446,7 @@ impl LineItemLayout<'_, '_> { // into a physical one now that we've computed inline size of the containing inline block above. *content_rect = logical_rect.as_physical(Some(&inline_box_containing_block)) } - } + }); fragment }) .collect(); @@ -495,7 +495,7 @@ impl LineItemLayout<'_, '_> { self.current_state.inline_advance += inner_state.inline_advance + pbm_sums.inline_sum(); self.current_state .fragments - .push((Fragment::Box(fragment), content_rect)); + .push((Fragment::Box(ArcRefCell::new(fragment)), content_rect)); } fn calculate_inline_box_block_start( @@ -566,7 +566,7 @@ impl LineItemLayout<'_, '_> { self.current_state.inline_advance += inline_advance; self.current_state.fragments.push(( - Fragment::Text(TextFragment { + Fragment::Text(ArcRefCell::new(TextFragment { base: text_item.base_fragment_info.into(), parent_style: text_item.parent_style, rect: PhysicalRect::zero(), @@ -575,7 +575,7 @@ impl LineItemLayout<'_, '_> { glyphs: text_item.text, text_decoration_line: text_item.text_decoration_line, justification_adjustment: self.justification_adjustment, - }), + })), content_rect, )); } @@ -627,9 +627,10 @@ impl LineItemLayout<'_, '_> { } self.current_state.inline_advance += atomic.size.inline; - self.current_state - .fragments - .push((Fragment::Box(atomic.fragment), content_rect)); + self.current_state.fragments.push(( + Fragment::Box(ArcRefCell::new(atomic.fragment)), + content_rect, + )); } fn layout_absolute(&mut self, absolute: AbsolutelyPositionedLineItem) { @@ -706,9 +707,10 @@ impl LineItemLayout<'_, '_> { float.fragment.content_rect.origin -= distance_from_parent_to_ifc .to_physical_size(self.layout.containing_block.style.writing_mode); - self.current_state - .fragments - .push((Fragment::Float(float.fragment), LogicalRect::zero())); + self.current_state.fragments.push(( + Fragment::Float(ArcRefCell::new(float.fragment)), + LogicalRect::zero(), + )); } } diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index 0781fc73b37..2f3092b2378 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -289,9 +289,9 @@ impl OutsideMarker { .fold(Au::zero(), |current_max, fragment| { current_max.max( match fragment { - Fragment::Text(text) => text.rect, - Fragment::Image(image) => image.rect, - Fragment::Positioning(positioning) => positioning.rect, + Fragment::Text(text) => text.borrow().rect, + Fragment::Image(image) => image.borrow().rect, + Fragment::Positioning(positioning) => positioning.borrow().rect, Fragment::Box(_) | Fragment::Float(_) | Fragment::AbsoluteOrFixedPositioned(_) | @@ -331,7 +331,7 @@ impl OutsideMarker { let mut base_fragment_info = BaseFragmentInfo::anonymous(); base_fragment_info.flags |= FragmentFlags::IS_OUTSIDE_LIST_ITEM_MARKER; - Fragment::Box(BoxFragment::new( + Fragment::Box(ArcRefCell::new(BoxFragment::new( base_fragment_info, self.marker_style.clone(), flow_layout.fragments, @@ -341,7 +341,7 @@ impl OutsideMarker { PhysicalSides::zero(), None, CollapsedBlockMargins::zero(), - )) + ))) } } @@ -724,8 +724,8 @@ impl BlockLevelBox { collapsible_with_parent_start_margin: Option<CollapsibleWithParentStartMargin>, ) -> Fragment { match self { - BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => { - Fragment::Box(positioning_context.layout_maybe_position_relative_fragment( + BlockLevelBox::SameFormattingContextBlock { base, contents, .. } => Fragment::Box( + ArcRefCell::new(positioning_context.layout_maybe_position_relative_fragment( layout_context, containing_block, &base.style, @@ -740,10 +740,10 @@ impl BlockLevelBox { collapsible_with_parent_start_margin, ) }, - )) - }, - BlockLevelBox::Independent(independent) => { - Fragment::Box(positioning_context.layout_maybe_position_relative_fragment( + )), + ), + BlockLevelBox::Independent(independent) => Fragment::Box(ArcRefCell::new( + positioning_context.layout_maybe_position_relative_fragment( layout_context, containing_block, independent.style(), @@ -755,8 +755,8 @@ impl BlockLevelBox { sequential_layout_state, ) }, - )) - }, + ), + )), BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => { // The static position of zero here is incorrect, however we do not know // the correct positioning until later, in place_block_level_fragment, and @@ -777,10 +777,8 @@ impl BlockLevelBox { positioning_context.push(hoisted_box); Fragment::AbsoluteOrFixedPositioned(hoisted_fragment) }, - BlockLevelBox::OutOfFlowFloatBox(float_box) => Fragment::Float(float_box.layout( - layout_context, - positioning_context, - containing_block, + BlockLevelBox::OutOfFlowFloatBox(float_box) => Fragment::Float(ArcRefCell::new( + float_box.layout(layout_context, positioning_context, containing_block), )), BlockLevelBox::OutsideMarker(outside_marker) => outside_marker.layout( layout_context, @@ -1912,6 +1910,7 @@ impl<'container> PlacementState<'container> { Fragment::Box(box_fragment) => box_fragment, _ => return, }; + let box_fragment = box_fragment.borrow(); // From <https://drafts.csswg.org/css-align-3/#baseline-export>: // > When finding the first/last baseline set of an inline-block, any baselines @@ -1955,6 +1954,7 @@ impl<'container> PlacementState<'container> { // between the marker and the item. For instance the marker should be positioned at // the baseline of list item content and the first line of the item content should // be at least as tall as the marker -- not the entire list item itself. + let fragment = &mut *fragment.borrow_mut(); let is_outside_marker = fragment .base .flags @@ -2049,6 +2049,7 @@ impl<'container> PlacementState<'container> { .expect("Found float fragment without SequentialLayoutState"); let block_offset_from_containing_block_top = self.current_block_direction_position + self.current_margin.solve(); + let box_fragment = &mut *box_fragment.borrow_mut(); sequential_layout_state.place_float_fragment( box_fragment, self.containing_block, diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 6f48ebd9e9d..078b225bac5 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -357,11 +357,7 @@ impl BoxTree { &(&initial_containing_block).into(), ); - let mut root_fragments = independent_layout - .fragments - .into_iter() - .map(ArcRefCell::new) - .collect::<Vec<_>>(); + let mut root_fragments = independent_layout.fragments.into_iter().collect::<Vec<_>>(); // Zero box for `:root { display: none }`, one for the root element otherwise. assert!(root_fragments.len() <= 1); @@ -378,7 +374,7 @@ impl BoxTree { let scrollable_overflow = root_fragments .iter() .fold(PhysicalRect::zero(), |acc, child| { - let child_overflow = child.borrow().scrollable_overflow(); + let child_overflow = child.scrollable_overflow(); // https://drafts.csswg.org/css-overflow/#scrolling-direction // We want to clip scrollable overflow on box-start and inline-start diff --git a/components/layout_2020/fragment_tree/base_fragment.rs b/components/layout_2020/fragment_tree/base_fragment.rs index 05fe784b01d..4c1efaf0677 100644 --- a/components/layout_2020/fragment_tree/base_fragment.rs +++ b/components/layout_2020/fragment_tree/base_fragment.rs @@ -13,7 +13,7 @@ use crate::layout_debug::DebugId; /// This data structure stores fields that are common to all non-base /// Fragment types and should generally be the first member of all /// concrete fragments. -#[derive(Debug, Serialize)] +#[derive(Clone, Debug, Serialize)] pub(crate) struct BaseFragment { /// A tag which identifies the DOM node and pseudo element of this /// Fragment's content. If this fragment isn't related to any DOM diff --git a/components/layout_2020/fragment_tree/box_fragment.rs b/components/layout_2020/fragment_tree/box_fragment.rs index 22767a601f8..7d61e1e6807 100644 --- a/components/layout_2020/fragment_tree/box_fragment.rs +++ b/components/layout_2020/fragment_tree/box_fragment.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use app_units::Au; +use atomic_refcell::AtomicRefCell; use base::print_tree::PrintTree; use serde::Serialize; use servo_arc::Arc as ServoArc; @@ -13,7 +14,6 @@ use style::properties::ComputedValues; use style::Zero; use super::{BaseFragment, BaseFragmentInfo, CollapsedBlockMargins, Fragment}; -use crate::cell::ArcRefCell; use crate::formatting_contexts::Baselines; use crate::fragment_tree::FragmentFlags; use crate::geom::{ @@ -53,7 +53,7 @@ pub(crate) struct BoxFragment { #[serde(skip_serializing)] pub style: ServoArc<ComputedValues>, - pub children: Vec<ArcRefCell<Fragment>>, + pub children: Vec<Fragment>, /// The content rect of this fragment in the parent fragment's content rectangle. This /// does not include padding, border, or margin -- it only includes content. @@ -84,7 +84,8 @@ pub(crate) struct BoxFragment { /// The resolved box insets if this box is `position: sticky`. These are calculated /// during stacking context tree construction because they rely on the size of the /// scroll container. - pub(crate) resolved_sticky_insets: Option<PhysicalSides<AuOrAuto>>, + #[serde(skip_serializing)] + pub(crate) resolved_sticky_insets: AtomicRefCell<Option<PhysicalSides<AuOrAuto>>>, #[serde(skip_serializing)] pub background_mode: BackgroundMode, @@ -115,7 +116,7 @@ impl BoxFragment { BoxFragment { base: base_fragment_info.into(), style, - children: children.into_iter().map(ArcRefCell::new).collect(), + children, content_rect, padding, border, @@ -124,7 +125,7 @@ impl BoxFragment { baselines: Baselines::default(), block_margins_collapsed_with_children, scrollable_overflow_from_children, - resolved_sticky_insets: None, + resolved_sticky_insets: AtomicRefCell::default(), background_mode: BackgroundMode::Normal, detailed_layout_info: None, } @@ -234,7 +235,7 @@ impl BoxFragment { )); for child in &self.children { - child.borrow().print(tree); + child.print(tree); } tree.end_level(); } @@ -278,7 +279,7 @@ impl BoxFragment { "Should not call this method on statically positioned box." ); - if let Some(resolved_sticky_insets) = self.resolved_sticky_insets { + if let Some(resolved_sticky_insets) = *self.resolved_sticky_insets.borrow() { return resolved_sticky_insets; } diff --git a/components/layout_2020/fragment_tree/containing_block.rs b/components/layout_2020/fragment_tree/containing_block.rs index f7bda18f35f..6edd9bb379b 100644 --- a/components/layout_2020/fragment_tree/containing_block.rs +++ b/components/layout_2020/fragment_tree/containing_block.rs @@ -52,7 +52,7 @@ pub(crate) struct ContainingBlockManager<'a, T> { impl<'a, T> ContainingBlockManager<'a, T> { pub(crate) fn get_containing_block_for_fragment(&self, fragment: &Fragment) -> &T { if let Fragment::Box(box_fragment) = fragment { - match box_fragment.style.clone_position() { + match box_fragment.borrow().style.clone_position() { ComputedPosition::Fixed => self.for_absolute_and_fixed_descendants, ComputedPosition::Absolute => self .for_absolute_descendants diff --git a/components/layout_2020/fragment_tree/fragment.rs b/components/layout_2020/fragment_tree/fragment.rs index 69e87df1e11..5c8b86d455b 100644 --- a/components/layout_2020/fragment_tree/fragment.rs +++ b/components/layout_2020/fragment_tree/fragment.rs @@ -23,16 +23,16 @@ use crate::cell::ArcRefCell; use crate::geom::{LogicalSides, PhysicalRect}; use crate::style_ext::ComputedValuesExt; -#[derive(Serialize)] +#[derive(Clone, Serialize)] pub(crate) enum Fragment { - Box(BoxFragment), + Box(ArcRefCell<BoxFragment>), /// Floating content. A floated fragment is very similar to a normal /// [BoxFragment] but it isn't positioned using normal in block flow /// positioning rules (margin collapse, etc). Instead, they are laid /// out by the [crate::flow::float::SequentialLayoutState] of their /// float containing block formatting context. - Float(BoxFragment), - Positioning(PositioningFragment), + Float(ArcRefCell<BoxFragment>), + Positioning(ArcRefCell<PositioningFragment>), /// Absolute and fixed position fragments are hoisted up so that they /// are children of the BoxFragment that establishes their containing /// blocks, so that they can be laid out properly. When this happens @@ -41,9 +41,9 @@ pub(crate) enum Fragment { /// regard to their original tree order during stacking context tree / /// display list construction. AbsoluteOrFixedPositioned(ArcRefCell<HoistedSharedFragment>), - Text(TextFragment), - Image(ImageFragment), - IFrame(IFrameFragment), + Text(ArcRefCell<TextFragment>), + Image(ArcRefCell<ImageFragment>), + IFrame(ArcRefCell<IFrameFragment>), } #[derive(Serialize)] @@ -99,26 +99,26 @@ pub(crate) struct IFrameFragment { } impl Fragment { - pub fn base(&self) -> Option<&BaseFragment> { + pub fn base(&self) -> Option<BaseFragment> { Some(match self { - Fragment::Box(fragment) => &fragment.base, - Fragment::Text(fragment) => &fragment.base, + Fragment::Box(fragment) => fragment.borrow().base.clone(), + Fragment::Text(fragment) => fragment.borrow().base.clone(), Fragment::AbsoluteOrFixedPositioned(_) => return None, - Fragment::Positioning(fragment) => &fragment.base, - Fragment::Image(fragment) => &fragment.base, - Fragment::IFrame(fragment) => &fragment.base, - Fragment::Float(fragment) => &fragment.base, + Fragment::Positioning(fragment) => fragment.borrow().base.clone(), + Fragment::Image(fragment) => fragment.borrow().base.clone(), + Fragment::IFrame(fragment) => fragment.borrow().base.clone(), + Fragment::Float(fragment) => fragment.borrow().base.clone(), }) } - pub(crate) fn content_rect_mut(&mut self) -> Option<&mut PhysicalRect<Au>> { + pub(crate) fn mutate_content_rect(&mut self, callback: impl FnOnce(&mut PhysicalRect<Au>)) { match self { Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => { - Some(&mut box_fragment.content_rect) + callback(&mut box_fragment.borrow_mut().content_rect) }, - Fragment::Positioning(_) | Fragment::AbsoluteOrFixedPositioned(_) => None, - Fragment::Text(text_fragment) => Some(&mut text_fragment.rect), - Fragment::Image(image_fragment) => Some(&mut image_fragment.rect), - Fragment::IFrame(iframe_fragment) => Some(&mut iframe_fragment.rect), + Fragment::Positioning(_) | Fragment::AbsoluteOrFixedPositioned(_) => {}, + Fragment::Text(text_fragment) => callback(&mut text_fragment.borrow_mut().rect), + Fragment::Image(image_fragment) => callback(&mut image_fragment.borrow_mut().rect), + Fragment::IFrame(iframe_fragment) => callback(&mut iframe_fragment.borrow_mut().rect), } } @@ -128,25 +128,26 @@ impl Fragment { pub fn print(&self, tree: &mut PrintTree) { match self { - Fragment::Box(fragment) => fragment.print(tree), + Fragment::Box(fragment) => fragment.borrow().print(tree), Fragment::Float(fragment) => { tree.new_level("Float".to_string()); - fragment.print(tree); + fragment.borrow().print(tree); tree.end_level(); }, Fragment::AbsoluteOrFixedPositioned(_) => { tree.add_item("AbsoluteOrFixedPositioned".to_string()); }, - Fragment::Positioning(fragment) => fragment.print(tree), - Fragment::Text(fragment) => fragment.print(tree), - Fragment::Image(fragment) => fragment.print(tree), - Fragment::IFrame(fragment) => fragment.print(tree), + Fragment::Positioning(fragment) => fragment.borrow().print(tree), + Fragment::Text(fragment) => fragment.borrow().print(tree), + Fragment::Image(fragment) => fragment.borrow().print(tree), + Fragment::IFrame(fragment) => fragment.borrow().print(tree), } } pub fn scrolling_area(&self, containing_block: &PhysicalRect<Au>) -> PhysicalRect<Au> { match self { Fragment::Box(fragment) | Fragment::Float(fragment) => fragment + .borrow() .scrollable_overflow() .translate(containing_block.origin.to_vector()), _ => self.scrollable_overflow(), @@ -156,13 +157,13 @@ impl Fragment { pub fn scrollable_overflow(&self) -> PhysicalRect<Au> { match self { Fragment::Box(fragment) | Fragment::Float(fragment) => { - fragment.scrollable_overflow_for_parent() + fragment.borrow().scrollable_overflow_for_parent() }, Fragment::AbsoluteOrFixedPositioned(_) => PhysicalRect::zero(), - Fragment::Positioning(fragment) => fragment.scrollable_overflow, - Fragment::Text(fragment) => fragment.rect, - Fragment::Image(fragment) => fragment.rect, - Fragment::IFrame(fragment) => fragment.rect, + Fragment::Positioning(fragment) => fragment.borrow().scrollable_overflow, + Fragment::Text(fragment) => fragment.borrow().rect, + Fragment::Image(fragment) => fragment.borrow().rect, + Fragment::IFrame(fragment) => fragment.borrow().rect, } } @@ -179,6 +180,7 @@ impl Fragment { match self { Fragment::Box(fragment) | Fragment::Float(fragment) => { + let fragment = fragment.borrow(); let content_rect = fragment .content_rect .translate(containing_block.origin.to_vector()); @@ -202,15 +204,16 @@ impl Fragment { fragment .children .iter() - .find_map(|child| child.borrow().find(&new_manager, level + 1, process_func)) + .find_map(|child| child.find(&new_manager, level + 1, process_func)) }, Fragment::Positioning(fragment) => { + let fragment = fragment.borrow(); let content_rect = fragment.rect.translate(containing_block.origin.to_vector()); let new_manager = manager.new_for_non_absolute_descendants(&content_rect); fragment .children .iter() - .find_map(|child| child.borrow().find(&new_manager, level + 1, process_func)) + .find_map(|child| child.find(&new_manager, level + 1, process_func)) }, _ => None, } diff --git a/components/layout_2020/fragment_tree/fragment_tree.rs b/components/layout_2020/fragment_tree/fragment_tree.rs index f2a440ecf9b..35718c708b9 100644 --- a/components/layout_2020/fragment_tree/fragment_tree.rs +++ b/components/layout_2020/fragment_tree/fragment_tree.rs @@ -13,7 +13,6 @@ use webrender_api::units; use webrender_traits::display_list::ScrollSensitivity; use super::{ContainingBlockManager, Fragment, Tag}; -use crate::cell::ArcRefCell; use crate::display_list::StackingContext; use crate::flow::CanvasBackground; use crate::geom::PhysicalRect; @@ -28,7 +27,7 @@ pub struct FragmentTree { /// * The first fragment is generated by the root element. /// * There may be additional fragments generated by positioned boxes /// that have the initial containing block. - pub(crate) root_fragments: Vec<ArcRefCell<Fragment>>, + pub(crate) root_fragments: Vec<Fragment>, /// The scrollable overflow rectangle for the entire tree /// <https://drafts.csswg.org/css-overflow/#scrollable> @@ -63,7 +62,7 @@ impl FragmentTree { pub fn print(&self) { let mut print_tree = PrintTree::new("Fragment Tree".to_string()); for fragment in &self.root_fragments { - fragment.borrow().print(&mut print_tree); + fragment.print(&mut print_tree); } } @@ -85,7 +84,7 @@ impl FragmentTree { }; self.root_fragments .iter() - .find_map(|child| child.borrow().find(&info, 0, &mut process_func)) + .find_map(|child| child.find(&info, 0, &mut process_func)) } pub fn remove_nodes_in_fragment_tree_from_set(&self, set: &mut FxHashSet<AnimationSetKey>) { @@ -110,9 +109,11 @@ impl FragmentTree { } let fragment_relative_rect = match fragment { - Fragment::Box(fragment) | Fragment::Float(fragment) => fragment.border_rect(), - Fragment::Positioning(fragment) => fragment.rect, - Fragment::Text(fragment) => fragment.rect, + Fragment::Box(fragment) | Fragment::Float(fragment) => { + fragment.borrow().border_rect() + }, + Fragment::Positioning(fragment) => fragment.borrow().rect, + Fragment::Text(fragment) => fragment.borrow().rect, Fragment::AbsoluteOrFixedPositioned(_) | Fragment::Image(_) | Fragment::IFrame(_) => return None, @@ -140,6 +141,7 @@ impl FragmentTree { // CSS layout box is inline, return zero." For this check we // also explicitly ignore the list item portion of the display // style. + let fragment = fragment.borrow(); if fragment.is_inline_box() { return Some(Rect::zero()); } @@ -151,7 +153,7 @@ impl FragmentTree { Size2D::new(padding_rect.size.width, padding_rect.size.height), ) }, - Fragment::Positioning(fragment) => fragment.rect.cast_unit(), + Fragment::Positioning(fragment) => fragment.borrow().rect.cast_unit(), _ => return None, }; @@ -168,7 +170,6 @@ impl FragmentTree { let mut scroll_area = self.initial_containing_block; for fragment in self.root_fragments.iter() { scroll_area = fragment - .borrow() .scrolling_area(&self.initial_containing_block) .union(&scroll_area); } diff --git a/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs b/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs index d54c76b30d0..0b67d981d34 100644 --- a/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs +++ b/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs @@ -8,7 +8,6 @@ use style::logical_geometry::WritingMode; use style::values::specified::align::AlignFlags; use super::Fragment; -use crate::cell::ArcRefCell; use crate::geom::{LogicalVec2, PhysicalRect, PhysicalVec}; /// A reference to a Fragment which is shared between `HoistedAbsolutelyPositionedBox` @@ -16,7 +15,7 @@ use crate::geom::{LogicalVec2, PhysicalRect, PhysicalVec}; /// This will be used later in order to paint this hoisted box in tree order. #[derive(Serialize)] pub(crate) struct HoistedSharedFragment { - pub fragment: Option<ArcRefCell<Fragment>>, + pub fragment: Option<Fragment>, /// The "static-position rect" of this absolutely positioned box. This is defined by the /// layout mode from which the box originates. /// diff --git a/components/layout_2020/fragment_tree/positioning_fragment.rs b/components/layout_2020/fragment_tree/positioning_fragment.rs index 3d2238f748e..36b51aa3d2a 100644 --- a/components/layout_2020/fragment_tree/positioning_fragment.rs +++ b/components/layout_2020/fragment_tree/positioning_fragment.rs @@ -19,7 +19,7 @@ use crate::geom::PhysicalRect; pub(crate) struct PositioningFragment { pub base: BaseFragment, pub rect: PhysicalRect<Au>, - pub children: Vec<ArcRefCell<Fragment>>, + pub children: Vec<Fragment>, /// The scrollable overflow of this anonymous fragment's children. pub scrollable_overflow: PhysicalRect<Au>, @@ -29,7 +29,7 @@ pub(crate) struct PositioningFragment { } impl PositioningFragment { - pub fn new_anonymous(rect: PhysicalRect<Au>, children: Vec<Fragment>) -> Self { + pub fn new_anonymous(rect: PhysicalRect<Au>, children: Vec<Fragment>) -> ArcRefCell<Self> { Self::new_with_base_fragment(BaseFragment::anonymous(), None, rect, children) } @@ -37,7 +37,7 @@ impl PositioningFragment { base_fragment_info: BaseFragmentInfo, rect: PhysicalRect<Au>, style: ServoArc<ComputedValues>, - ) -> Self { + ) -> ArcRefCell<Self> { Self::new_with_base_fragment(base_fragment_info.into(), Some(style), rect, Vec::new()) } @@ -46,7 +46,7 @@ impl PositioningFragment { style: Option<ServoArc<ComputedValues>>, rect: PhysicalRect<Au>, children: Vec<Fragment>, - ) -> Self { + ) -> ArcRefCell<Self> { let content_origin = rect.origin; let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| { acc.union( @@ -55,13 +55,13 @@ impl PositioningFragment { .translate(content_origin.to_vector()), ) }); - PositioningFragment { + ArcRefCell::new(PositioningFragment { base, style, rect, - children: children.into_iter().map(ArcRefCell::new).collect(), + children, scrollable_overflow, - } + }) } pub fn print(&self, tree: &mut PrintTree) { @@ -74,7 +74,7 @@ impl PositioningFragment { )); for child in &self.children { - child.borrow().print(tree); + child.print(tree); } tree.end_level(); } diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index a3790aefa9d..5a88cc740ec 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -161,9 +161,11 @@ impl PositioningContext { index: PositioningContextLength, ) { let start_offset = match &parent_fragment { - Fragment::Box(fragment) | Fragment::Float(fragment) => &fragment.content_rect.origin, + Fragment::Box(fragment) | Fragment::Float(fragment) => { + fragment.borrow().content_rect.origin + }, Fragment::AbsoluteOrFixedPositioned(_) => return, - Fragment::Positioning(fragment) => &fragment.rect.origin, + Fragment::Positioning(fragment) => fragment.borrow().rect.origin, _ => unreachable!(), }; self.adjust_static_position_of_hoisted_fragments_with_offset( @@ -335,7 +337,7 @@ impl PositioningContext { &mut self, layout_context: &LayoutContext, initial_containing_block: &DefiniteContainingBlock, - fragments: &mut Vec<ArcRefCell<Fragment>>, + fragments: &mut Vec<Fragment>, ) { debug_assert!(self.for_nearest_positioned_ancestor.is_none()); @@ -409,7 +411,7 @@ impl HoistedAbsolutelyPositionedBox { pub(crate) fn layout_many( layout_context: &LayoutContext, boxes: &mut [Self], - fragments: &mut Vec<ArcRefCell<Fragment>>, + fragments: &mut Vec<Fragment>, for_nearest_containing_block_for_all_descendants: &mut Vec<HoistedAbsolutelyPositionedBox>, containing_block: &DefiniteContainingBlock, ) { @@ -421,14 +423,15 @@ impl HoistedAbsolutelyPositionedBox { .par_iter_mut() .map(|hoisted_box| { let mut new_hoisted_boxes: Vec<HoistedAbsolutelyPositionedBox> = Vec::new(); - let new_fragment = ArcRefCell::new(Fragment::Box(hoisted_box.layout( + let new_fragment = hoisted_box.layout( layout_context, &mut new_hoisted_boxes, containing_block, - ))); + ); - hoisted_box.fragment.borrow_mut().fragment = Some(new_fragment.clone()); - (new_fragment, new_hoisted_boxes) + hoisted_box.fragment.borrow_mut().fragment = + Some(Fragment::Box(new_fragment.clone())); + (Fragment::Box(new_fragment), new_hoisted_boxes) }) .unzip_into_vecs(&mut new_fragments, &mut new_hoisted_boxes); @@ -437,13 +440,14 @@ impl HoistedAbsolutelyPositionedBox { .extend(new_hoisted_boxes.into_iter().flatten()); } else { fragments.extend(boxes.iter_mut().map(|box_| { - let new_fragment = ArcRefCell::new(Fragment::Box(box_.layout( + let new_fragment = box_.layout( layout_context, for_nearest_containing_block_for_all_descendants, containing_block, - ))); - box_.fragment.borrow_mut().fragment = Some(new_fragment.clone()); - new_fragment + ); + + box_.fragment.borrow_mut().fragment = Some(Fragment::Box(new_fragment.clone())); + Fragment::Box(new_fragment) })) } } @@ -453,7 +457,7 @@ impl HoistedAbsolutelyPositionedBox { layout_context: &LayoutContext, for_nearest_containing_block_for_all_descendants: &mut Vec<HoistedAbsolutelyPositionedBox>, containing_block: &DefiniteContainingBlock, - ) -> BoxFragment { + ) -> ArcRefCell<BoxFragment> { let cbis = containing_block.size.inline; let cbbs = containing_block.size.block; let containing_block_writing_mode = containing_block.style.writing_mode; @@ -696,7 +700,7 @@ impl HoistedAbsolutelyPositionedBox { for_nearest_containing_block_for_all_descendants .extend(positioning_context.for_nearest_containing_block_for_all_descendants); - new_fragment + ArcRefCell::new(new_fragment) } } diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs index f0d5ef017df..a75f7fd81c2 100644 --- a/components/layout_2020/query.rs +++ b/components/layout_2020/query.rs @@ -192,6 +192,7 @@ pub fn process_resolved_style_request<'dom>( let (content_rect, margins, padding, detailed_layout_info) = match fragment { Fragment::Box(ref box_fragment) | Fragment::Float(ref box_fragment) => { + let box_fragment = box_fragment.borrow(); if style.get_box().position != Position::Static { let resolved_insets = || { box_fragment.calculate_resolved_insets_if_positioned(containing_block) @@ -213,16 +214,16 @@ pub fn process_resolved_style_request<'dom>( let content_rect = box_fragment.content_rect; let margins = box_fragment.margin; let padding = box_fragment.padding; - let detailed_layout_info = &box_fragment.detailed_layout_info; + let detailed_layout_info = box_fragment.detailed_layout_info.clone(); (content_rect, margins, padding, detailed_layout_info) }, Fragment::Positioning(positioning_fragment) => { - let content_rect = positioning_fragment.rect; + let content_rect = positioning_fragment.borrow().rect; ( content_rect, SideOffsets2D::zero(), SideOffsets2D::zero(), - &None, + None, ) }, _ => return None, @@ -235,7 +236,7 @@ pub fn process_resolved_style_request<'dom>( // > When an element generates a grid container box... if display.inside() == DisplayInside::Grid { if let Some(SpecificLayoutInfo::Grid(info)) = detailed_layout_info { - if let Some(value) = resolve_grid_template(info, style, longhand_id) { + if let Some(value) = resolve_grid_template(&info, style, longhand_id) { return Some(value); } } @@ -274,7 +275,7 @@ fn resolved_size_should_be_used_value(fragment: &Fragment) -> bool { // https://drafts.csswg.org/css-sizing-3/#preferred-size-properties // > Applies to: all elements except non-replaced inlines match fragment { - Fragment::Box(box_fragment) => !box_fragment.is_inline_box(), + Fragment::Box(box_fragment) => !box_fragment.borrow().is_inline_box(), Fragment::Float(_) | Fragment::Positioning(_) | Fragment::AbsoluteOrFixedPositioned(_) | @@ -446,9 +447,9 @@ fn process_offset_parent_query_inner( // // [1]: https://github.com/w3c/csswg-drafts/issues/4541 let fragment_relative_rect = match fragment { - Fragment::Box(fragment) | Fragment::Float(fragment) => fragment.border_rect(), - Fragment::Text(fragment) => fragment.rect, - Fragment::Positioning(fragment) => fragment.rect, + Fragment::Box(fragment) | Fragment::Float(fragment) => fragment.borrow().border_rect(), + Fragment::Text(fragment) => fragment.borrow().rect, + Fragment::Positioning(fragment) => fragment.borrow().rect, Fragment::AbsoluteOrFixedPositioned(_) | Fragment::Image(_) | Fragment::IFrame(_) => unreachable!(), @@ -460,7 +461,7 @@ fn process_offset_parent_query_inner( // this algorithm: [...] The element’s computed value of the // `position` property is `fixed`." let is_fixed = matches!( - fragment, Fragment::Box(fragment) if fragment.style.get_box().position == Position::Fixed + fragment, Fragment::Box(fragment) if fragment.borrow().style.get_box().position == Position::Fixed ); if is_body_element { @@ -489,6 +490,7 @@ fn process_offset_parent_query_inner( // Record the paths of the nodes being traversed. let parent_node_address = match fragment { Fragment::Box(fragment) | Fragment::Float(fragment) => { + let fragment = &*fragment.borrow(); let is_eligible_parent = is_eligible_parent(fragment); let is_static_body_element = is_body_element && fragment.style.get_box().position == Position::Static; @@ -538,14 +540,15 @@ fn process_offset_parent_query_inner( unreachable!(); }; // Again, take the *first* associated CSS layout box. - fragment.border_rect().origin.to_vector() + containing_block.origin.to_vector() + fragment.borrow().border_rect().origin.to_vector() + + containing_block.origin.to_vector() } let containing_block = &fragment_tree.initial_containing_block; - let fragment = &(*fragment_tree.root_fragments[0].borrow()); + let fragment = &fragment_tree.root_fragments[0]; if let Fragment::AbsoluteOrFixedPositioned(shared_fragment) = fragment { let shared_fragment = &*shared_fragment.borrow(); - let fragment = &*shared_fragment.fragment.as_ref().unwrap().borrow(); + let fragment = shared_fragment.fragment.as_ref().unwrap(); extract_box_fragment(fragment, containing_block) } else { extract_box_fragment(fragment, containing_block) @@ -561,6 +564,7 @@ fn process_offset_parent_query_inner( .find(|fragment, _, containing_block| { match fragment { Fragment::Box(fragment) | Fragment::Float(fragment) => { + let fragment = fragment.borrow(); if fragment.base.tag == Some(offset_parent_node_tag) { // Again, take the *first* associated CSS layout box. let padding_box_corner = fragment.padding_rect().origin.to_vector() diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs index df845841438..391cd34c22a 100644 --- a/components/layout_2020/replaced.rs +++ b/components/layout_2020/replaced.rs @@ -27,6 +27,7 @@ use style::Zero; use url::Url; use webrender_api::ImageKey; +use crate::cell::ArcRefCell; use crate::context::LayoutContext; use crate::dom::NodeExt; use crate::fragment_tree::{BaseFragmentInfo, Fragment, IFrameFragment, ImageFragment}; @@ -334,23 +335,25 @@ impl ReplacedContents { .as_ref() .and_then(|image| image.id) .map(|image_key| { - Fragment::Image(ImageFragment { + Fragment::Image(ArcRefCell::new(ImageFragment { base: self.base_fragment_info.into(), style: style.clone(), rect, clip, image_key: Some(image_key), - }) + })) }) .into_iter() .collect(), - ReplacedContentKind::Video(video) => vec![Fragment::Image(ImageFragment { - base: self.base_fragment_info.into(), - style: style.clone(), - rect, - clip, - image_key: video.as_ref().map(|video| video.image_key), - })], + ReplacedContentKind::Video(video) => { + vec![Fragment::Image(ArcRefCell::new(ImageFragment { + base: self.base_fragment_info.into(), + style: style.clone(), + rect, + clip, + image_key: video.as_ref().map(|video| video.image_key), + }))] + }, ReplacedContentKind::IFrame(iframe) => { let size = Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px()); layout_context.iframe_sizes.lock().insert( @@ -361,13 +364,13 @@ impl ReplacedContents { size, }, ); - vec![Fragment::IFrame(IFrameFragment { + vec![Fragment::IFrame(ArcRefCell::new(IFrameFragment { base: self.base_fragment_info.into(), style: style.clone(), pipeline_id: iframe.pipeline_id, browsing_context_id: iframe.browsing_context_id, rect, - })] + }))] }, ReplacedContentKind::Canvas(canvas_info) => { if self.natural_size.width == Some(Au::zero()) || @@ -392,13 +395,13 @@ impl ReplacedContents { }, CanvasSource::Empty => return vec![], }; - vec![Fragment::Image(ImageFragment { + vec![Fragment::Image(ArcRefCell::new(ImageFragment { base: self.base_fragment_info.into(), style: style.clone(), rect, clip, image_key: Some(image_key), - })] + }))] }, } } diff --git a/components/layout_2020/table/layout.rs b/components/layout_2020/table/layout.rs index a405dd5bae4..09ff5298f67 100644 --- a/components/layout_2020/table/layout.rs +++ b/components/layout_2020/table/layout.rs @@ -24,7 +24,9 @@ use style::values::generics::box_::{GenericVerticalAlign as VerticalAlign, Verti use style::values::generics::length::GenericLengthPercentageOrAuto::{Auto, LengthPercentage}; use style::Zero; -use super::{Table, TableCaption, TableSlot, TableSlotCell, TableTrack, TableTrackGroup}; +use super::{ + ArcRefCell, Table, TableCaption, TableSlot, TableSlotCell, TableTrack, TableTrackGroup, +}; use crate::context::LayoutContext; use crate::formatting_contexts::{Baselines, IndependentLayout}; use crate::fragment_tree::{ @@ -1740,7 +1742,7 @@ impl<'a> TableLayout<'a> { .to_logical(table_writing_mode) .block; - let caption_fragment = Fragment::Box(caption_fragment); + let caption_fragment = Fragment::Box(ArcRefCell::new(caption_fragment)); positioning_context.adjust_static_position_of_hoisted_fragments( &caption_fragment, original_positioning_context_length, @@ -1790,7 +1792,7 @@ impl<'a> TableLayout<'a> { .block; table_layout.content_inline_size_for_table = Some(logical_grid_content_rect.size.inline); - let grid_fragment = Fragment::Box(grid_fragment); + let grid_fragment = Fragment::Box(ArcRefCell::new(grid_fragment)); positioning_context.adjust_static_position_of_hoisted_fragments( &grid_fragment, original_positioning_context_length, @@ -1831,7 +1833,7 @@ impl<'a> TableLayout<'a> { .to_logical(table_writing_mode) .block; - let caption_fragment = Fragment::Box(caption_fragment); + let caption_fragment = Fragment::Box(ArcRefCell::new(caption_fragment)); positioning_context.adjust_static_position_of_hoisted_fragments( &caption_fragment, original_positioning_context_length, @@ -2182,7 +2184,9 @@ impl<'a> TableLayout<'a> { rect, }) } - row_fragment_layout.fragments.push(Fragment::Box(fragment)); + row_fragment_layout + .fragments + .push(Fragment::Box(ArcRefCell::new(fragment))); } fn make_fragments_for_columns_and_column_groups( @@ -2345,7 +2349,7 @@ impl<'a> RowFragmentLayout<'a> { containing_block_for_logical_conversion: &ContainingBlock, containing_block_for_children: &ContainingBlock, row_group_fragment_layout: &mut Option<RowGroupFragmentLayout>, - ) -> BoxFragment { + ) -> ArcRefCell<BoxFragment> { if self.positioning_context.is_some() { self.rect.start_corner += relative_adjustement(&self.row.style, containing_block_for_children); @@ -2396,7 +2400,7 @@ impl<'a> RowFragmentLayout<'a> { positioning_context.append(row_positioning_context); } - row_fragment + ArcRefCell::new(row_fragment) } } @@ -2432,7 +2436,7 @@ impl RowGroupFragmentLayout { table_positioning_context: &mut PositioningContext, containing_block_for_logical_conversion: &ContainingBlock, containing_block_for_children: &ContainingBlock, - ) -> BoxFragment { + ) -> ArcRefCell<BoxFragment> { if self.positioning_context.is_some() { self.rect.start_corner += relative_adjustement(&self.style, containing_block_for_children); @@ -2458,7 +2462,7 @@ impl RowGroupFragmentLayout { table_positioning_context.append(row_positioning_context); } - row_group_fragment + ArcRefCell::new(row_group_fragment) } } diff --git a/components/layout_2020/taffy/layout.rs b/components/layout_2020/taffy/layout.rs index 73851992ed4..e9d86abcda6 100644 --- a/components/layout_2020/taffy/layout.rs +++ b/components/layout_2020/taffy/layout.rs @@ -551,7 +551,7 @@ impl TaffyContainer { match &mut child.taffy_level_box { TaffyItemBoxInner::InFlowBox(independent_box) => { - let fragment = Fragment::Box( + let fragment = Fragment::Box(ArcRefCell::new( BoxFragment::new( independent_box.base_fragment_info(), independent_box.style().clone(), @@ -568,7 +568,7 @@ impl TaffyContainer { last: None, }) .with_detailed_layout_info(child_detailed_layout_info), - ); + )); child .positioning_context |