Skip to content

Commit 3c4328f

Browse files
committed
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.
1 parent 66abb1d commit 3c4328f

File tree

4 files changed

+165
-114
lines changed

4 files changed

+165
-114
lines changed

components/layout/display_list/builder.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2616,6 +2616,8 @@ impl BlockFlow {
26162616
clip: ClippingRegion::from_rect(border_box.to_layout()),
26172617
content_rect: LayoutRect::zero(),
26182618
node_type: ClipScrollNodeType::StickyFrame(sticky_frame_data),
2619+
scroll_node_id: None,
2620+
clip_chain_id: None,
26192621
});
26202622

26212623
let new_clipping_and_scrolling = ClippingAndScrolling::simple(new_clip_scroll_index);
@@ -2683,6 +2685,8 @@ impl BlockFlow {
26832685
clip: clip,
26842686
content_rect: Rect::new(content_box.origin, content_size).to_layout(),
26852687
node_type: ClipScrollNodeType::ScrollFrame(sensitivity, external_id),
2688+
scroll_node_id: None,
2689+
clip_chain_id: None,
26862690
});
26872691

26882692
let new_clipping_and_scrolling = ClippingAndScrolling::simple(new_clip_scroll_index);
@@ -2719,6 +2723,8 @@ impl BlockFlow {
27192723
clip: ClippingRegion::from_rect(clip_rect.to_layout()),
27202724
content_rect: LayoutRect::zero(), // content_rect isn't important for clips.
27212725
node_type: ClipScrollNodeType::Clip(ClipType::Rect),
2726+
scroll_node_id: None,
2727+
clip_chain_id: None,
27222728
});
27232729

27242730
let new_indices = ClippingAndScrolling::new(new_index, new_index);

components/layout/display_list/items.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use gfx_traits::print_tree::PrintTree;
1818
use gfx_traits::{self, StackingContextId};
1919
use msg::constellation_msg::PipelineId;
2020
use net_traits::image::base::Image;
21+
use script_traits::compositor::ScrollTreeNodeId;
2122
use servo_geometry::MaxRect;
2223
use std::cmp::Ordering;
2324
use std::collections::HashMap;
@@ -31,6 +32,7 @@ use webrender_api::{
3132
FilterOp, GlyphInstance, GradientStop, ImageKey, MixBlendMode, PrimitiveFlags,
3233
ScrollSensitivity, Shadow, SpatialId, StickyOffsetBounds, TransformStyle,
3334
};
35+
use wr::ClipChainId;
3436

3537
pub use style::dom::OpaqueNode;
3638

@@ -369,6 +371,12 @@ pub struct ClipScrollNode {
369371

370372
/// The type of this ClipScrollNode.
371373
pub node_type: ClipScrollNodeType,
374+
375+
/// The WebRender spatial id of this node assigned during WebRender conversion.
376+
pub scroll_node_id: Option<ScrollTreeNodeId>,
377+
378+
/// The WebRender clip id of this node assigned during WebRender conversion.
379+
pub clip_chain_id: Option<ClipChainId>,
372380
}
373381

374382
impl ClipScrollNode {
@@ -378,6 +386,8 @@ impl ClipScrollNode {
378386
clip: ClippingRegion::from_rect(LayoutRect::zero()),
379387
content_rect: LayoutRect::zero(),
380388
node_type: ClipScrollNodeType::Placeholder,
389+
scroll_node_id: None,
390+
clip_chain_id: None,
381391
}
382392
}
383393

@@ -400,6 +410,8 @@ impl ClipScrollNode {
400410
clip: ClippingRegion::from_rect(clip_rect),
401411
content_rect: LayoutRect::zero(), // content_rect isn't important for clips.
402412
node_type: ClipScrollNodeType::Clip(ClipType::Rounded(complex_region)),
413+
scroll_node_id: None,
414+
clip_chain_id: None,
403415
}
404416
}
405417
}

components/layout/display_list/webrender_helpers.rs

Lines changed: 77 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,24 @@ use msg::constellation_msg::PipelineId;
1313
use script_traits::compositor::{CompositorDisplayListInfo, ScrollTreeNodeId, ScrollableNodeInfo};
1414
use webrender_api::units::{LayoutPoint, LayoutSize, LayoutVector2D};
1515
use webrender_api::{
16-
self, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem, DisplayListBuilder, Epoch,
17-
PrimitiveFlags, PropertyBinding, PushStackingContextDisplayItem, RasterSpace,
18-
ReferenceFrameKind, SpaceAndClipInfo, SpatialId, StackingContext,
16+
self, ClipChainId, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem,
17+
DisplayListBuilder, Epoch, PrimitiveFlags, PropertyBinding, PushStackingContextDisplayItem,
18+
RasterSpace, ReferenceFrameKind, SpaceAndClipInfo, SpatialId, StackingContext,
1919
};
2020

21-
struct ClipScrollState {
22-
clip_ids: Vec<Option<ClipId>>,
23-
scroll_node_ids: Vec<Option<ScrollTreeNodeId>>,
21+
struct ClipScrollState<'a> {
22+
clip_scroll_nodes: &'a mut Vec<ClipScrollNode>,
2423
compositor_info: CompositorDisplayListInfo,
2524
}
2625

27-
impl ClipScrollState {
28-
fn new(size: usize, compositor_info: CompositorDisplayListInfo) -> Self {
26+
impl<'a> ClipScrollState<'a> {
27+
fn new(
28+
clip_scroll_nodes: &'a mut Vec<ClipScrollNode>,
29+
compositor_info: CompositorDisplayListInfo,
30+
builder: &mut DisplayListBuilder,
31+
) -> Self {
2932
let mut state = ClipScrollState {
30-
clip_ids: vec![None; size],
31-
scroll_node_ids: vec![None; size],
33+
clip_scroll_nodes,
3234
compositor_info,
3335
};
3436

@@ -37,32 +39,38 @@ impl ClipScrollState {
3739
// automatically. We also follow the "old" WebRender API for clip/scroll for now,
3840
// hence both arrays are initialized based on FIRST_SPATIAL_NODE_INDEX, while
3941
// FIRST_CLIP_NODE_INDEX is not taken into account.
40-
state.scroll_node_ids[0] = Some(state.compositor_info.root_reference_frame_id);
41-
state.scroll_node_ids[1] = Some(state.compositor_info.root_scroll_node_id);
42+
state.clip_scroll_nodes[0].scroll_node_id =
43+
Some(state.compositor_info.root_reference_frame_id);
44+
state.clip_scroll_nodes[1].scroll_node_id = Some(state.compositor_info.root_scroll_node_id);
4245

43-
let root_clip_id = ClipId::root(state.compositor_info.pipeline_id);
44-
state.add_clip_node_mapping(0, root_clip_id);
45-
state.add_clip_node_mapping(1, root_clip_id);
46+
let root_clip_chain =
47+
builder.define_clip_chain(None, [ClipId::root(state.compositor_info.pipeline_id)]);
48+
state.add_clip_node_mapping(0, root_clip_chain);
49+
state.add_clip_node_mapping(1, root_clip_chain);
4650

4751
state
4852
}
4953

50-
fn webrender_clip_id_for_index(&mut self, index: usize) -> ClipId {
51-
self.clip_ids[index].expect("Tried to use WebRender parent ClipId before it was defined.")
54+
fn webrender_clip_id_for_index(&mut self, index: usize) -> ClipChainId {
55+
self.clip_scroll_nodes[index]
56+
.clip_chain_id
57+
.expect("Tried to access WebRender ClipId before definining it.")
5258
}
5359

5460
fn webrender_spatial_id_for_index(&mut self, index: usize) -> SpatialId {
55-
self.scroll_node_ids[index]
61+
self.clip_scroll_nodes[index]
62+
.scroll_node_id
5663
.expect("Tried to use WebRender parent SpatialId before it was defined.")
5764
.spatial_id
5865
}
5966

60-
fn add_clip_node_mapping(&mut self, index: usize, webrender_id: ClipId) {
61-
self.clip_ids[index] = Some(webrender_id);
67+
fn add_clip_node_mapping(&mut self, index: usize, webrender_id: ClipChainId) {
68+
self.clip_scroll_nodes[index].clip_chain_id = Some(webrender_id);
6269
}
6370

6471
fn scroll_node_id_from_index(&self, index: usize) -> ScrollTreeNodeId {
65-
self.scroll_node_ids[index]
72+
self.clip_scroll_nodes[index]
73+
.scroll_node_id
6674
.expect("Tried to use WebRender parent SpatialId before it was defined.")
6775
}
6876

@@ -74,15 +82,17 @@ impl ClipScrollState {
7482
scroll_info: Option<ScrollableNodeInfo>,
7583
) {
7684
let parent_scroll_node_id = parent_index.map(|index| self.scroll_node_id_from_index(index));
77-
self.scroll_node_ids[index] = Some(self.compositor_info.scroll_tree.add_scroll_tree_node(
78-
parent_scroll_node_id.as_ref(),
79-
spatial_id,
80-
scroll_info,
81-
));
85+
self.clip_scroll_nodes[index].scroll_node_id =
86+
Some(self.compositor_info.scroll_tree.add_scroll_tree_node(
87+
parent_scroll_node_id.as_ref(),
88+
spatial_id,
89+
scroll_info,
90+
));
8291
}
8392

8493
fn add_spatial_node_mapping_to_parent_index(&mut self, index: usize, parent_index: usize) {
85-
self.scroll_node_ids[index] = self.scroll_node_ids[parent_index];
94+
self.clip_scroll_nodes[index].scroll_node_id =
95+
self.clip_scroll_nodes[parent_index].scroll_node_id
8696
}
8797
}
8898

@@ -100,27 +110,22 @@ impl DisplayList {
100110
epoch: Epoch,
101111
) -> (DisplayListBuilder, CompositorDisplayListInfo, IsContentful) {
102112
let webrender_pipeline = pipeline_id.to_webrender();
103-
let mut state = ClipScrollState::new(
104-
self.clip_scroll_nodes.len(),
105-
CompositorDisplayListInfo::new(
106-
viewport_size,
107-
self.bounds().size,
108-
webrender_pipeline,
109-
epoch,
110-
),
111-
);
112-
113113
let mut builder = DisplayListBuilder::with_capacity(
114114
webrender_pipeline,
115115
self.bounds().size,
116116
1024 * 1024, // 1 MB of space
117117
);
118118

119+
let content_size = self.bounds().size;
120+
let mut state = ClipScrollState::new(
121+
&mut self.clip_scroll_nodes,
122+
CompositorDisplayListInfo::new(viewport_size, content_size, webrender_pipeline, epoch),
123+
&mut builder,
124+
);
125+
119126
let mut is_contentful = IsContentful(false);
120127
for item in &mut self.list {
121-
is_contentful.0 |= item
122-
.convert_to_webrender(&self.clip_scroll_nodes, &mut state, &mut builder)
123-
.0;
128+
is_contentful.0 |= item.convert_to_webrender(&mut state, &mut builder).0;
124129
}
125130

126131
(builder, state.compositor_info, is_contentful)
@@ -130,7 +135,6 @@ impl DisplayList {
130135
impl DisplayItem {
131136
fn convert_to_webrender(
132137
&mut self,
133-
clip_scroll_nodes: &[ClipScrollNode],
134138
state: &mut ClipScrollState,
135139
builder: &mut DisplayListBuilder,
136140
) -> IsContentful {
@@ -165,7 +169,7 @@ impl DisplayItem {
165169
CommonItemProperties {
166170
clip_rect: base.clip_rect,
167171
spatial_id: current_scroll_node_id.spatial_id,
168-
clip_id: current_clip_id,
172+
clip_id: ClipId::ClipChain(current_clip_id),
169173
// TODO(gw): Make use of the WR backface visibility functionality.
170174
flags: PrimitiveFlags::default(),
171175
hit_info: tag,
@@ -339,48 +343,54 @@ impl DisplayItem {
339343
},
340344
DisplayItem::DefineClipScrollNode(ref mut item) => {
341345
let index = item.node_index.to_index();
342-
let node = &clip_scroll_nodes[index];
346+
let node = state.clip_scroll_nodes[index].clone();
343347
let item_rect = node.clip.main;
344348

345349
let parent_index = node.parent_index.to_index();
346350
let parent_spatial_id = state.webrender_spatial_id_for_index(parent_index);
347-
let parent_clip_id = state.webrender_clip_id_for_index(parent_index);
351+
let parent_clip_chain_id = state.webrender_clip_id_for_index(parent_index);
352+
353+
let parent_space_and_clip_info = SpaceAndClipInfo {
354+
clip_id: ClipId::root(state.compositor_info.pipeline_id),
355+
spatial_id: parent_spatial_id,
356+
};
348357

349358
match node.node_type {
350359
ClipScrollNodeType::Clip(clip_type) => {
351-
let space_and_clip_info = SpaceAndClipInfo {
352-
clip_id: parent_clip_id,
353-
spatial_id: parent_spatial_id,
354-
};
355360
let clip_id = match clip_type {
356361
ClipType::Rect => {
357-
builder.define_clip_rect(&space_and_clip_info, item_rect)
358-
},
359-
ClipType::Rounded(complex) => {
360-
builder.define_clip_rounded_rect(&space_and_clip_info, complex)
362+
builder.define_clip_rect(&parent_space_and_clip_info, item_rect)
361363
},
364+
ClipType::Rounded(complex) => builder
365+
.define_clip_rounded_rect(&parent_space_and_clip_info, complex),
362366
};
363367

364-
state.add_clip_node_mapping(index, clip_id);
368+
let clip_chain_id =
369+
builder.define_clip_chain(Some(parent_clip_chain_id), [clip_id]);
370+
state.add_clip_node_mapping(index, clip_chain_id);
365371
state.add_spatial_node_mapping_to_parent_index(index, parent_index);
366372
},
367373
ClipScrollNodeType::ScrollFrame(scroll_sensitivity, external_id) => {
368-
let space_clip_info = builder.define_scroll_frame(
369-
&SpaceAndClipInfo {
370-
clip_id: parent_clip_id,
371-
spatial_id: parent_spatial_id,
372-
},
373-
Some(external_id),
374-
node.content_rect,
375-
item_rect,
376-
scroll_sensitivity,
377-
LayoutVector2D::zero(),
378-
);
374+
let clip_id =
375+
builder.define_clip_rect(&parent_space_and_clip_info, item_rect);
376+
let clip_chain_id =
377+
builder.define_clip_chain(Some(parent_clip_chain_id), [clip_id]);
378+
state.add_clip_node_mapping(index, clip_chain_id);
379+
380+
let spatial_id = builder
381+
.define_scroll_frame(
382+
&parent_space_and_clip_info,
383+
Some(external_id),
384+
node.content_rect,
385+
item_rect,
386+
scroll_sensitivity,
387+
LayoutVector2D::zero(),
388+
)
389+
.spatial_id;
379390

380-
state.add_clip_node_mapping(index, space_clip_info.clip_id);
381391
state.register_spatial_node(
382392
index,
383-
space_clip_info.spatial_id,
393+
spatial_id,
384394
Some(parent_index),
385395
Some(ScrollableNodeInfo {
386396
external_id,
@@ -401,7 +411,7 @@ impl DisplayItem {
401411
LayoutVector2D::zero(),
402412
);
403413

404-
state.add_clip_node_mapping(index, parent_clip_id);
414+
state.add_clip_node_mapping(index, parent_clip_chain_id);
405415
state.register_spatial_node(index, id, Some(current_scrolling_index), None);
406416
},
407417
ClipScrollNodeType::Placeholder => {

0 commit comments

Comments
 (0)