mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
layout: Simplify PositioningContext
by having it hold a single Vec
(#36795)
`PositioningContext` held two vectors, one inside an `Option`, to differentiate between the version used for a containing block for all descendants (including `position: absolute` and `position: fixed`) or only for `position: absolute` descendants. This distinction was really hard to reason about and required a lot of bookkeeping about what kind of `PositioningContext` a layout box's parent expected. In addition, it led to a lot of mistakes. This change simplifies things so that `PositioningContext` only holds a single vector. When it comes time to lay out hoisted absolutely positioned fragments, the code then: - lays out all of them (in the case of a `PositioningContext` for all descendants), or - only lays out the `position: absolute` descendants and preserves the `position: fixed` descendants (in the case the `PositioningContext` is only for `position: absolute`.), or - lays out none of them if the `PositioningContext` was created for box that did not establish a containing block for absolutes. It's possible that this way of dealing with hoisted absolutes is a bit less efficient, but, the number of these descendants is typically quite small, so it should not be significant. In addition, this decreases the size in memory of all `PositioningContexts` which are created in more situations as time goes on. Testing: There is a new WPT test with this change. Fixes: #36696. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
e25e63b587
commit
9bc16482a3
12 changed files with 203 additions and 323 deletions
|
@ -29,7 +29,7 @@ use crate::geom::{
|
|||
use crate::layout_box_base::CacheableLayoutResult;
|
||||
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
|
||||
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
|
||||
use crate::style_ext::{ComputedValuesExt, LayoutStyle};
|
||||
use crate::style_ext::LayoutStyle;
|
||||
use crate::{ConstraintSpace, ContainingBlock, ContainingBlockSize};
|
||||
|
||||
const DUMMY_NODE_ID: taffy::NodeId = taffy::NodeId::new(u64::MAX);
|
||||
|
@ -250,29 +250,15 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
|
|||
},
|
||||
style,
|
||||
};
|
||||
let layout = {
|
||||
let mut child_positioning_context = independent_context
|
||||
.new_positioning_context()
|
||||
.unwrap_or_else(|| {
|
||||
PositioningContext::new_for_subtree(
|
||||
self.positioning_context
|
||||
.collects_for_nearest_positioned_ancestor(),
|
||||
)
|
||||
});
|
||||
|
||||
let layout = non_replaced.layout_without_caching(
|
||||
self.layout_context,
|
||||
&mut child_positioning_context,
|
||||
&content_box_size_override,
|
||||
containing_block,
|
||||
false, /* depends_on_block_constraints */
|
||||
);
|
||||
|
||||
// Store layout data on child for later access
|
||||
child.positioning_context = child_positioning_context;
|
||||
|
||||
layout
|
||||
};
|
||||
child.positioning_context = PositioningContext::default();
|
||||
let layout = non_replaced.layout_without_caching(
|
||||
self.layout_context,
|
||||
&mut child.positioning_context,
|
||||
&content_box_size_override,
|
||||
containing_block,
|
||||
false, /* depends_on_block_constraints */
|
||||
);
|
||||
|
||||
child.child_fragments = layout.fragments;
|
||||
self.child_specific_layout_infos[usize::from(node_id)] =
|
||||
|
@ -373,8 +359,7 @@ impl ComputeInlineContentSizes for TaffyContainer {
|
|||
|
||||
let mut grid_context = TaffyContainerContext {
|
||||
layout_context,
|
||||
positioning_context:
|
||||
&mut PositioningContext::new_for_containing_block_for_all_descendants(),
|
||||
positioning_context: &mut PositioningContext::default(),
|
||||
content_box_size_override: containing_block,
|
||||
style,
|
||||
source_child_nodes: &self.children,
|
||||
|
@ -540,17 +525,6 @@ impl TaffyContainer {
|
|||
let child_specific_layout_info: Option<SpecificLayoutInfo> =
|
||||
std::mem::take(&mut container_ctx.child_specific_layout_infos[child_id]);
|
||||
|
||||
let establishes_containing_block_for_absolute_descendants =
|
||||
if let TaffyItemBoxInner::InFlowBox(independent_box) = &child.taffy_level_box {
|
||||
child
|
||||
.style
|
||||
.establishes_containing_block_for_absolute_descendants(
|
||||
independent_box.base_fragment_info().flags,
|
||||
)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
let fragment = match &mut child.taffy_level_box {
|
||||
TaffyItemBoxInner::InFlowBox(independent_box) => {
|
||||
let mut fragment_info = independent_box.base_fragment_info();
|
||||
|
@ -573,29 +547,21 @@ impl TaffyContainer {
|
|||
})
|
||||
.with_specific_layout_info(child_specific_layout_info);
|
||||
|
||||
if establishes_containing_block_for_absolute_descendants {
|
||||
child.positioning_context.layout_collected_children(
|
||||
container_ctx.layout_context,
|
||||
&mut box_fragment,
|
||||
);
|
||||
}
|
||||
|
||||
let fragment = Fragment::Box(ArcRefCell::new(box_fragment));
|
||||
|
||||
child.positioning_context.layout_collected_children(
|
||||
container_ctx.layout_context,
|
||||
&mut box_fragment,
|
||||
);
|
||||
child
|
||||
.positioning_context
|
||||
.adjust_static_position_of_hoisted_fragments(
|
||||
&fragment,
|
||||
.adjust_static_position_of_hoisted_fragments_with_offset(
|
||||
&box_fragment.content_rect.origin.to_vector(),
|
||||
PositioningContextLength::zero(),
|
||||
);
|
||||
let child_positioning_context = std::mem::replace(
|
||||
&mut child.positioning_context,
|
||||
PositioningContext::new_for_containing_block_for_all_descendants(),
|
||||
);
|
||||
container_ctx
|
||||
.positioning_context
|
||||
.append(child_positioning_context);
|
||||
fragment
|
||||
.append(std::mem::take(&mut child.positioning_context));
|
||||
|
||||
Fragment::Box(ArcRefCell::new(box_fragment))
|
||||
},
|
||||
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(abs_pos_box) => {
|
||||
fn resolve_alignment(value: AlignFlags, auto: AlignFlags) -> AlignFlags {
|
||||
|
|
|
@ -110,7 +110,7 @@ impl TaffyItemBox {
|
|||
Self {
|
||||
taffy_layout: Default::default(),
|
||||
child_fragments: Vec::new(),
|
||||
positioning_context: PositioningContext::new_for_containing_block_for_all_descendants(),
|
||||
positioning_context: PositioningContext::default(),
|
||||
style,
|
||||
taffy_level_box: inner,
|
||||
}
|
||||
|
@ -118,8 +118,7 @@ impl TaffyItemBox {
|
|||
|
||||
pub(crate) fn invalidate_cached_fragment(&mut self) {
|
||||
self.taffy_layout = Default::default();
|
||||
self.positioning_context =
|
||||
PositioningContext::new_for_containing_block_for_all_descendants();
|
||||
self.positioning_context = PositioningContext::default();
|
||||
match self.taffy_level_box {
|
||||
TaffyItemBoxInner::InFlowBox(ref independent_formatting_context) => {
|
||||
independent_formatting_context
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue