Auto merge of #7392 - mrobinson:layered-separate, r=pcwalton

Split out layered child stacking contexts in display lists

This patch is in preparation for more dynamic layerization of the
pieces of display lists. It also prevents having to sort the children
by z-index multiple times.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7392)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-08-26 11:38:34 -06:00
commit fa5ad1c6b4
2 changed files with 42 additions and 20 deletions

View file

@ -98,6 +98,8 @@ pub struct DisplayList {
pub outlines: LinkedList<DisplayItem>, pub outlines: LinkedList<DisplayItem>,
/// Child stacking contexts. /// Child stacking contexts.
pub children: LinkedList<Arc<StackingContext>>, pub children: LinkedList<Arc<StackingContext>>,
/// Child stacking contexts with their own layers.
pub layered_children: LinkedList<Arc<StackingContext>>,
} }
impl DisplayList { impl DisplayList {
@ -112,6 +114,28 @@ impl DisplayList {
positioned_content: LinkedList::new(), positioned_content: LinkedList::new(),
outlines: LinkedList::new(), outlines: LinkedList::new(),
children: LinkedList::new(), children: LinkedList::new(),
layered_children: LinkedList::new(),
}
}
/// Sort all children by their z-index and split layered children into their own
/// section of the display list.
/// TODO(mrobinson): This should properly handle unlayered children that are on
/// top of layered children.
#[inline]
pub fn sort_and_layerize_children(&mut self) {
let mut children: SmallVec<[Arc<StackingContext>; 8]> = SmallVec::new();
while let Some(stacking_context) = self.children.pop_front() {
children.push(stacking_context);
}
children.sort_by(|this, other| this.z_index.cmp(&other.z_index));
for stacking_context in children.into_iter() {
if stacking_context.layer.is_some() {
self.layered_children.push_back(stacking_context);
} else {
self.children.push_back(stacking_context);
}
} }
} }
@ -126,6 +150,7 @@ impl DisplayList {
self.positioned_content.append(&mut other.positioned_content); self.positioned_content.append(&mut other.positioned_content);
self.outlines.append(&mut other.outlines); self.outlines.append(&mut other.outlines);
self.children.append(&mut other.children); self.children.append(&mut other.children);
self.layered_children.append(&mut other.children);
} }
/// Merges all display items from all non-float stacking levels to the `float` stacking level. /// Merges all display items from all non-float stacking levels to the `float` stacking level.
@ -222,6 +247,15 @@ impl DisplayList {
&indentation[0..MIN_INDENTATION_LENGTH]); &indentation[0..MIN_INDENTATION_LENGTH]);
} }
} }
if !self.layered_children.is_empty() {
println!("{} Layered children stacking contexts list length: {}",
indentation,
self.layered_children.len());
for stacking_context in &self.layered_children {
stacking_context.print(indentation.clone() +
&indentation[0..MIN_INDENTATION_LENGTH]);
}
}
} }
} }
@ -266,7 +300,7 @@ pub struct StackingContext {
impl StackingContext { impl StackingContext {
/// Creates a new stacking context. /// Creates a new stacking context.
#[inline] #[inline]
pub fn new(display_list: Box<DisplayList>, pub fn new(mut display_list: Box<DisplayList>,
bounds: &Rect<Au>, bounds: &Rect<Au>,
overflow: &Rect<Au>, overflow: &Rect<Au>,
z_index: i32, z_index: i32,
@ -278,6 +312,7 @@ impl StackingContext {
establishes_3d_context: bool, establishes_3d_context: bool,
scrolls_overflow_area: bool) scrolls_overflow_area: bool)
-> StackingContext { -> StackingContext {
display_list.sort_and_layerize_children();
StackingContext { StackingContext {
display_list: display_list, display_list: display_list,
bounds: *bounds, bounds: *bounds,
@ -317,15 +352,6 @@ impl StackingContext {
display_list.print_items("####".to_owned()); display_list.print_items("####".to_owned());
} }
// Sort positioned children according to z-index.
let mut positioned_children: SmallVec<[Arc<StackingContext>; 8]> = SmallVec::new();
for kid in &display_list.children {
if kid.layer.is_none() {
positioned_children.push((*kid).clone());
}
}
positioned_children.sort_by(|this, other| this.z_index.cmp(&other.z_index));
// Set up our clip rect and transform. // Set up our clip rect and transform.
let old_transform = paint_subcontext.draw_target.get_transform(); let old_transform = paint_subcontext.draw_target.get_transform();
let xform_2d = Matrix2D::new(transform.m11, transform.m12, let xform_2d = Matrix2D::new(transform.m11, transform.m12,
@ -340,7 +366,7 @@ impl StackingContext {
} }
// Step 3: Positioned descendants with negative z-indices. // Step 3: Positioned descendants with negative z-indices.
for positioned_kid in &*positioned_children { for positioned_kid in &display_list.children {
if positioned_kid.z_index >= 0 { if positioned_kid.z_index >= 0 {
break break
} }
@ -382,7 +408,7 @@ impl StackingContext {
} }
// Step 9: Positioned descendants with nonnegative, numeric z-indices. // Step 9: Positioned descendants with nonnegative, numeric z-indices.
for positioned_kid in &*positioned_children { for positioned_kid in &self.display_list.children {
if positioned_kid.z_index < 0 { if positioned_kid.z_index < 0 {
continue continue
} }
@ -614,7 +640,7 @@ pub fn find_stacking_context_with_layer_id(this: &Arc<StackingContext>, layer_id
Some(_) | None => {} Some(_) | None => {}
} }
for kid in &this.display_list.children { for kid in &this.display_list.layered_children {
match find_stacking_context_with_layer_id(kid, layer_id) { match find_stacking_context_with_layer_id(kid, layer_id) {
Some(stacking_context) => return Some(stacking_context), Some(stacking_context) => return Some(stacking_context),
None => {} None => {}

View file

@ -28,7 +28,6 @@ use profile_traits::mem::{self, ReportsChan};
use profile_traits::time::{self, profile}; use profile_traits::time::{self, profile};
use rand::{self, Rng}; use rand::{self, Rng};
use skia::gl_context::GLContext; use skia::gl_context::GLContext;
use smallvec::SmallVec;
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::collections::HashMap; use std::collections::HashMap;
use std::mem as std_mem; use std::mem as std_mem;
@ -394,14 +393,11 @@ impl<C> PaintTask<C> where C: PaintListener + Send + 'static {
} }
}; };
// Sort positioned children according to z-index. for kid in stacking_context.display_list.children.iter() {
let mut positioned_children: SmallVec<[Arc<StackingContext>; 8]> = SmallVec::new(); build(properties, &**kid, &page_position, &transform, &perspective, next_parent_id)
for kid in &stacking_context.display_list.children {
positioned_children.push((*kid).clone());
} }
positioned_children.sort_by(|this, other| this.z_index.cmp(&other.z_index));
for kid in positioned_children.iter() { for kid in stacking_context.display_list.layered_children.iter() {
build(properties, &**kid, &page_position, &transform, &perspective, next_parent_id) build(properties, &**kid, &page_position, &transform, &perspective, next_parent_id)
} }
} }