mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Use the WebRender clip chain API
The old clipping API has been removed from WebRender, so this switches both legacy and new layout over to use the clip chain API in preparation for the WebRender upgrade.
This commit is contained in:
parent
66abb1dfc4
commit
3c4328f3dc
4 changed files with 165 additions and 114 deletions
|
@ -2616,6 +2616,8 @@ impl BlockFlow {
|
|||
clip: ClippingRegion::from_rect(border_box.to_layout()),
|
||||
content_rect: LayoutRect::zero(),
|
||||
node_type: ClipScrollNodeType::StickyFrame(sticky_frame_data),
|
||||
scroll_node_id: None,
|
||||
clip_chain_id: None,
|
||||
});
|
||||
|
||||
let new_clipping_and_scrolling = ClippingAndScrolling::simple(new_clip_scroll_index);
|
||||
|
@ -2683,6 +2685,8 @@ impl BlockFlow {
|
|||
clip: clip,
|
||||
content_rect: Rect::new(content_box.origin, content_size).to_layout(),
|
||||
node_type: ClipScrollNodeType::ScrollFrame(sensitivity, external_id),
|
||||
scroll_node_id: None,
|
||||
clip_chain_id: None,
|
||||
});
|
||||
|
||||
let new_clipping_and_scrolling = ClippingAndScrolling::simple(new_clip_scroll_index);
|
||||
|
@ -2719,6 +2723,8 @@ impl BlockFlow {
|
|||
clip: ClippingRegion::from_rect(clip_rect.to_layout()),
|
||||
content_rect: LayoutRect::zero(), // content_rect isn't important for clips.
|
||||
node_type: ClipScrollNodeType::Clip(ClipType::Rect),
|
||||
scroll_node_id: None,
|
||||
clip_chain_id: None,
|
||||
});
|
||||
|
||||
let new_indices = ClippingAndScrolling::new(new_index, new_index);
|
||||
|
|
|
@ -18,6 +18,7 @@ use gfx_traits::print_tree::PrintTree;
|
|||
use gfx_traits::{self, StackingContextId};
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::image::base::Image;
|
||||
use script_traits::compositor::ScrollTreeNodeId;
|
||||
use servo_geometry::MaxRect;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::HashMap;
|
||||
|
@ -31,6 +32,7 @@ use webrender_api::{
|
|||
FilterOp, GlyphInstance, GradientStop, ImageKey, MixBlendMode, PrimitiveFlags,
|
||||
ScrollSensitivity, Shadow, SpatialId, StickyOffsetBounds, TransformStyle,
|
||||
};
|
||||
use wr::ClipChainId;
|
||||
|
||||
pub use style::dom::OpaqueNode;
|
||||
|
||||
|
@ -369,6 +371,12 @@ pub struct ClipScrollNode {
|
|||
|
||||
/// The type of this ClipScrollNode.
|
||||
pub node_type: ClipScrollNodeType,
|
||||
|
||||
/// The WebRender spatial id of this node assigned during WebRender conversion.
|
||||
pub scroll_node_id: Option<ScrollTreeNodeId>,
|
||||
|
||||
/// The WebRender clip id of this node assigned during WebRender conversion.
|
||||
pub clip_chain_id: Option<ClipChainId>,
|
||||
}
|
||||
|
||||
impl ClipScrollNode {
|
||||
|
@ -378,6 +386,8 @@ impl ClipScrollNode {
|
|||
clip: ClippingRegion::from_rect(LayoutRect::zero()),
|
||||
content_rect: LayoutRect::zero(),
|
||||
node_type: ClipScrollNodeType::Placeholder,
|
||||
scroll_node_id: None,
|
||||
clip_chain_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,6 +410,8 @@ impl ClipScrollNode {
|
|||
clip: ClippingRegion::from_rect(clip_rect),
|
||||
content_rect: LayoutRect::zero(), // content_rect isn't important for clips.
|
||||
node_type: ClipScrollNodeType::Clip(ClipType::Rounded(complex_region)),
|
||||
scroll_node_id: None,
|
||||
clip_chain_id: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,22 +13,24 @@ use msg::constellation_msg::PipelineId;
|
|||
use script_traits::compositor::{CompositorDisplayListInfo, ScrollTreeNodeId, ScrollableNodeInfo};
|
||||
use webrender_api::units::{LayoutPoint, LayoutSize, LayoutVector2D};
|
||||
use webrender_api::{
|
||||
self, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem, DisplayListBuilder, Epoch,
|
||||
PrimitiveFlags, PropertyBinding, PushStackingContextDisplayItem, RasterSpace,
|
||||
ReferenceFrameKind, SpaceAndClipInfo, SpatialId, StackingContext,
|
||||
self, ClipChainId, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem,
|
||||
DisplayListBuilder, Epoch, PrimitiveFlags, PropertyBinding, PushStackingContextDisplayItem,
|
||||
RasterSpace, ReferenceFrameKind, SpaceAndClipInfo, SpatialId, StackingContext,
|
||||
};
|
||||
|
||||
struct ClipScrollState {
|
||||
clip_ids: Vec<Option<ClipId>>,
|
||||
scroll_node_ids: Vec<Option<ScrollTreeNodeId>>,
|
||||
struct ClipScrollState<'a> {
|
||||
clip_scroll_nodes: &'a mut Vec<ClipScrollNode>,
|
||||
compositor_info: CompositorDisplayListInfo,
|
||||
}
|
||||
|
||||
impl ClipScrollState {
|
||||
fn new(size: usize, compositor_info: CompositorDisplayListInfo) -> Self {
|
||||
impl<'a> ClipScrollState<'a> {
|
||||
fn new(
|
||||
clip_scroll_nodes: &'a mut Vec<ClipScrollNode>,
|
||||
compositor_info: CompositorDisplayListInfo,
|
||||
builder: &mut DisplayListBuilder,
|
||||
) -> Self {
|
||||
let mut state = ClipScrollState {
|
||||
clip_ids: vec![None; size],
|
||||
scroll_node_ids: vec![None; size],
|
||||
clip_scroll_nodes,
|
||||
compositor_info,
|
||||
};
|
||||
|
||||
|
@ -37,32 +39,38 @@ impl ClipScrollState {
|
|||
// automatically. We also follow the "old" WebRender API for clip/scroll for now,
|
||||
// hence both arrays are initialized based on FIRST_SPATIAL_NODE_INDEX, while
|
||||
// FIRST_CLIP_NODE_INDEX is not taken into account.
|
||||
state.scroll_node_ids[0] = Some(state.compositor_info.root_reference_frame_id);
|
||||
state.scroll_node_ids[1] = Some(state.compositor_info.root_scroll_node_id);
|
||||
state.clip_scroll_nodes[0].scroll_node_id =
|
||||
Some(state.compositor_info.root_reference_frame_id);
|
||||
state.clip_scroll_nodes[1].scroll_node_id = Some(state.compositor_info.root_scroll_node_id);
|
||||
|
||||
let root_clip_id = ClipId::root(state.compositor_info.pipeline_id);
|
||||
state.add_clip_node_mapping(0, root_clip_id);
|
||||
state.add_clip_node_mapping(1, root_clip_id);
|
||||
let root_clip_chain =
|
||||
builder.define_clip_chain(None, [ClipId::root(state.compositor_info.pipeline_id)]);
|
||||
state.add_clip_node_mapping(0, root_clip_chain);
|
||||
state.add_clip_node_mapping(1, root_clip_chain);
|
||||
|
||||
state
|
||||
}
|
||||
|
||||
fn webrender_clip_id_for_index(&mut self, index: usize) -> ClipId {
|
||||
self.clip_ids[index].expect("Tried to use WebRender parent ClipId before it was defined.")
|
||||
fn webrender_clip_id_for_index(&mut self, index: usize) -> ClipChainId {
|
||||
self.clip_scroll_nodes[index]
|
||||
.clip_chain_id
|
||||
.expect("Tried to access WebRender ClipId before definining it.")
|
||||
}
|
||||
|
||||
fn webrender_spatial_id_for_index(&mut self, index: usize) -> SpatialId {
|
||||
self.scroll_node_ids[index]
|
||||
self.clip_scroll_nodes[index]
|
||||
.scroll_node_id
|
||||
.expect("Tried to use WebRender parent SpatialId before it was defined.")
|
||||
.spatial_id
|
||||
}
|
||||
|
||||
fn add_clip_node_mapping(&mut self, index: usize, webrender_id: ClipId) {
|
||||
self.clip_ids[index] = Some(webrender_id);
|
||||
fn add_clip_node_mapping(&mut self, index: usize, webrender_id: ClipChainId) {
|
||||
self.clip_scroll_nodes[index].clip_chain_id = Some(webrender_id);
|
||||
}
|
||||
|
||||
fn scroll_node_id_from_index(&self, index: usize) -> ScrollTreeNodeId {
|
||||
self.scroll_node_ids[index]
|
||||
self.clip_scroll_nodes[index]
|
||||
.scroll_node_id
|
||||
.expect("Tried to use WebRender parent SpatialId before it was defined.")
|
||||
}
|
||||
|
||||
|
@ -74,15 +82,17 @@ impl ClipScrollState {
|
|||
scroll_info: Option<ScrollableNodeInfo>,
|
||||
) {
|
||||
let parent_scroll_node_id = parent_index.map(|index| self.scroll_node_id_from_index(index));
|
||||
self.scroll_node_ids[index] = Some(self.compositor_info.scroll_tree.add_scroll_tree_node(
|
||||
parent_scroll_node_id.as_ref(),
|
||||
spatial_id,
|
||||
scroll_info,
|
||||
));
|
||||
self.clip_scroll_nodes[index].scroll_node_id =
|
||||
Some(self.compositor_info.scroll_tree.add_scroll_tree_node(
|
||||
parent_scroll_node_id.as_ref(),
|
||||
spatial_id,
|
||||
scroll_info,
|
||||
));
|
||||
}
|
||||
|
||||
fn add_spatial_node_mapping_to_parent_index(&mut self, index: usize, parent_index: usize) {
|
||||
self.scroll_node_ids[index] = self.scroll_node_ids[parent_index];
|
||||
self.clip_scroll_nodes[index].scroll_node_id =
|
||||
self.clip_scroll_nodes[parent_index].scroll_node_id
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,27 +110,22 @@ impl DisplayList {
|
|||
epoch: Epoch,
|
||||
) -> (DisplayListBuilder, CompositorDisplayListInfo, IsContentful) {
|
||||
let webrender_pipeline = pipeline_id.to_webrender();
|
||||
let mut state = ClipScrollState::new(
|
||||
self.clip_scroll_nodes.len(),
|
||||
CompositorDisplayListInfo::new(
|
||||
viewport_size,
|
||||
self.bounds().size,
|
||||
webrender_pipeline,
|
||||
epoch,
|
||||
),
|
||||
);
|
||||
|
||||
let mut builder = DisplayListBuilder::with_capacity(
|
||||
webrender_pipeline,
|
||||
self.bounds().size,
|
||||
1024 * 1024, // 1 MB of space
|
||||
);
|
||||
|
||||
let content_size = self.bounds().size;
|
||||
let mut state = ClipScrollState::new(
|
||||
&mut self.clip_scroll_nodes,
|
||||
CompositorDisplayListInfo::new(viewport_size, content_size, webrender_pipeline, epoch),
|
||||
&mut builder,
|
||||
);
|
||||
|
||||
let mut is_contentful = IsContentful(false);
|
||||
for item in &mut self.list {
|
||||
is_contentful.0 |= item
|
||||
.convert_to_webrender(&self.clip_scroll_nodes, &mut state, &mut builder)
|
||||
.0;
|
||||
is_contentful.0 |= item.convert_to_webrender(&mut state, &mut builder).0;
|
||||
}
|
||||
|
||||
(builder, state.compositor_info, is_contentful)
|
||||
|
@ -130,7 +135,6 @@ impl DisplayList {
|
|||
impl DisplayItem {
|
||||
fn convert_to_webrender(
|
||||
&mut self,
|
||||
clip_scroll_nodes: &[ClipScrollNode],
|
||||
state: &mut ClipScrollState,
|
||||
builder: &mut DisplayListBuilder,
|
||||
) -> IsContentful {
|
||||
|
@ -165,7 +169,7 @@ impl DisplayItem {
|
|||
CommonItemProperties {
|
||||
clip_rect: base.clip_rect,
|
||||
spatial_id: current_scroll_node_id.spatial_id,
|
||||
clip_id: current_clip_id,
|
||||
clip_id: ClipId::ClipChain(current_clip_id),
|
||||
// TODO(gw): Make use of the WR backface visibility functionality.
|
||||
flags: PrimitiveFlags::default(),
|
||||
hit_info: tag,
|
||||
|
@ -339,48 +343,54 @@ impl DisplayItem {
|
|||
},
|
||||
DisplayItem::DefineClipScrollNode(ref mut item) => {
|
||||
let index = item.node_index.to_index();
|
||||
let node = &clip_scroll_nodes[index];
|
||||
let node = state.clip_scroll_nodes[index].clone();
|
||||
let item_rect = node.clip.main;
|
||||
|
||||
let parent_index = node.parent_index.to_index();
|
||||
let parent_spatial_id = state.webrender_spatial_id_for_index(parent_index);
|
||||
let parent_clip_id = state.webrender_clip_id_for_index(parent_index);
|
||||
let parent_clip_chain_id = state.webrender_clip_id_for_index(parent_index);
|
||||
|
||||
let parent_space_and_clip_info = SpaceAndClipInfo {
|
||||
clip_id: ClipId::root(state.compositor_info.pipeline_id),
|
||||
spatial_id: parent_spatial_id,
|
||||
};
|
||||
|
||||
match node.node_type {
|
||||
ClipScrollNodeType::Clip(clip_type) => {
|
||||
let space_and_clip_info = SpaceAndClipInfo {
|
||||
clip_id: parent_clip_id,
|
||||
spatial_id: parent_spatial_id,
|
||||
};
|
||||
let clip_id = match clip_type {
|
||||
ClipType::Rect => {
|
||||
builder.define_clip_rect(&space_and_clip_info, item_rect)
|
||||
},
|
||||
ClipType::Rounded(complex) => {
|
||||
builder.define_clip_rounded_rect(&space_and_clip_info, complex)
|
||||
builder.define_clip_rect(&parent_space_and_clip_info, item_rect)
|
||||
},
|
||||
ClipType::Rounded(complex) => builder
|
||||
.define_clip_rounded_rect(&parent_space_and_clip_info, complex),
|
||||
};
|
||||
|
||||
state.add_clip_node_mapping(index, clip_id);
|
||||
let clip_chain_id =
|
||||
builder.define_clip_chain(Some(parent_clip_chain_id), [clip_id]);
|
||||
state.add_clip_node_mapping(index, clip_chain_id);
|
||||
state.add_spatial_node_mapping_to_parent_index(index, parent_index);
|
||||
},
|
||||
ClipScrollNodeType::ScrollFrame(scroll_sensitivity, external_id) => {
|
||||
let space_clip_info = builder.define_scroll_frame(
|
||||
&SpaceAndClipInfo {
|
||||
clip_id: parent_clip_id,
|
||||
spatial_id: parent_spatial_id,
|
||||
},
|
||||
Some(external_id),
|
||||
node.content_rect,
|
||||
item_rect,
|
||||
scroll_sensitivity,
|
||||
LayoutVector2D::zero(),
|
||||
);
|
||||
let clip_id =
|
||||
builder.define_clip_rect(&parent_space_and_clip_info, item_rect);
|
||||
let clip_chain_id =
|
||||
builder.define_clip_chain(Some(parent_clip_chain_id), [clip_id]);
|
||||
state.add_clip_node_mapping(index, clip_chain_id);
|
||||
|
||||
let spatial_id = builder
|
||||
.define_scroll_frame(
|
||||
&parent_space_and_clip_info,
|
||||
Some(external_id),
|
||||
node.content_rect,
|
||||
item_rect,
|
||||
scroll_sensitivity,
|
||||
LayoutVector2D::zero(),
|
||||
)
|
||||
.spatial_id;
|
||||
|
||||
state.add_clip_node_mapping(index, space_clip_info.clip_id);
|
||||
state.register_spatial_node(
|
||||
index,
|
||||
space_clip_info.spatial_id,
|
||||
spatial_id,
|
||||
Some(parent_index),
|
||||
Some(ScrollableNodeInfo {
|
||||
external_id,
|
||||
|
@ -401,7 +411,7 @@ impl DisplayItem {
|
|||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
state.add_clip_node_mapping(index, parent_clip_id);
|
||||
state.add_clip_node_mapping(index, parent_clip_chain_id);
|
||||
state.register_spatial_node(index, id, Some(current_scrolling_index), None);
|
||||
},
|
||||
ClipScrollNodeType::Placeholder => {
|
||||
|
|
|
@ -37,7 +37,7 @@ pub(crate) struct ContainingBlock {
|
|||
|
||||
/// The WebRender ClipId to use for this children of this containing
|
||||
/// block.
|
||||
clip_id: wr::ClipId,
|
||||
clip_chain_id: wr::ClipChainId,
|
||||
|
||||
/// The physical rect of this containing block.
|
||||
rect: PhysicalRect<Length>,
|
||||
|
@ -47,11 +47,11 @@ impl ContainingBlock {
|
|||
pub(crate) fn new(
|
||||
rect: &PhysicalRect<Length>,
|
||||
scroll_node_id: ScrollTreeNodeId,
|
||||
clip_id: wr::ClipId,
|
||||
clip_chain_id: wr::ClipChainId,
|
||||
) -> Self {
|
||||
ContainingBlock {
|
||||
scroll_node_id,
|
||||
clip_id,
|
||||
clip_chain_id,
|
||||
rect: *rect,
|
||||
}
|
||||
}
|
||||
|
@ -76,15 +76,19 @@ pub(crate) enum StackingContextSection {
|
|||
|
||||
impl DisplayList {
|
||||
pub fn build_stacking_context_tree(&mut self, fragment_tree: &FragmentTree) -> StackingContext {
|
||||
let root_clip_chain_id = self
|
||||
.wr
|
||||
.define_clip_chain(None, [wr::ClipId::root(self.wr.pipeline_id)]);
|
||||
|
||||
let cb_for_non_fixed_descendants = ContainingBlock::new(
|
||||
&fragment_tree.initial_containing_block,
|
||||
self.compositor_info.root_scroll_node_id,
|
||||
wr::ClipId::root(self.wr.pipeline_id),
|
||||
root_clip_chain_id,
|
||||
);
|
||||
let cb_for_fixed_descendants = ContainingBlock::new(
|
||||
&fragment_tree.initial_containing_block,
|
||||
self.compositor_info.root_reference_frame_id,
|
||||
wr::ClipId::root(self.wr.pipeline_id),
|
||||
root_clip_chain_id,
|
||||
);
|
||||
|
||||
// We need to specify all three containing blocks here, because absolute
|
||||
|
@ -142,27 +146,40 @@ impl DisplayList {
|
|||
fn define_scroll_frame(
|
||||
&mut self,
|
||||
parent_scroll_node_id: &ScrollTreeNodeId,
|
||||
parent_clip_id: &wr::ClipId,
|
||||
parent_clip_chain_id: &wr::ClipChainId,
|
||||
external_id: wr::ExternalScrollId,
|
||||
content_rect: LayoutRect,
|
||||
clip_rect: LayoutRect,
|
||||
scroll_sensitivity: wr::ScrollSensitivity,
|
||||
external_scroll_offset: LayoutVector2D,
|
||||
) -> (ScrollTreeNodeId, wr::ClipId) {
|
||||
let new_space_and_clip = self.wr.define_scroll_frame(
|
||||
&wr::SpaceAndClipInfo {
|
||||
spatial_id: parent_scroll_node_id.spatial_id,
|
||||
clip_id: *parent_clip_id,
|
||||
},
|
||||
Some(external_id),
|
||||
content_rect,
|
||||
clip_rect,
|
||||
scroll_sensitivity,
|
||||
external_scroll_offset,
|
||||
);
|
||||
) -> (ScrollTreeNodeId, wr::ClipChainId) {
|
||||
let parent_space_and_clip_info = wr::SpaceAndClipInfo {
|
||||
spatial_id: parent_scroll_node_id.spatial_id,
|
||||
clip_id: wr::ClipId::root(self.wr.pipeline_id),
|
||||
};
|
||||
|
||||
let new_clip_id = self
|
||||
.wr
|
||||
.define_clip_rect(&parent_space_and_clip_info, clip_rect);
|
||||
let new_clip_chain_id = self
|
||||
.wr
|
||||
.define_clip_chain(Some(*parent_clip_chain_id), [new_clip_id]);
|
||||
|
||||
let new_spatial_id = self
|
||||
.wr
|
||||
.define_scroll_frame(
|
||||
&parent_space_and_clip_info,
|
||||
Some(external_id),
|
||||
content_rect,
|
||||
clip_rect,
|
||||
scroll_sensitivity,
|
||||
external_scroll_offset,
|
||||
)
|
||||
.spatial_id;
|
||||
|
||||
let new_scroll_node_id = self.compositor_info.scroll_tree.add_scroll_tree_node(
|
||||
Some(&parent_scroll_node_id),
|
||||
new_space_and_clip.spatial_id,
|
||||
new_spatial_id,
|
||||
Some(ScrollableNodeInfo {
|
||||
external_id,
|
||||
scrollable_size: content_rect.size - clip_rect.size,
|
||||
|
@ -170,13 +187,13 @@ impl DisplayList {
|
|||
offset: LayoutVector2D::zero(),
|
||||
}),
|
||||
);
|
||||
(new_scroll_node_id, new_space_and_clip.clip_id)
|
||||
(new_scroll_node_id, new_clip_chain_id)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct StackingContextFragment {
|
||||
scroll_node_id: ScrollTreeNodeId,
|
||||
clip_id: wr::ClipId,
|
||||
clip_chain_id: wr::ClipChainId,
|
||||
section: StackingContextSection,
|
||||
containing_block: PhysicalRect<Length>,
|
||||
fragment: ArcRefCell<Fragment>,
|
||||
|
@ -185,7 +202,7 @@ pub(crate) struct StackingContextFragment {
|
|||
impl StackingContextFragment {
|
||||
fn build_display_list(&self, builder: &mut DisplayListBuilder) {
|
||||
builder.current_scroll_node_id = self.scroll_node_id;
|
||||
builder.current_clip_id = self.clip_id;
|
||||
builder.current_clip_id = wr::ClipId::ClipChain(self.clip_chain_id);
|
||||
self.fragment
|
||||
.borrow()
|
||||
.build_display_list(builder, &self.containing_block, self.section);
|
||||
|
@ -346,7 +363,7 @@ impl StackingContext {
|
|||
LayoutPoint::zero(), // origin
|
||||
self.spatial_id,
|
||||
style.get_webrender_primitive_flags(),
|
||||
None, // clip_id
|
||||
None, // clip_chain_id
|
||||
style.get_used_transform_style().to_webrender(),
|
||||
effects.mix_blend_mode.to_webrender(),
|
||||
&filters,
|
||||
|
@ -608,7 +625,7 @@ impl Fragment {
|
|||
stacking_context.fragments.push(StackingContextFragment {
|
||||
section: StackingContextSection::Content,
|
||||
scroll_node_id: containing_block.scroll_node_id,
|
||||
clip_id: containing_block.clip_id,
|
||||
clip_chain_id: containing_block.clip_chain_id,
|
||||
containing_block: containing_block.rect,
|
||||
fragment: fragment_ref.clone(),
|
||||
});
|
||||
|
@ -721,7 +738,7 @@ impl BoxFragment {
|
|||
.rect
|
||||
.translate(-reference_frame_data.origin.to_vector()),
|
||||
new_spatial_id,
|
||||
containing_block.clip_id,
|
||||
containing_block.clip_chain_id,
|
||||
);
|
||||
let new_containing_block_info =
|
||||
containing_block_info.new_for_non_absolute_descendants(&adjusted_containing_block);
|
||||
|
@ -796,19 +813,19 @@ impl BoxFragment {
|
|||
stacking_context: &mut StackingContext,
|
||||
) {
|
||||
let mut new_scroll_node_id = containing_block.scroll_node_id;
|
||||
let mut new_clip_id = containing_block.clip_id;
|
||||
if let Some(clip_id) = self.build_clip_frame_if_necessary(
|
||||
let mut new_clip_chain_id = containing_block.clip_chain_id;
|
||||
if let Some(clip_chain_id) = self.build_clip_frame_if_necessary(
|
||||
display_list,
|
||||
&new_scroll_node_id,
|
||||
&new_clip_id,
|
||||
&new_clip_chain_id,
|
||||
&containing_block.rect,
|
||||
) {
|
||||
new_clip_id = clip_id;
|
||||
new_clip_chain_id = clip_chain_id;
|
||||
}
|
||||
|
||||
stacking_context.fragments.push(StackingContextFragment {
|
||||
scroll_node_id: new_scroll_node_id,
|
||||
clip_id: new_clip_id,
|
||||
clip_chain_id: new_clip_chain_id,
|
||||
section: self.get_stacking_context_section(),
|
||||
containing_block: containing_block.rect,
|
||||
fragment: fragment.clone(),
|
||||
|
@ -816,7 +833,7 @@ impl BoxFragment {
|
|||
if self.style.get_outline().outline_width.px() > 0.0 {
|
||||
stacking_context.fragments.push(StackingContextFragment {
|
||||
scroll_node_id: new_scroll_node_id,
|
||||
clip_id: new_clip_id,
|
||||
clip_chain_id: new_clip_chain_id,
|
||||
section: StackingContextSection::Outline,
|
||||
containing_block: containing_block.rect,
|
||||
fragment: fragment.clone(),
|
||||
|
@ -825,14 +842,14 @@ impl BoxFragment {
|
|||
|
||||
// We want to build the scroll frame after the background and border, because
|
||||
// they shouldn't scroll with the rest of the box content.
|
||||
if let Some((scroll_node_id, clip_id)) = self.build_scroll_frame_if_necessary(
|
||||
if let Some((scroll_node_id, clip_chain_id)) = self.build_scroll_frame_if_necessary(
|
||||
display_list,
|
||||
&new_scroll_node_id,
|
||||
&new_clip_id,
|
||||
&new_clip_chain_id,
|
||||
&containing_block.rect,
|
||||
) {
|
||||
new_scroll_node_id = scroll_node_id;
|
||||
new_clip_id = clip_id;
|
||||
new_clip_chain_id = clip_chain_id;
|
||||
}
|
||||
|
||||
let padding_rect = self
|
||||
|
@ -845,9 +862,9 @@ impl BoxFragment {
|
|||
.translate(containing_block.rect.origin.to_vector());
|
||||
|
||||
let for_absolute_descendants =
|
||||
ContainingBlock::new(&padding_rect, new_scroll_node_id, new_clip_id);
|
||||
ContainingBlock::new(&padding_rect, new_scroll_node_id, new_clip_chain_id);
|
||||
let for_non_absolute_descendants =
|
||||
ContainingBlock::new(&content_rect, new_scroll_node_id, new_clip_id);
|
||||
ContainingBlock::new(&content_rect, new_scroll_node_id, new_clip_chain_id);
|
||||
|
||||
// Create a new `ContainingBlockInfo` for descendants depending on
|
||||
// whether or not this fragment establishes a containing block for
|
||||
|
@ -887,9 +904,9 @@ impl BoxFragment {
|
|||
&self,
|
||||
display_list: &mut DisplayList,
|
||||
parent_scroll_node_id: &ScrollTreeNodeId,
|
||||
parent_clip_id: &wr::ClipId,
|
||||
parent_clip_chain_id: &wr::ClipChainId,
|
||||
containing_block_rect: &PhysicalRect<Length>,
|
||||
) -> Option<wr::ClipId> {
|
||||
) -> Option<wr::ClipChainId> {
|
||||
let position = self.style.get_box().position;
|
||||
// https://drafts.csswg.org/css2/#clipping
|
||||
// The clip property applies only to absolutely positioned elements
|
||||
|
@ -911,22 +928,28 @@ impl BoxFragment {
|
|||
.translate(containing_block_rect.origin.to_vector())
|
||||
.to_webrender();
|
||||
|
||||
Some(display_list.wr.define_clip_rect(
|
||||
&wr::SpaceAndClipInfo {
|
||||
spatial_id: parent_scroll_node_id.spatial_id,
|
||||
clip_id: *parent_clip_id,
|
||||
},
|
||||
clip_rect,
|
||||
))
|
||||
let parent_space_and_clip = &wr::SpaceAndClipInfo {
|
||||
spatial_id: parent_scroll_node_id.spatial_id,
|
||||
clip_id: wr::ClipId::root(display_list.wr.pipeline_id),
|
||||
};
|
||||
|
||||
let clip_id = display_list
|
||||
.wr
|
||||
.define_clip_rect(&parent_space_and_clip, clip_rect);
|
||||
Some(
|
||||
display_list
|
||||
.wr
|
||||
.define_clip_chain(Some(*parent_clip_chain_id), [clip_id]),
|
||||
)
|
||||
}
|
||||
|
||||
fn build_scroll_frame_if_necessary(
|
||||
&self,
|
||||
display_list: &mut DisplayList,
|
||||
parent_scroll_node_id: &ScrollTreeNodeId,
|
||||
parent_clip_id: &wr::ClipId,
|
||||
parent_clip_id: &wr::ClipChainId,
|
||||
containing_block_rect: &PhysicalRect<Length>,
|
||||
) -> Option<(ScrollTreeNodeId, wr::ClipId)> {
|
||||
) -> Option<(ScrollTreeNodeId, wr::ClipChainId)> {
|
||||
let overflow_x = self.style.get_box().overflow_x;
|
||||
let overflow_y = self.style.get_box().overflow_y;
|
||||
if overflow_x == ComputedOverflow::Visible && overflow_y == ComputedOverflow::Visible {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue