diff options
author | Martin Robinson <mrobinson@igalia.com> | 2016-10-10 19:36:52 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2016-10-13 09:50:45 +0200 |
commit | be62ad71176d66648f2aa754477668f7742f296b (patch) | |
tree | a8f68374f03b787e1c2c77623810431c2c01224e /components/gfx/paint_thread.rs | |
parent | b110eb394ebeb6528240ac3d01e17b0577a9dfbd (diff) | |
download | servo-be62ad71176d66648f2aa754477668f7742f296b.tar.gz servo-be62ad71176d66648f2aa754477668f7742f296b.zip |
Integrate stacking contexts into the display list
Integrate stacking contexts into the display list by adding two new
entry types, PushStackingContext and PopStackingContext. This allows us
to eliminate the ugly offsets map that DisplayList used to contain
and seems to speed up display list construction. With this approach
we are able to also completely prune pseudo-stacking contexts from the
final display list and remove their (minimal) overhead from display
list traversal Traversing the display list is also a bit simpler now.
Additionally, this will allow easier editing of the DisplayList to
properly support scrolling roots. The push/pop entries can be
duplicated to clone complex StackingContext trees between layers.
Diffstat (limited to 'components/gfx/paint_thread.rs')
-rw-r--r-- | components/gfx/paint_thread.rs | 78 |
1 files changed, 29 insertions, 49 deletions
diff --git a/components/gfx/paint_thread.rs b/components/gfx/paint_thread.rs index 13754a3cf15..a17a0ee2bb7 100644 --- a/components/gfx/paint_thread.rs +++ b/components/gfx/paint_thread.rs @@ -158,27 +158,20 @@ struct LayerCreator { layers: Vec<PaintLayer>, layer_details_stack: Vec<PaintLayer>, current_layer: Option<PaintLayer>, - current_item_index: usize, } impl LayerCreator { - fn create_layers_with_display_list(display_list: &DisplayList) -> Vec<PaintLayer> { + fn create_layers_with_display_list<'a>(display_list: &'a DisplayList) -> Vec<PaintLayer> { let mut layer_creator = LayerCreator { layers: Vec::new(), layer_details_stack: Vec::new(), current_layer: None, - current_item_index: 0, }; - let mut traversal = DisplayListTraversal { - display_list: display_list, - current_item_index: 0, - last_item_index: display_list.list.len(), - }; - layer_creator.create_layers_for_stacking_context(&display_list.root_stacking_context, - &mut traversal, - &Point2D::zero(), - &Matrix4D::identity(), - &Matrix4D::identity()); + let mut traversal = DisplayListTraversal::new(display_list); + layer_creator.process_stacking_context_items(&mut traversal, + &Point2D::zero(), + &Matrix4D::identity(), + &Matrix4D::identity()); layer_creator.layers } @@ -222,8 +215,7 @@ impl LayerCreator { // // The origin for child layers which might be somewhere other than the // layer origin, since layer boundaries are expanded to include overflow. - self.process_stacking_context_items(stacking_context, - traversal, + self.process_stacking_context_items(traversal, &-stacking_context.overflow.origin, &Matrix4D::identity(), &Matrix4D::identity()); @@ -232,52 +224,42 @@ impl LayerCreator { return; } - if stacking_context.context_type != StackingContextType::Real { - self.process_stacking_context_items(stacking_context, - traversal, - parent_origin, - transform, - perspective); - return; - } - - self.process_stacking_context_items(stacking_context, - traversal, + debug_assert!(stacking_context.context_type == StackingContextType::Real); + self.process_stacking_context_items(traversal, &(stacking_context.bounds.origin + *parent_origin), &transform.pre_mul(&stacking_context.transform), &perspective.pre_mul(&stacking_context.perspective)); } fn process_stacking_context_items<'a>(&mut self, - stacking_context: &StackingContext, traversal: &mut DisplayListTraversal<'a>, parent_origin: &Point2D<Au>, transform: &Matrix4D<f32>, perspective: &Matrix4D<f32>) { - for kid in stacking_context.children() { - while let Some(item) = traversal.advance(stacking_context) { - self.create_layers_for_item(item, - parent_origin, - transform, - perspective); + while let Some(item) = traversal.next() { + match item { + &DisplayItem::PushStackingContextClass(ref stacking_context_item) => { + self.create_layers_for_stacking_context(&stacking_context_item.stacking_context, + traversal, + parent_origin, + transform, + perspective); + } + &DisplayItem::PopStackingContextClass(_) => return, + _ => { + self.create_layers_for_item(traversal.previous_item_id(), + item, + parent_origin, + transform, + perspective); + } } - self.create_layers_for_stacking_context(kid, - traversal, - parent_origin, - transform, - perspective); - } - - while let Some(item) = traversal.advance(stacking_context) { - self.create_layers_for_item(item, - parent_origin, - transform, - perspective); } } fn create_layers_for_item<'a>(&mut self, + current_item_index: usize, item: &DisplayItem, parent_origin: &Point2D<Au>, transform: &Matrix4D<f32>, @@ -294,9 +276,8 @@ impl LayerCreator { perspective, self.current_parent_layer_id(), self.current_parent_stacking_context_id(), - self.current_item_index); + current_item_index); self.layers.push(layer); - self.current_item_index += 1; return; } @@ -318,9 +299,8 @@ impl LayerCreator { } if let Some(ref mut current_layer) = self.current_layer { - current_layer.add_item(self.current_item_index); + current_layer.add_item(current_item_index); } - self.current_item_index += 1; } } |