From 0892fada740f0030d544037621da8a20c7a60663 Mon Sep 17 00:00:00 2001 From: Isabelle Carter Date: Wed, 22 Jan 2014 09:57:25 -0800 Subject: [PATCH] Multiple display list support --- src/components/gfx/display_list.rs | 52 ++++++++++++++- src/components/gfx/render_task.rs | 7 ++- src/components/main/layout/block.rs | 31 ++++++--- src/components/main/layout/box_.rs | 77 ++++++++++++----------- src/components/main/layout/flow.rs | 38 ++++++----- src/components/main/layout/inline.rs | 13 ++-- src/components/main/layout/layout_task.rs | 57 ++++++++--------- 7 files changed, 172 insertions(+), 103 deletions(-) diff --git a/src/components/gfx/display_list.rs b/src/components/gfx/display_list.rs index 5c0df142302..bd61aa8aae8 100644 --- a/src/components/gfx/display_list.rs +++ b/src/components/gfx/display_list.rs @@ -27,11 +27,62 @@ use std::cast::transmute_region; use std::vec::VecIterator; use style::computed_values::border_style; +pub struct DisplayListCollection { + lists: ~[DisplayList] +} + +impl DisplayListCollection { + pub fn new() -> DisplayListCollection { + DisplayListCollection { + lists: ~[] + } + } + + pub fn iter<'a>(&'a self) -> DisplayListIterator<'a,E> { + ParentDisplayListIterator(self.lists.iter()) + } + + pub fn add_list(&mut self, list: DisplayList) { + self.lists.push(list); + } + + pub fn draw_lists_into_context(&self, render_context: &mut RenderContext) { + for list in self.lists.iter() { + list.draw_into_context(render_context); + } + debug!("{:?}", self.dump()); + } + + fn dump(&self) { + let mut index = 0; + for list in self.lists.iter() { + debug!("dumping display list {:d}:", index); + list.dump(); + index = index + 1; + } + } +} + /// A list of rendering operations to be performed. pub struct DisplayList { list: ~[DisplayItem] } +pub enum DisplayListIterator<'a,E> { + EmptyDisplayListIterator, + ParentDisplayListIterator(VecIterator<'a,DisplayList>), +} + +impl<'a,E> Iterator<&'a DisplayList> for DisplayListIterator<'a,E> { + #[inline] + fn next(&mut self) -> Option<&'a DisplayList> { + match *self { + EmptyDisplayListIterator => None, + ParentDisplayListIterator(ref mut subiterator) => subiterator.next(), + } + } +} + impl DisplayList { /// Creates a new display list. pub fn new() -> DisplayList { @@ -62,7 +113,6 @@ impl DisplayList { item.draw_into_context(render_context) } debug!("Ending display list."); - debug!("{:?}", self.dump()); } /// Returns a preorder iterator over the given display list. diff --git a/src/components/gfx/render_task.rs b/src/components/gfx/render_task.rs index a5fcf6b3340..82a5b04aec3 100644 --- a/src/components/gfx/render_task.rs +++ b/src/components/gfx/render_task.rs @@ -24,13 +24,14 @@ use std::comm::{Chan, Port, SharedChan}; use extra::arc::Arc; use buffer_map::BufferMap; -use display_list::DisplayList; +use font_context::{FontContext, FontContextInfo}; +use display_list::DisplayListCollection; use font_context::{FontContext, FontContextInfo}; use opts::Opts; use render_context::RenderContext; pub struct RenderLayer { - display_list: Arc>, + display_list_collection: Arc>, size: Size2D, color: Color } @@ -305,7 +306,7 @@ impl RenderTask { // Draw the display list. profile(time::RenderingDrawingCategory, self.profiler_chan.clone(), || { - render_layer.display_list.get().draw_into_context(&mut ctx); + render_layer.display_list_collection.get().draw_lists_into_context(&mut ctx); ctx.draw_target.flush(); }); } diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index e3388a22370..36898c91cd2 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -14,7 +14,7 @@ use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType}; use std::cell::RefCell; use geom::{Point2D, Rect, SideOffsets2D}; -use gfx::display_list::DisplayList; +use gfx::display_list::{DisplayList, DisplayListCollection}; use servo_util::geometry::Au; use servo_util::geometry; @@ -496,22 +496,31 @@ impl BlockFlow { &mut self, builder: &DisplayListBuilder, dirty: &Rect, - list: &RefCell>) - -> bool { + mut index: uint, + lists: &RefCell>) + -> uint { if self.is_float() { - return self.build_display_list_float(builder, dirty, list); + self.build_display_list_float(builder, dirty, index, lists); + return index; + } + + if self.is_fixed { + lists.with_mut(|lists| { + index = lists.lists.len(); + lists.add_list(DisplayList::::new()); + }); } let abs_rect = Rect(self.base.abs_position, self.base.position.size); if !abs_rect.intersects(dirty) { - return true; + return index; } debug!("build_display_list_block: adding display element"); // add box that starts block context for box_ in self.box_.iter() { - box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list) + box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, index, lists); } // TODO: handle any out-of-flow elements let this_position = self.base.abs_position; @@ -521,24 +530,26 @@ impl BlockFlow { child_base.abs_position = this_position + child_base.position.origin; } - false + index } pub fn build_display_list_float( &mut self, builder: &DisplayListBuilder, dirty: &Rect, - list: &RefCell>) + index: uint, + lists: &RefCell>) -> bool { let abs_rect = Rect(self.base.abs_position, self.base.position.size); if !abs_rect.intersects(dirty) { - return true + return true; } + let offset = self.base.abs_position + self.float.get_ref().rel_pos; // add box that starts block context for box_ in self.box_.iter() { - box_.build_display_list(builder, dirty, offset, (&*self) as &Flow, list) + box_.build_display_list(builder, dirty, offset, (&*self) as &Flow, index, lists); } diff --git a/src/components/main/layout/box_.rs b/src/components/main/layout/box_.rs index 3203d90301b..48388e4f627 100644 --- a/src/components/main/layout/box_.rs +++ b/src/components/main/layout/box_.rs @@ -9,10 +9,10 @@ use extra::arc::{MutexArc, Arc}; use geom::{Point2D, Rect, Size2D, SideOffsets2D}; use gfx::color::rgb; use gfx::display_list::{BaseDisplayItem, BorderDisplayItem, BorderDisplayItemClass}; -use gfx::display_list::{DisplayList, ImageDisplayItem, ImageDisplayItemClass}; +use gfx::display_list::{ImageDisplayItem, ImageDisplayItemClass}; use gfx::display_list::{SolidColorDisplayItem, SolidColorDisplayItemClass, TextDisplayItem}; use gfx::display_list::{TextDisplayItemClass, TextDisplayItemFlags, ClipDisplayItem}; -use gfx::display_list::{ClipDisplayItemClass}; +use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection}; use gfx::font::FontStyle; use gfx::text::text_run::TextRun; @@ -784,7 +784,8 @@ impl Box { pub fn paint_inline_background_border_if_applicable( &self, - list: &RefCell>, + index: uint, + lists: &RefCell>, absolute_bounds: &Rect, offset: &Point2D) { // FIXME: This causes a lot of background colors to be displayed when they are clearly not @@ -803,7 +804,7 @@ impl Box { info.style.get().Background.background_color); if !background_color.alpha.approx_eq(&0.0) { - list.with_mut(|list| { + lists.with_mut(|lists| { let solid_color_display_item = ~SolidColorDisplayItem { base: BaseDisplayItem { bounds: bg_rect.clone(), @@ -812,7 +813,7 @@ impl Box { color: background_color.to_gfx_color(), }; - list.append_item(SolidColorDisplayItemClass(solid_color_display_item)) + lists.lists[index].append_item(SolidColorDisplayItemClass(solid_color_display_item)) }); } let border = &info.border; @@ -834,7 +835,7 @@ impl Box { let left_style = style.Border.border_left_style; - list.with_mut(|list| { + lists.with_mut(|lists| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: bg_rect, @@ -851,7 +852,7 @@ impl Box { left_style) }; - list.append_item(BorderDisplayItemClass(border_display_item)) + lists.lists[index].append_item(BorderDisplayItemClass(border_display_item)) }); bg_rect.origin.x = bg_rect.origin.x + border.left; @@ -865,7 +866,8 @@ impl Box { /// necessary. pub fn paint_background_if_applicable( &self, - list: &RefCell>, + index: uint, + lists: &RefCell>, absolute_bounds: &Rect) { // FIXME: This causes a lot of background colors to be displayed when they are clearly not // needed. We could use display list optimization to clean this up, but it still seems @@ -874,7 +876,7 @@ impl Box { let style = self.style(); let background_color = style.resolve_color(style.Background.background_color); if !background_color.alpha.approx_eq(&0.0) { - list.with_mut(|list| { + lists.with_mut(|lists| { let solid_color_display_item = ~SolidColorDisplayItem { base: BaseDisplayItem { bounds: *absolute_bounds, @@ -883,8 +885,8 @@ impl Box { color: background_color.to_gfx_color(), }; - list.append_item(SolidColorDisplayItemClass(solid_color_display_item)) - }) + lists.lists[index].append_item(SolidColorDisplayItemClass(solid_color_display_item)) + }); } } @@ -892,7 +894,8 @@ impl Box { /// necessary. pub fn paint_borders_if_applicable( &self, - list: &RefCell>, + index: uint, + lists: &RefCell>, abs_bounds: &Rect) { // Fast path. let border = self.border.get(); @@ -916,7 +919,7 @@ impl Box { - self.noncontent_inline_right(); // Append the border to the display list. - list.with_mut(|list| { + lists.with_mut(|lists| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: abs_bounds, @@ -933,7 +936,7 @@ impl Box { left_style) }; - list.append_item(BorderDisplayItemClass(border_display_item)) + lists.lists[index].append_item(BorderDisplayItemClass(border_display_item)) }); } @@ -957,7 +960,8 @@ impl Box { dirty: &Rect, offset: Point2D, flow: &Flow, - list: &RefCell>) { + index: uint, + lists: &RefCell>) { let box_bounds = self.position.get(); let absolute_box_bounds = box_bounds.translate(&offset); debug!("Box::build_display_list at rel={}, abs={}: {:s}", @@ -975,14 +979,14 @@ impl Box { return; } - self.paint_inline_background_border_if_applicable(list, &absolute_box_bounds, &offset); + self.paint_inline_background_border_if_applicable(index, lists, &absolute_box_bounds, &offset); // Add the background to the list, if applicable. - self.paint_background_if_applicable(list, &absolute_box_bounds); + self.paint_background_if_applicable(index, lists, &absolute_box_bounds); match self.specific { UnscannedTextBox(_) => fail!("Shouldn't see unscanned boxes here."), ScannedTextBox(ref text_box) => { - list.with_mut(|list| { + lists.with_mut(|lists| { let item = ~ClipDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -991,7 +995,7 @@ impl Box { child_list: ~[], need_clip: false }; - list.append_item(ClipDisplayItemClass(item)); + lists.lists[index].append_item(ClipDisplayItemClass(item)); }); let text_color = self.style().Color.color.to_gfx_color(); @@ -1022,7 +1026,7 @@ impl Box { - self.noncontent_inline_right(); // Create the text box. - list.with_mut(|list| { + lists.with_mut(|lists| { let text_display_item = ~TextDisplayItem { base: BaseDisplayItem { bounds: bounds, @@ -1037,7 +1041,7 @@ impl Box { flags: text_flags, }; - list.append_item(TextDisplayItemClass(text_display_item)) + lists.lists[index].append_item(TextDisplayItemClass(text_display_item)); }); // Draw debug frames for text bounds. @@ -1048,7 +1052,7 @@ impl Box { // Compute the text box bounds and draw a border surrounding them. let debug_border = SideOffsets2D::new_all_same(Au::from_px(1)); - list.with_mut(|list| { + lists.with_mut(|lists| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -1059,7 +1063,7 @@ impl Box { style: SideOffsets2D::new_all_same(border_style::solid) }; - list.append_item(BorderDisplayItemClass(border_display_item)) + lists.lists[index].append_item(BorderDisplayItemClass(border_display_item)); }); // Draw a rectangle representing the baselines. @@ -1070,7 +1074,7 @@ impl Box { let baseline = Rect(absolute_box_bounds.origin + Point2D(Au(0), ascent), Size2D(absolute_box_bounds.size.width, Au(0))); - list.with_mut(|list| { + lists.with_mut(|lists| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: baseline, @@ -1081,12 +1085,12 @@ impl Box { style: SideOffsets2D::new_all_same(border_style::dashed) }; - list.append_item(BorderDisplayItemClass(border_display_item)) + lists.lists[index].append_item(BorderDisplayItemClass(border_display_item)); }); }); }, GenericBox | IframeBox(..) => { - list.with_mut(|list| { + lists.with_mut(|lists| { let item = ~ClipDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -1095,7 +1099,7 @@ impl Box { child_list: ~[], need_clip: self.needs_clip() }; - list.append_item(ClipDisplayItemClass(item)); + lists.lists[index].append_item(ClipDisplayItemClass(item)); }); // FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We @@ -1103,7 +1107,7 @@ impl Box { debug!("{:?}", { let debug_border = SideOffsets2D::new_all_same(Au::from_px(1)); - list.with_mut(|list| { + lists.with_mut(|lists| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -1114,12 +1118,12 @@ impl Box { style: SideOffsets2D::new_all_same(border_style::solid) }; - list.append_item(BorderDisplayItemClass(border_display_item)) + lists.lists[index].append_item(BorderDisplayItemClass(border_display_item)); }); }); }, ImageBox(ref image_box) => { - list.with_mut(|list| { + lists.with_mut(|lists| { let item = ~ClipDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -1128,7 +1132,7 @@ impl Box { child_list: ~[], need_clip: false }; - list.append_item(ClipDisplayItemClass(item)); + lists.lists[index].append_item(ClipDisplayItemClass(item)); }); let mut image_ref = image_box.image.borrow_mut(); @@ -1146,7 +1150,7 @@ impl Box { debug!("(building display list) building image box"); // Place the image into the display list. - list.with_mut(|list| { + lists.with_mut(|lists| { let image_display_item = ~ImageDisplayItem { base: BaseDisplayItem { bounds: bounds, @@ -1154,7 +1158,7 @@ impl Box { }, image: image.clone(), }; - list.append_item(ImageDisplayItemClass(image_display_item)); + lists.lists[index].append_item(ImageDisplayItemClass(image_display_item)); }); } None => { @@ -1169,7 +1173,7 @@ impl Box { debug!("{:?}", { let debug_border = SideOffsets2D::new_all_same(Au::from_px(1)); - list.with_mut(|list| { + lists.with_mut(|lists| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -1180,7 +1184,7 @@ impl Box { style: SideOffsets2D::new_all_same(border_style::solid) }; - list.append_item(BorderDisplayItemClass(border_display_item)) + lists.lists[index].append_item(BorderDisplayItemClass(border_display_item)) }); }); @@ -1207,7 +1211,8 @@ impl Box { // Add a border, if applicable. // // TODO: Outlines. - self.paint_borders_if_applicable(list, &absolute_box_bounds); + self.paint_borders_if_applicable(index, lists, &absolute_box_bounds); + } /// Returns the *minimum width* and *preferred width* of this box as defined by CSS 2.1. diff --git a/src/components/main/layout/flow.rs b/src/components/main/layout/flow.rs index 175baeddea6..7ab170ab4ea 100644 --- a/src/components/main/layout/flow.rs +++ b/src/components/main/layout/flow.rs @@ -41,7 +41,7 @@ use extra::dlist::{DList, DListIterator, MutDListIterator}; use extra::container::Deque; use geom::point::Point2D; use geom::rect::Rect; -use gfx::display_list::{ClipDisplayItemClass, DisplayList}; +use gfx::display_list::{ClipDisplayItemClass, DisplayListCollection, DisplayList}; use layout::display_list_builder::ToGfxColor; use gfx::color::Color; use servo_util::geometry::Au; @@ -206,12 +206,13 @@ pub trait MutableFlowUtils { /// Computes the overflow region for this flow. fn store_overflow(self, _: &mut LayoutContext); - /// Builds a display list for this flow and its children. - fn build_display_list( + /// builds the display lists + fn build_display_lists( self, builder: &DisplayListBuilder, dirty: &Rect, - list: &RefCell>) + index: uint, + mut list: &RefCell>) -> bool; } @@ -699,33 +700,37 @@ impl<'a> MutableFlowUtils for &'a mut Flow { mut_base(self).overflow = overflow } - fn build_display_list( + fn build_display_lists( self, builder: &DisplayListBuilder, dirty: &Rect, - list: &RefCell>) + mut index: uint, + lists: &RefCell>) -> bool { debug!("Flow: building display list for f{}", base(self).id); - match self.class() { - BlockFlowClass => self.as_block().build_display_list_block(builder, dirty, list), - InlineFlowClass => self.as_inline().build_display_list_inline(builder, dirty, list), + index = match self.class() { + BlockFlowClass => self.as_block().build_display_list_block(builder, dirty, index, lists), + InlineFlowClass => self.as_inline().build_display_list_inline(builder, dirty, index, lists), }; - if list.with_mut(|list| list.list.len() == 0) { + if lists.with_mut(|lists| lists.lists[index].list.len() == 0) { return true; } - let child_list = ~RefCell::new(DisplayList::new()); + let mut child_lists = DisplayListCollection::new(); + child_lists.add_list(DisplayList::new()); + let child_lists = RefCell::new(child_lists); for kid in child_iter(self) { - kid.build_display_list(builder,dirty,child_list); + kid.build_display_lists(builder, dirty, 0u, &child_lists); } - let mut child_list = Some(child_list.unwrap()); - list.with_mut(|list| { - let result = list.list.mut_rev_iter().position(|item| { + let mut child_lists = Some(child_lists.unwrap()); + lists.with_mut(|lists| { + let mut child_lists = child_lists.take_unwrap(); + let result = lists.lists[index].list.mut_rev_iter().position(|item| { match *item { ClipDisplayItemClass(ref mut item) => { - item.child_list.push_all_move(child_list.take_unwrap().list); + item.child_list.push_all_move(child_lists.lists.shift().list); true }, _ => false, @@ -736,6 +741,7 @@ impl<'a> MutableFlowUtils for &'a mut Flow { fail!("fail to find parent item"); } + lists.lists.push_all_move(child_lists.lists); }); true } diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs index 839b6686dbb..1a29866fe8f 100644 --- a/src/components/main/layout/inline.rs +++ b/src/components/main/layout/inline.rs @@ -16,7 +16,7 @@ use layout::float_context::{PlacementInfo, FloatLeft}; use extra::container::Deque; use extra::ringbuf::RingBuf; use geom::{Point2D, Rect, Size2D}; -use gfx::display_list::DisplayList; +use gfx::display_list::DisplayListCollection; use servo_util::geometry::Au; use servo_util::range::Range; use std::cell::RefCell; @@ -495,11 +495,12 @@ impl InlineFlow { &self, builder: &DisplayListBuilder, dirty: &Rect, - list: &RefCell>) - -> bool { + index: uint, + lists: &RefCell>) + -> uint { let abs_rect = Rect(self.base.abs_position, self.base.position.size); if !abs_rect.intersects(dirty) { - return true; + return index; } // TODO(#228): Once we form line boxes and have their cached bounds, we can be smarter and @@ -509,14 +510,14 @@ impl InlineFlow { self.boxes.len()); for box_ in self.boxes.iter() { - box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list) + box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, index, lists); } // TODO(#225): Should `inline-block` elements have flows as children of the inline flow or // should the flow be nested inside the box somehow? // For now, don't traverse the subtree rooted here - true + index } /// Returns the relative offset from the baseline for this box, taking into account the value diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index 61af5250de1..7ed6d84570d 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -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, /// A cached display list. - display_list: Option>>, + display_list_collection: Option>>, 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::::new()); + let mut display_list_collection = DisplayListCollection::new(); + display_list_collection.add_list(DisplayList::::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 = 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) } } }