Multiple display list support

This commit is contained in:
Isabelle Carter 2014-01-22 09:57:25 -08:00
parent 7e3075522d
commit 0892fada74
7 changed files with 172 additions and 103 deletions

View file

@ -25,7 +25,8 @@ use layout::wrapper::LayoutNode;
use extra::arc::{Arc, MutexArc};
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::display_list::{ClipDisplayItemClass, DisplayItem, DisplayItemIterator, DisplayList};
use gfx::display_list::{ClipDisplayItemClass, DisplayItem, DisplayItemIterator};
use gfx::display_list::{DisplayList, DisplayListCollection};
use gfx::font_context::FontContextInfo;
use gfx::opts::Opts;
use gfx::render_task::{RenderMsg, RenderChan, RenderLayer};
@ -89,7 +90,7 @@ pub struct LayoutTask {
screen_size: Size2D<Au>,
/// A cached display list.
display_list: Option<Arc<DisplayList<OpaqueNode>>>,
display_list_collection: Option<Arc<DisplayListCollection<OpaqueNode>>>,
stylist: ~Stylist,
@ -273,7 +274,7 @@ impl LayoutTask {
screen_size: screen_size,
leaf_set: MutexArc::new(LeafSet::new()),
display_list: None,
display_list_collection: None,
stylist: ~new_stylist(),
parallel_traversal: parallel_traversal,
profiler_chan: profiler_chan,
@ -575,14 +576,16 @@ impl LayoutTask {
if data.goal == ReflowForDisplay {
profile(time::LayoutDispListBuildCategory, self.profiler_chan.clone(), || {
let root_size = flow::base(layout_root).position.size;
let display_list = ~RefCell::new(DisplayList::<OpaqueNode>::new());
let mut display_list_collection = DisplayListCollection::new();
display_list_collection.add_list(DisplayList::<OpaqueNode>::new());
let display_list_collection = ~RefCell::new(display_list_collection);
let dirty = flow::base(layout_root).position.clone();
let display_list_builder = DisplayListBuilder {
ctx: &layout_ctx,
};
layout_root.build_display_list(&display_list_builder, &dirty, display_list);
layout_root.build_display_lists(&display_list_builder, &dirty, 0u, display_list_collection);
let display_list = Arc::new(display_list.unwrap());
let display_list_collection = Arc::new(display_list_collection.unwrap());
let mut color = color::rgba(255.0, 255.0, 255.0, 255.0);
@ -607,13 +610,13 @@ impl LayoutTask {
}
let render_layer = RenderLayer {
display_list: display_list.clone(),
display_list_collection: display_list_collection.clone(),
size: Size2D(root_size.width.to_nearest_px() as uint,
root_size.height.to_nearest_px() as uint),
color: color
};
self.display_list = Some(display_list.clone());
self.display_list_collection = Some(display_list_collection.clone());
debug!("Layout done!");
@ -656,8 +659,9 @@ impl LayoutTask {
}
let mut rect = None;
let display_list = self.display_list.as_ref().unwrap().get();
union_boxes_for_node(&mut rect, display_list.iter(), node);
for display_list in self.display_list_collection.as_ref().unwrap().get().iter() {
union_boxes_for_node(&mut rect, display_list.iter(), node);
}
reply_chan.send(ContentBoxResponse(rect.unwrap_or(Au::zero_rect())))
}
ContentBoxesQuery(node, reply_chan) => {
@ -676,8 +680,9 @@ impl LayoutTask {
}
let mut boxes = ~[];
let display_list = self.display_list.as_ref().unwrap().get();
add_boxes_for_node(&mut boxes, display_list.iter(), node);
for display_list in self.display_list_collection.as_ref().unwrap().get().iter() {
add_boxes_for_node(&mut boxes, display_list.iter(), node);
}
reply_chan.send(ContentBoxesResponse(boxes))
}
HitTestQuery(_, point, reply_chan) => {
@ -717,27 +722,17 @@ impl LayoutTask {
let ret: Option<HitTestResponse> = None;
ret
}
let response = {
match self.display_list {
Some(ref list) => {
let display_list = list.get();
let (x, y) = (Au::from_frac_px(point.x as f64),
Au::from_frac_px(point.y as f64));
let resp = hit_test(x,y,display_list.list);
if resp.is_none() {
Err(())
} else {
Ok(resp.unwrap())
}
}
None => {
error!("Can't hit test: no display list");
Err(())
},
for display_list in self.display_list_collection.as_ref().unwrap().get().lists.rev_iter() {
let (x, y) = (Au::from_frac_px(point.x as f64),
Au::from_frac_px(point.y as f64));
let resp = hit_test(x,y,display_list.list);
if resp.is_some() {
reply_chan.send(Ok(resp.unwrap()));
return
}
};
}
reply_chan.send(Err(()));
reply_chan.send(response)
}
}
}