From aefa941626514dd27c378fee41bd8231f57ab5d3 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 28 Jun 2016 16:38:14 +0200 Subject: [PATCH 1/4] Pass a straight Vec to DisplayList::new(). There is no reason to have a runtime check here. --- components/gfx/display_list/mod.rs | 7 +------ components/layout_thread/lib.rs | 3 +-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index ac93adcca1f..1c2c7cca579 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -215,13 +215,8 @@ pub struct DisplayList { impl DisplayList { pub fn new(mut root_stacking_context: StackingContext, - items: &mut Option>) + items: Vec) -> DisplayList { - let items = match items.take() { - Some(items) => items, - None => panic!("Tried to create empty display list."), - }; - let mut offsets = FnvHashMap(HashMap::with_hasher(Default::default())); DisplayList::sort_and_count_stacking_contexts(&mut root_stacking_context, &mut offsets, 0); diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index e47670f99c1..ff42af63ee5 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -918,8 +918,7 @@ impl LayoutThread { root_background_color)); rw_data.display_list = - Some(Arc::new(DisplayList::new(root_stacking_context, - &mut Some(display_list_entries)))) + Some(Arc::new(DisplayList::new(root_stacking_context, display_list_entries))) } if data.goal == ReflowGoal::ForDisplay { From ae064dc7c1554b8cf0a8cae5b43c124031907dfb Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 28 Jun 2016 16:38:41 +0200 Subject: [PATCH 2/4] Simplify the code setting hit_test_response. --- components/layout_thread/lib.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index ff42af63ee5..6d46500621b 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -1156,17 +1156,11 @@ impl LayoutThread { }, ReflowQueryType::HitTestQuery(point, update_cursor) => { let point = Point2D::new(Au::from_f32_px(point.x), Au::from_f32_px(point.y)); - let result = match rw_data.display_list { - None => panic!("Tried to hit test with no display list"), - Some(ref display_list) => { - display_list.hit_test(&point, &rw_data.stacking_context_scroll_offsets) - } - }; - rw_data.hit_test_response = if result.len() > 0 { - (Some(result[0]), update_cursor) - } else { - (None, update_cursor) - }; + let result = rw_data.display_list + .as_ref() + .expect("Tried to hit test with no display list") + .hit_test(&point, &rw_data.stacking_context_scroll_offsets); + rw_data.hit_test_response = (result.get(0).cloned(), update_cursor); }, ReflowQueryType::NodeGeometryQuery(node) => { let node = unsafe { ServoLayoutNode::new(&node) }; From 4e8ff4f9bcbc014d2f7341d706d644e7c88765f1 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 28 Jun 2016 16:58:36 +0200 Subject: [PATCH 3/4] Return the result from DisplayItem::hit_test(). --- components/gfx/display_list/mod.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 1c2c7cca579..988bfa5af96 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -636,13 +636,17 @@ impl StackingContext { for child in self.children.iter() { while let Some(item) = traversal.advance(self) { - item.hit_test(point, result); + if let Some(meta) = item.hit_test(point) { + result.push(meta); + } } child.hit_test(traversal, &point, scroll_offsets, result); } while let Some(item) = traversal.advance(self) { - item.hit_test(point, result); + if let Some(meta) = item.hit_test(point) { + result.push(meta); + } } } @@ -1331,21 +1335,21 @@ impl DisplayItem { println!("{}+ {:?}", indent, self); } - fn hit_test(&self, point: Point2D, result: &mut Vec) { + fn hit_test(&self, point: Point2D) -> Option { // TODO(pcwalton): Use a precise algorithm here. This will allow us to properly hit // test elements with `border-radius`, for example. let base_item = self.base(); if !base_item.clip.might_intersect_point(&point) { // Clipped out. - return; + return None; } if !self.bounds().contains(&point) { // Can't possibly hit. - return; + return None; } if base_item.metadata.pointing.is_none() { // `pointer-events` is `none`. Ignore this item. - return; + return None; } match *self { @@ -1364,18 +1368,17 @@ impl DisplayItem { (border.border_widths.top + border.border_widths.bottom))); if interior_rect.contains(&point) { - return; + return None; } } DisplayItem::BoxShadowClass(_) => { // Box shadows can never be hit. - return + return None; } _ => {} } - // We found a hit! - result.push(base_item.metadata); + Some(base_item.metadata) } } From 6b981039d083e66445c1f8df65f6025febdb8238 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 29 Jun 2016 09:46:45 +0200 Subject: [PATCH 4/4] Avoid the Vec reversal in DisplayList::hit_test. --- components/gfx/display_list/mod.rs | 6 ++---- components/layout/query.rs | 1 + components/layout_thread/lib.rs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 988bfa5af96..25b7c46075f 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -480,9 +480,8 @@ impl DisplayList { &draw_target, &stacking_context.filters, stacking_context.blend_mode); } - /// Places all nodes containing the point of interest into `result`, topmost first. Respects - /// the `pointer-events` CSS property If `topmost_only` is true, stops after placing one node - /// into the list. `result` must be empty upon entry to this function. + /// Return all nodes containing the point of interest, bottommost first, + /// and respecting the `pointer-events` CSS property. pub fn hit_test(&self, point: &Point2D, scroll_offsets: &ScrollOffsetMap) -> Vec { let mut traversal = DisplayListTraversal { @@ -492,7 +491,6 @@ impl DisplayList { }; let mut result = Vec::new(); self.root_stacking_context.hit_test(&mut traversal, point, scroll_offsets, &mut result); - result.reverse(); result } } diff --git a/components/layout/query.rs b/components/layout/query.rs index f5735c97877..ea22bd966d5 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -150,6 +150,7 @@ impl LayoutRPC for LayoutRPCImpl { }; nodes_from_point_list.iter() + .rev() .map(|metadata| metadata.node.to_untrusted_node_address()) .collect() } diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 6d46500621b..b33a5c56eb1 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -1160,7 +1160,7 @@ impl LayoutThread { .as_ref() .expect("Tried to hit test with no display list") .hit_test(&point, &rw_data.stacking_context_scroll_offsets); - rw_data.hit_test_response = (result.get(0).cloned(), update_cursor); + rw_data.hit_test_response = (result.last().cloned(), update_cursor); }, ReflowQueryType::NodeGeometryQuery(node) => { let node = unsafe { ServoLayoutNode::new(&node) };