Skip to content

Commit d95c371

Browse files
authored
Auto merge of servo#29486 - mrobinson:move-more-code-into-clip-scroll-state, r=mukilan
Move more code into ClipScrollState during WebRender DL building This change moves a bit more code into the `ClipScrollState` helper during WR display list building as well as inlines build_common_item_properties. This is all in preparation of modifications to this code which will build a Compositor-side scroll tree. It should not change any behavior. <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes do not require tests because they do not change behavior. <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
2 parents cd81a7a + 05dda40 commit d95c371

File tree

1 file changed

+99
-74
lines changed

1 file changed

+99
-74
lines changed

components/layout/display_list/webrender_helpers.rs

Lines changed: 99 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use crate::display_list::items::{BaseDisplayItem, ClipScrollNode, ClipScrollNodeType, ClipType};
1111
use crate::display_list::items::{DisplayItem, DisplayList, StackingContextType};
1212
use msg::constellation_msg::PipelineId;
13-
use webrender_api::units::LayoutPoint;
13+
use webrender_api::units::{LayoutPoint, LayoutVector2D};
1414
use webrender_api::{
1515
self, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem, DisplayListBuilder,
1616
PrimitiveFlags, PropertyBinding, PushStackingContextDisplayItem, RasterSpace,
@@ -24,6 +24,54 @@ struct ClipScrollState {
2424
active_spatial_id: SpatialId,
2525
}
2626

27+
impl ClipScrollState {
28+
fn new(size: usize, pipeline_id: webrender_api::PipelineId) -> Self {
29+
let root_clip_id = ClipId::root(pipeline_id);
30+
let root_scroll_node_id = SpatialId::root_scroll_node(pipeline_id);
31+
let root_reference_frame_id = SpatialId::root_reference_frame(pipeline_id);
32+
let mut state = ClipScrollState {
33+
clip_ids: vec![None; size],
34+
spatial_ids: vec![None; size],
35+
active_clip_id: root_clip_id,
36+
active_spatial_id: root_scroll_node_id,
37+
};
38+
39+
// We need to register the WebRender root reference frame and root scroll node ids
40+
// here manually, because WebRender and the CompositorDisplayListInfo create them
41+
// automatically. We also follow the "old" WebRender API for clip/scroll for now,
42+
// hence both arrays are initialized based on FIRST_SPATIAL_NODE_INDEX, while
43+
// FIRST_CLIP_NODE_INDEX is not taken into account.
44+
state.spatial_ids[0] = Some(root_reference_frame_id);
45+
state.spatial_ids[1] = Some(root_scroll_node_id);
46+
47+
state.add_clip_node_mapping(0, root_clip_id);
48+
state.add_clip_node_mapping(1, root_clip_id);
49+
50+
state
51+
}
52+
53+
fn webrender_clip_id_for_index(&mut self, index: usize) -> ClipId {
54+
self.clip_ids[index].expect("Tried to use WebRender parent ClipId before it was defined.")
55+
}
56+
57+
fn webrender_spatial_id_for_index(&mut self, index: usize) -> SpatialId {
58+
self.spatial_ids[index]
59+
.expect("Tried to use WebRender parent SpatialId before it was defined.")
60+
}
61+
62+
fn add_clip_node_mapping(&mut self, index: usize, webrender_id: ClipId) {
63+
self.clip_ids[index] = Some(webrender_id);
64+
}
65+
66+
fn register_spatial_node(&mut self, index: usize, webrender_id: SpatialId) {
67+
self.spatial_ids[index] = Some(webrender_id);
68+
}
69+
70+
fn add_spatial_node_mapping_to_parent_index(&mut self, index: usize, parent_index: usize) {
71+
self.spatial_ids[index] = self.spatial_ids[parent_index];
72+
}
73+
}
74+
2775
/// Contentful paint, for the purpose of
2876
/// https://w3c.github.io/paint-timing/#first-contentful-paint
2977
/// (i.e. the display list contains items of type text,
@@ -35,27 +83,8 @@ impl DisplayList {
3583
&mut self,
3684
pipeline_id: PipelineId,
3785
) -> (DisplayListBuilder, IsContentful) {
38-
let mut clip_ids = vec![None; self.clip_scroll_nodes.len()];
39-
let mut spatial_ids = vec![None; self.clip_scroll_nodes.len()];
40-
41-
// We need to add the WebRender root reference frame and root scroll node ids
42-
// here manually, because WebRender creates these automatically.
43-
// We also follow the "old" WebRender API for clip/scroll for now,
44-
// hence both arrays are initialized based on FIRST_SPATIAL_NODE_INDEX,
45-
// while FIRST_CLIP_NODE_INDEX is not taken into account.
46-
4786
let webrender_pipeline = pipeline_id.to_webrender();
48-
clip_ids[0] = Some(ClipId::root(webrender_pipeline));
49-
clip_ids[1] = Some(ClipId::root(webrender_pipeline));
50-
spatial_ids[0] = Some(SpatialId::root_reference_frame(webrender_pipeline));
51-
spatial_ids[1] = Some(SpatialId::root_scroll_node(webrender_pipeline));
52-
53-
let mut state = ClipScrollState {
54-
clip_ids,
55-
spatial_ids,
56-
active_clip_id: ClipId::root(webrender_pipeline),
57-
active_spatial_id: SpatialId::root_scroll_node(webrender_pipeline),
58-
};
87+
let mut state = ClipScrollState::new(self.clip_scroll_nodes.len(), webrender_pipeline);
5988

6089
let mut builder = DisplayListBuilder::with_capacity(
6190
webrender_pipeline,
@@ -89,75 +118,89 @@ impl DisplayItem {
89118
let clip_and_scroll_indices = self.base().clipping_and_scrolling;
90119
trace!("converting {:?}", clip_and_scroll_indices);
91120

92-
let cur_spatial_id = state.spatial_ids[clip_and_scroll_indices.scrolling.to_index()]
93-
.expect("Tried to use WebRender SpatialId before it was defined.");
121+
let current_scrolling_index = clip_and_scroll_indices.scrolling.to_index();
122+
let cur_spatial_id = state.webrender_spatial_id_for_index(current_scrolling_index);
94123
if cur_spatial_id != state.active_spatial_id {
95124
state.active_spatial_id = cur_spatial_id;
96125
}
97126

98127
let internal_clip_id = clip_and_scroll_indices
99128
.clipping
100129
.unwrap_or(clip_and_scroll_indices.scrolling);
101-
let cur_clip_id = state.clip_ids[internal_clip_id.to_index()]
102-
.expect("Tried to use WebRender ClipId before it was defined.");
130+
let cur_clip_id = state.webrender_clip_id_for_index(internal_clip_id.to_index());
103131
if cur_clip_id != state.active_clip_id {
104132
state.active_clip_id = cur_clip_id;
105133
}
106134

135+
let build_common_item_properties = |base: &BaseDisplayItem| {
136+
let tag = match base.metadata.pointing {
137+
Some(cursor) => Some((base.metadata.node.0 as u64, cursor)),
138+
None => None,
139+
};
140+
CommonItemProperties {
141+
clip_rect: base.clip_rect,
142+
spatial_id: state.active_spatial_id,
143+
clip_id: state.active_clip_id,
144+
// TODO(gw): Make use of the WR backface visibility functionality.
145+
flags: PrimitiveFlags::default(),
146+
hit_info: tag,
147+
}
148+
};
149+
107150
match *self {
108151
DisplayItem::Rectangle(ref mut item) => {
109-
item.item.common = build_common_item_properties(&item.base, state);
152+
item.item.common = build_common_item_properties(&item.base);
110153
builder.push_item(&WrDisplayItem::Rectangle(item.item));
111154
IsContentful(false)
112155
},
113156
DisplayItem::Text(ref mut item) => {
114-
item.item.common = build_common_item_properties(&item.base, state);
157+
item.item.common = build_common_item_properties(&item.base);
115158
builder.push_item(&WrDisplayItem::Text(item.item));
116159
builder.push_iter(item.data.iter());
117160
IsContentful(true)
118161
},
119162
DisplayItem::Image(ref mut item) => {
120-
item.item.common = build_common_item_properties(&item.base, state);
163+
item.item.common = build_common_item_properties(&item.base);
121164
builder.push_item(&WrDisplayItem::Image(item.item));
122165
IsContentful(true)
123166
},
124167
DisplayItem::RepeatingImage(ref mut item) => {
125-
item.item.common = build_common_item_properties(&item.base, state);
168+
item.item.common = build_common_item_properties(&item.base);
126169
builder.push_item(&WrDisplayItem::RepeatingImage(item.item));
127170
IsContentful(true)
128171
},
129172
DisplayItem::Border(ref mut item) => {
130-
item.item.common = build_common_item_properties(&item.base, state);
173+
item.item.common = build_common_item_properties(&item.base);
131174
if !item.data.is_empty() {
132175
builder.push_stops(item.data.as_ref());
133176
}
134177
builder.push_item(&WrDisplayItem::Border(item.item));
135178
IsContentful(false)
136179
},
137180
DisplayItem::Gradient(ref mut item) => {
138-
item.item.common = build_common_item_properties(&item.base, state);
181+
item.item.common = build_common_item_properties(&item.base);
139182
builder.push_stops(item.data.as_ref());
140183
builder.push_item(&WrDisplayItem::Gradient(item.item));
141184
IsContentful(false)
142185
},
143186
DisplayItem::RadialGradient(ref mut item) => {
144-
item.item.common = build_common_item_properties(&item.base, state);
187+
item.item.common = build_common_item_properties(&item.base);
145188
builder.push_stops(item.data.as_ref());
146189
builder.push_item(&WrDisplayItem::RadialGradient(item.item));
147190
IsContentful(false)
148191
},
149192
DisplayItem::Line(ref mut item) => {
150-
item.item.common = build_common_item_properties(&item.base, state);
193+
item.item.common = build_common_item_properties(&item.base);
151194
builder.push_item(&WrDisplayItem::Line(item.item));
152195
IsContentful(false)
153196
},
154197
DisplayItem::BoxShadow(ref mut item) => {
155-
item.item.common = build_common_item_properties(&item.base, state);
198+
item.item.common = build_common_item_properties(&item.base);
156199
builder.push_item(&WrDisplayItem::BoxShadow(item.item));
157200
IsContentful(false)
158201
},
159202
DisplayItem::PushTextShadow(ref mut item) => {
160-
let common = build_common_item_properties(&item.base, state);
203+
let common = build_common_item_properties(&item.base);
161204
builder.push_shadow(
162205
&SpaceAndClipInfo {
163206
spatial_id: common.spatial_id,
@@ -173,7 +216,7 @@ impl DisplayItem {
173216
IsContentful(false)
174217
},
175218
DisplayItem::Iframe(ref mut item) => {
176-
let common = build_common_item_properties(&item.base, state);
219+
let common = build_common_item_properties(&item.base);
177220
builder.push_iframe(
178221
item.bounds,
179222
common.clip_rect,
@@ -212,19 +255,20 @@ impl DisplayItem {
212255
(None, None) => unreachable!(),
213256
};
214257

215-
let spatial_id = builder.push_reference_frame(
258+
let new_spatial_id = builder.push_reference_frame(
216259
stacking_context.bounds.origin,
217260
state.active_spatial_id,
218261
stacking_context.transform_style,
219262
PropertyBinding::Value(transform),
220263
ref_frame,
221264
);
222265

223-
state.spatial_ids[frame_index.to_index()] = Some(spatial_id);
224-
state.clip_ids[frame_index.to_index()] = Some(cur_clip_id);
266+
let index = frame_index.to_index();
267+
state.add_clip_node_mapping(index, cur_clip_id);
268+
state.register_spatial_node(index, new_spatial_id);
225269

226270
bounds.origin = LayoutPoint::zero();
227-
spatial_id
271+
new_spatial_id
228272
} else {
229273
state.active_spatial_id
230274
};
@@ -264,21 +308,21 @@ impl DisplayItem {
264308
IsContentful(false)
265309
},
266310
DisplayItem::DefineClipScrollNode(ref mut item) => {
267-
let node = &clip_scroll_nodes[item.node_index.to_index()];
311+
let index = item.node_index.to_index();
312+
let node = &clip_scroll_nodes[index];
268313
let item_rect = node.clip.main;
269314

270-
let parent_spatial_id = state.spatial_ids[node.parent_index.to_index()]
271-
.expect("Tried to use WebRender parent SpatialId before it was defined.");
272-
let parent_clip_id = state.clip_ids[node.parent_index.to_index()]
273-
.expect("Tried to use WebRender parent ClipId before it was defined.");
315+
let parent_index = node.parent_index.to_index();
316+
let parent_spatial_id = state.webrender_spatial_id_for_index(parent_index);
317+
let parent_clip_id = state.webrender_clip_id_for_index(parent_index);
274318

275319
match node.node_type {
276320
ClipScrollNodeType::Clip(clip_type) => {
277321
let space_and_clip_info = SpaceAndClipInfo {
278322
clip_id: parent_clip_id,
279323
spatial_id: parent_spatial_id,
280324
};
281-
let id = match clip_type {
325+
let clip_id = match clip_type {
282326
ClipType::Rect => {
283327
builder.define_clip_rect(&space_and_clip_info, item_rect)
284328
},
@@ -287,8 +331,8 @@ impl DisplayItem {
287331
},
288332
};
289333

290-
state.spatial_ids[item.node_index.to_index()] = Some(parent_spatial_id);
291-
state.clip_ids[item.node_index.to_index()] = Some(id);
334+
state.add_clip_node_mapping(index, clip_id);
335+
state.add_spatial_node_mapping_to_parent_index(index, parent_index);
292336
},
293337
ClipScrollNodeType::ScrollFrame(scroll_sensitivity, external_id) => {
294338
let space_clip_info = builder.define_scroll_frame(
@@ -298,14 +342,13 @@ impl DisplayItem {
298342
},
299343
Some(external_id),
300344
node.content_rect,
301-
node.clip.main,
345+
item_rect,
302346
scroll_sensitivity,
303-
webrender_api::units::LayoutVector2D::zero(),
347+
LayoutVector2D::zero(),
304348
);
305349

306-
state.clip_ids[item.node_index.to_index()] = Some(space_clip_info.clip_id);
307-
state.spatial_ids[item.node_index.to_index()] =
308-
Some(space_clip_info.spatial_id);
350+
state.register_spatial_node(index, space_clip_info.spatial_id);
351+
state.add_clip_node_mapping(index, space_clip_info.clip_id);
309352
},
310353
ClipScrollNodeType::StickyFrame(ref sticky_data) => {
311354
// TODO: Add define_sticky_frame_with_parent to WebRender.
@@ -315,11 +358,11 @@ impl DisplayItem {
315358
sticky_data.margins,
316359
sticky_data.vertical_offset_bounds,
317360
sticky_data.horizontal_offset_bounds,
318-
webrender_api::units::LayoutVector2D::zero(),
361+
LayoutVector2D::zero(),
319362
);
320363

321-
state.spatial_ids[item.node_index.to_index()] = Some(id);
322-
state.clip_ids[item.node_index.to_index()] = Some(parent_clip_id);
364+
state.add_clip_node_mapping(index, parent_clip_id);
365+
state.register_spatial_node(index, id);
323366
},
324367
ClipScrollNodeType::Placeholder => {
325368
unreachable!("Found DefineClipScrollNode for Placeholder type node.");
@@ -330,21 +373,3 @@ impl DisplayItem {
330373
}
331374
}
332375
}
333-
334-
fn build_common_item_properties(
335-
base: &BaseDisplayItem,
336-
state: &ClipScrollState,
337-
) -> CommonItemProperties {
338-
let tag = match base.metadata.pointing {
339-
Some(cursor) => Some((base.metadata.node.0 as u64, cursor)),
340-
None => None,
341-
};
342-
CommonItemProperties {
343-
clip_rect: base.clip_rect,
344-
spatial_id: state.active_spatial_id,
345-
clip_id: state.active_clip_id,
346-
// TODO(gw): Make use of the WR backface visibility functionality.
347-
flags: PrimitiveFlags::default(),
348-
hit_info: tag,
349-
}
350-
}

0 commit comments

Comments
 (0)