auto merge of #1579 : ibnc/servo/multiple_display_lists, r=larsbergstrom

Fixes: #1538

Still needs to be rebased.
This commit is contained in:
bors-servo 2014-01-30 15:22:33 -08:00
commit 9352e1db00
7 changed files with 172 additions and 103 deletions

View file

@ -25,7 +25,8 @@ use layout::wrapper::{DomLeafSet, 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};
@ -92,7 +93,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,
@ -295,7 +296,7 @@ impl LayoutTask {
dom_leaf_set: MutexArc::new(DomLeafSet::new()),
flow_leaf_set: MutexArc::new(FlowLeafSet::new()),
display_list: None,
display_list_collection: None,
stylist: ~new_stylist(),
parallel_traversal: parallel_traversal,
profiler_chan: profiler_chan,
@ -620,14 +621,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);
@ -652,13 +655,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!");
@ -701,8 +704,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) => {
@ -721,8 +725,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) => {
@ -762,27 +767,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)
}
}
}