10
10
use crate :: display_list:: items:: { BaseDisplayItem , ClipScrollNode , ClipScrollNodeType , ClipType } ;
11
11
use crate :: display_list:: items:: { DisplayItem , DisplayList , StackingContextType } ;
12
12
use msg:: constellation_msg:: PipelineId ;
13
- use webrender_api:: units:: LayoutPoint ;
13
+ use webrender_api:: units:: { LayoutPoint , LayoutVector2D } ;
14
14
use webrender_api:: {
15
15
self , ClipId , CommonItemProperties , DisplayItem as WrDisplayItem , DisplayListBuilder ,
16
16
PrimitiveFlags , PropertyBinding , PushStackingContextDisplayItem , RasterSpace ,
@@ -24,6 +24,54 @@ struct ClipScrollState {
24
24
active_spatial_id : SpatialId ,
25
25
}
26
26
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
+
27
75
/// Contentful paint, for the purpose of
28
76
/// https://w3c.github.io/paint-timing/#first-contentful-paint
29
77
/// (i.e. the display list contains items of type text,
@@ -35,27 +83,8 @@ impl DisplayList {
35
83
& mut self ,
36
84
pipeline_id : PipelineId ,
37
85
) -> ( 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
-
47
86
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) ;
59
88
60
89
let mut builder = DisplayListBuilder :: with_capacity (
61
90
webrender_pipeline,
@@ -89,75 +118,89 @@ impl DisplayItem {
89
118
let clip_and_scroll_indices = self . base ( ) . clipping_and_scrolling ;
90
119
trace ! ( "converting {:?}" , clip_and_scroll_indices) ;
91
120
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 ) ;
94
123
if cur_spatial_id != state. active_spatial_id {
95
124
state. active_spatial_id = cur_spatial_id;
96
125
}
97
126
98
127
let internal_clip_id = clip_and_scroll_indices
99
128
. clipping
100
129
. 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 ( ) ) ;
103
131
if cur_clip_id != state. active_clip_id {
104
132
state. active_clip_id = cur_clip_id;
105
133
}
106
134
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
+
107
150
match * self {
108
151
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 ) ;
110
153
builder. push_item ( & WrDisplayItem :: Rectangle ( item. item ) ) ;
111
154
IsContentful ( false )
112
155
} ,
113
156
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 ) ;
115
158
builder. push_item ( & WrDisplayItem :: Text ( item. item ) ) ;
116
159
builder. push_iter ( item. data . iter ( ) ) ;
117
160
IsContentful ( true )
118
161
} ,
119
162
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 ) ;
121
164
builder. push_item ( & WrDisplayItem :: Image ( item. item ) ) ;
122
165
IsContentful ( true )
123
166
} ,
124
167
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 ) ;
126
169
builder. push_item ( & WrDisplayItem :: RepeatingImage ( item. item ) ) ;
127
170
IsContentful ( true )
128
171
} ,
129
172
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 ) ;
131
174
if !item. data . is_empty ( ) {
132
175
builder. push_stops ( item. data . as_ref ( ) ) ;
133
176
}
134
177
builder. push_item ( & WrDisplayItem :: Border ( item. item ) ) ;
135
178
IsContentful ( false )
136
179
} ,
137
180
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 ) ;
139
182
builder. push_stops ( item. data . as_ref ( ) ) ;
140
183
builder. push_item ( & WrDisplayItem :: Gradient ( item. item ) ) ;
141
184
IsContentful ( false )
142
185
} ,
143
186
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 ) ;
145
188
builder. push_stops ( item. data . as_ref ( ) ) ;
146
189
builder. push_item ( & WrDisplayItem :: RadialGradient ( item. item ) ) ;
147
190
IsContentful ( false )
148
191
} ,
149
192
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 ) ;
151
194
builder. push_item ( & WrDisplayItem :: Line ( item. item ) ) ;
152
195
IsContentful ( false )
153
196
} ,
154
197
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 ) ;
156
199
builder. push_item ( & WrDisplayItem :: BoxShadow ( item. item ) ) ;
157
200
IsContentful ( false )
158
201
} ,
159
202
DisplayItem :: PushTextShadow ( ref mut item) => {
160
- let common = build_common_item_properties ( & item. base , state ) ;
203
+ let common = build_common_item_properties ( & item. base ) ;
161
204
builder. push_shadow (
162
205
& SpaceAndClipInfo {
163
206
spatial_id : common. spatial_id ,
@@ -173,7 +216,7 @@ impl DisplayItem {
173
216
IsContentful ( false )
174
217
} ,
175
218
DisplayItem :: Iframe ( ref mut item) => {
176
- let common = build_common_item_properties ( & item. base , state ) ;
219
+ let common = build_common_item_properties ( & item. base ) ;
177
220
builder. push_iframe (
178
221
item. bounds ,
179
222
common. clip_rect ,
@@ -212,19 +255,20 @@ impl DisplayItem {
212
255
( None , None ) => unreachable ! ( ) ,
213
256
} ;
214
257
215
- let spatial_id = builder. push_reference_frame (
258
+ let new_spatial_id = builder. push_reference_frame (
216
259
stacking_context. bounds . origin ,
217
260
state. active_spatial_id ,
218
261
stacking_context. transform_style ,
219
262
PropertyBinding :: Value ( transform) ,
220
263
ref_frame,
221
264
) ;
222
265
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) ;
225
269
226
270
bounds. origin = LayoutPoint :: zero ( ) ;
227
- spatial_id
271
+ new_spatial_id
228
272
} else {
229
273
state. active_spatial_id
230
274
} ;
@@ -264,21 +308,21 @@ impl DisplayItem {
264
308
IsContentful ( false )
265
309
} ,
266
310
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] ;
268
313
let item_rect = node. clip . main ;
269
314
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) ;
274
318
275
319
match node. node_type {
276
320
ClipScrollNodeType :: Clip ( clip_type) => {
277
321
let space_and_clip_info = SpaceAndClipInfo {
278
322
clip_id : parent_clip_id,
279
323
spatial_id : parent_spatial_id,
280
324
} ;
281
- let id = match clip_type {
325
+ let clip_id = match clip_type {
282
326
ClipType :: Rect => {
283
327
builder. define_clip_rect ( & space_and_clip_info, item_rect)
284
328
} ,
@@ -287,8 +331,8 @@ impl DisplayItem {
287
331
} ,
288
332
} ;
289
333
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 ) ;
292
336
} ,
293
337
ClipScrollNodeType :: ScrollFrame ( scroll_sensitivity, external_id) => {
294
338
let space_clip_info = builder. define_scroll_frame (
@@ -298,14 +342,13 @@ impl DisplayItem {
298
342
} ,
299
343
Some ( external_id) ,
300
344
node. content_rect ,
301
- node . clip . main ,
345
+ item_rect ,
302
346
scroll_sensitivity,
303
- webrender_api :: units :: LayoutVector2D :: zero ( ) ,
347
+ LayoutVector2D :: zero ( ) ,
304
348
) ;
305
349
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 ) ;
309
352
} ,
310
353
ClipScrollNodeType :: StickyFrame ( ref sticky_data) => {
311
354
// TODO: Add define_sticky_frame_with_parent to WebRender.
@@ -315,11 +358,11 @@ impl DisplayItem {
315
358
sticky_data. margins ,
316
359
sticky_data. vertical_offset_bounds ,
317
360
sticky_data. horizontal_offset_bounds ,
318
- webrender_api :: units :: LayoutVector2D :: zero ( ) ,
361
+ LayoutVector2D :: zero ( ) ,
319
362
) ;
320
363
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 ) ;
323
366
} ,
324
367
ClipScrollNodeType :: Placeholder => {
325
368
unreachable ! ( "Found DefineClipScrollNode for Placeholder type node." ) ;
@@ -330,21 +373,3 @@ impl DisplayItem {
330
373
}
331
374
}
332
375
}
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