mirror of
https://github.com/servo/servo.git
synced 2025-06-21 15:49:04 +01:00
Multiple display list support
This commit is contained in:
parent
7e3075522d
commit
0892fada74
7 changed files with 172 additions and 103 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue