aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout_2020/flow/root.rs
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2023-05-15 10:35:45 +0200
committerMartin Robinson <mrobinson@igalia.com>2023-05-17 10:46:27 +0200
commitb60e105526705f941b2b9df4e12eaabbe2621802 (patch)
tree48f98019a5ec3984c9ec79d6c4e0caaedb17f094 /components/layout_2020/flow/root.rs
parentc5d31c3ab6ad4c633869ef4c4d32cd01c480661f (diff)
downloadservo-b60e105526705f941b2b9df4e12eaabbe2621802.tar.gz
servo-b60e105526705f941b2b9df4e12eaabbe2621802.zip
Refactor Layout 2020 layout for a compositor-side scroll tree
This change refactors how layout is done in Layout 2020 in preparation for a compositor-side scroll tree: 1. Now the SpatialId and ClipId of each fragment is stored separately. This will allow storing a scroll node id instead of only the handle to the WebRender spatial node. 2. Separate out stacking context tree construction and display list building. This change will make it possible to eventually build the stacking context tree without the full display list if we find that necessary. For instance, this might be useful to cache containing block boundaries. 3. Add a `DisplayList` struct that stores both the WebRender display list builder and the compositor info. This exposes the API to the layout thread for display list building. In addition, this change adds a lot of missing documentation. This should not change behavior.
Diffstat (limited to 'components/layout_2020/flow/root.rs')
-rw-r--r--components/layout_2020/flow/root.rs61
1 files changed, 9 insertions, 52 deletions
diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs
index f44b0c88159..5006b65a48b 100644
--- a/components/layout_2020/flow/root.rs
+++ b/components/layout_2020/flow/root.rs
@@ -4,9 +4,7 @@
use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
-use crate::display_list::stacking_context::{
- ContainingBlock, ContainingBlockInfo, StackingContext, StackingContextBuildMode,
-};
+use crate::display_list::StackingContext;
use crate::dom::{LayoutBox, NodeExt};
use crate::dom_traversal::{iter_child_nodes, Contents, NodeAndStyleInfo};
use crate::flexbox::FlexLevelBox;
@@ -38,7 +36,6 @@ use style::dom::OpaqueNode;
use style::properties::ComputedValues;
use style::values::computed::Length;
use style_traits::CSSPixel;
-use webrender_api::{ClipId, SpaceAndClipInfo, SpatialId};
#[derive(Serialize)]
pub struct BoxTree {
@@ -60,7 +57,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.
- root_fragments: Vec<ArcRefCell<Fragment>>,
+ pub(crate) root_fragments: Vec<ArcRefCell<Fragment>>,
/// The scrollable overflow rectangle for the entire tree
/// https://drafts.csswg.org/css-overflow/#scrollable
@@ -384,58 +381,18 @@ impl BoxTree {
}
impl FragmentTree {
- pub fn build_display_list(&self, builder: &mut crate::display_list::DisplayListBuilder) {
- let stacking_context = self.build_stacking_context_tree(builder);
-
+ pub(crate) fn build_display_list(
+ &self,
+ builder: &mut crate::display_list::DisplayListBuilder,
+ root_stacking_context: &StackingContext,
+ ) {
// Paint the canvas’ background (if any) before/under everything else
- stacking_context.build_canvas_background_display_list(
+ root_stacking_context.build_canvas_background_display_list(
builder,
self,
&self.initial_containing_block,
);
-
- stacking_context.build_display_list(builder);
- }
-
- fn build_stacking_context_tree(
- &self,
- builder: &mut crate::display_list::DisplayListBuilder,
- ) -> StackingContext {
- let mut stacking_context = StackingContext::create_root(&builder.wr);
- let pipeline_id = builder.wr.pipeline_id;
- let cb_for_non_fixed_descendants = ContainingBlock::new(
- &self.initial_containing_block,
- SpaceAndClipInfo::root_scroll(pipeline_id),
- );
- let cb_for_fixed_descendants = ContainingBlock::new(
- &self.initial_containing_block,
- SpaceAndClipInfo {
- spatial_id: SpatialId::root_reference_frame(pipeline_id),
- clip_id: ClipId::root(pipeline_id),
- },
- );
-
- for fragment in &self.root_fragments {
- fragment.borrow().build_stacking_context_tree(
- fragment,
- &mut builder.wr,
- // We need to specify all three containing blocks here, because absolute
- // descdendants of the root cannot share the containing block we specify
- // for fixed descendants. In this case, they need to have the spatial
- // id of the root scroll frame, whereas fixed descendants need the
- // spatial id of the root reference frame so that they do not scroll with
- // page content.
- &ContainingBlockInfo {
- for_non_absolute_descendants: &cb_for_non_fixed_descendants,
- for_absolute_descendants: Some(&cb_for_non_fixed_descendants),
- for_absolute_and_fixed_descendants: &cb_for_fixed_descendants,
- },
- &mut stacking_context,
- StackingContextBuildMode::SkipHoisted,
- );
- }
- stacking_context.sort();
- stacking_context
+ root_stacking_context.build_display_list(builder);
}
pub fn print(&self) {