1010use crate :: display_list:: items:: { BaseDisplayItem , ClipScrollNode , ClipScrollNodeType , ClipType } ;
1111use crate :: display_list:: items:: { DisplayItem , DisplayList , StackingContextType } ;
1212use msg:: constellation_msg:: PipelineId ;
13- use webrender_api:: units:: LayoutPoint ;
13+ use webrender_api:: units:: { LayoutPoint , LayoutVector2D } ;
1414use 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