Index: components/viz/host/hit_test/hit_test_query_unittest.cc |
diff --git a/components/viz/host/hit_test/hit_test_query_unittest.cc b/components/viz/host/hit_test/hit_test_query_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..35182b43d13407b3f5e44a4cef85ecb928dda94e |
--- /dev/null |
+++ b/components/viz/host/hit_test/hit_test_query_unittest.cc |
@@ -0,0 +1,526 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "components/viz/host/hit_test/hit_test_query.h" |
+ |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace viz { |
+namespace hit_test { |
+namespace test { |
+ |
+class HitTestQueryTest : public testing::Test { |
+ public: |
+ HitTestQueryTest() {} |
+ ~HitTestQueryTest() override {} |
+ |
+ HitTestQuery hit_test_query_; |
+ |
+ private: |
+ // testing::Test: |
+ void SetUp() override {} |
+ void TearDown() override {} |
+ |
+ DISALLOW_COPY_AND_ASSIGN(HitTestQueryTest); |
+}; |
+ |
+// One surface. |
+// |
+// +e---------+ |
+// | | |
+// | | |
+// | | |
+// +----------+ |
+// |
+TEST_F(HitTestQueryTest, OneSurface) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ gfx::Rect e_bounds = gfx::Rect(0, 0, 600, 600); |
+ gfx::Transform transform_e_to_e; |
+ DisplayHitTestDataList display_hit_test_data_list = { |
+ {e_id, e_bounds, transform_e_to_e, 1 /* HIT_TEST_MINE */, 0} // e |
+ }; |
+ hit_test_query_.set_display_hit_test_data_list(display_hit_test_data_list); |
+ |
+ // All points are in e's coordinate system when we reach this case. |
+ gfx::Point point1(1, 1); |
+ gfx::Point point2(600, 600); |
+ gfx::Point point3(0, 0); |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id, target1.id); |
+ EXPECT_EQ(point1, target1.location_in_target); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ // point2 is on the bounds of e so no target found. |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(cc::FrameSinkId(), target2.id); |
+ EXPECT_EQ(gfx::Point(), target2.location_in_target); |
+ EXPECT_FALSE(target2.flags); |
+ |
+ // There's a valid Target for point3, see Rect::Contains. |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(e_id, target3.id); |
+ EXPECT_EQ(point3, target3.location_in_target); |
+ EXPECT_TRUE(target3.flags); |
+} |
+ |
+// One embedder with two children. |
+// |
+// +e------------+ Point maps to |
+// | +c1-+ +c2---| ----- ------- |
+// |1| | | | 1 e |
+// | | 2 | | 3 | 4 2 c1 |
+// | +---+ | | 3 c2 |
+// +-------------+ 4 none |
+// |
+TEST_F(HitTestQueryTest, OneEmbedderTwoChildren) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ cc::FrameSinkId c1_id = cc::FrameSinkId(2, 2); |
+ cc::FrameSinkId c2_id = cc::FrameSinkId(3, 3); |
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
+ gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 200, 200); |
+ gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 400, 400); |
+ gfx::Transform transform_e_to_e, transform_e_to_c1, transform_e_to_c2; |
+ transform_e_to_c1.Translate(-100, -100); |
+ transform_e_to_c2.Translate(-300, -300); |
+ DisplayHitTestDataList display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 2}, // e |
+ {c1_id, c1_bounds_in_e, transform_e_to_c1, 1 /* HIT_TEST_MINE */, |
+ 0}, // c1 |
+ {c2_id, c2_bounds_in_e, transform_e_to_c2, 1 /* HIT_TEST_MINE */, |
+ 0} // c2 |
+ }; |
+ hit_test_query_.set_display_hit_test_data_list(display_hit_test_data_list); |
+ |
+ // All points are in e's coordinate system when we reach this case. |
+ gfx::Point point1(99, 200); |
+ gfx::Point point2(150, 150); |
+ gfx::Point point3(400, 400); |
+ gfx::Point point4(650, 350); |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id, target1.id); |
+ EXPECT_EQ(point1, target1.location_in_target); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(c1_id, target2.id); |
+ EXPECT_EQ(gfx::Point(50, 50), target2.location_in_target); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(c2_id, target3.id); |
+ EXPECT_EQ(gfx::Point(100, 100), target3.location_in_target); |
+ EXPECT_TRUE(target3.flags); |
+ |
+ Target target4 = hit_test_query_.FindTargetForLocation(point4); |
+ EXPECT_EQ(cc::FrameSinkId(), target4.id); |
+ EXPECT_EQ(gfx::Point(), target4.location_in_target); |
+ EXPECT_FALSE(target4.flags); |
+} |
+ |
+// One embedder with a rotated child. |
+TEST_F(HitTestQueryTest, OneEmbedderRotatedChild) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ cc::FrameSinkId c_id = cc::FrameSinkId(2, 2); |
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
+ gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 1000, 1000); |
+ gfx::Transform transform_e_to_e, transform_e_to_c; |
+ transform_e_to_c.Translate(-100, -100); |
+ transform_e_to_c.Skew(2, 3); |
+ transform_e_to_c.Scale(.5f, .7f); |
+ |
+ DisplayHitTestDataList display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 1}, // e |
+ {c_id, c_bounds_in_e, transform_e_to_c, 1 /* HIT_TEST_MINE */, 0} // c |
+ }; |
+ hit_test_query_.set_display_hit_test_data_list(display_hit_test_data_list); |
+ |
+ // All points are in e's coordinate system when we reach this case. |
+ gfx::Point point1(150, 120); // Point(-22, -12) after transform. |
+ gfx::Point point2(550, 400); // Point(185, 194) after transform. |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id, target1.id); |
+ EXPECT_EQ(point1, target1.location_in_target); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(c_id, target2.id); |
+ EXPECT_EQ(gfx::Point(185, 194), target2.location_in_target); |
+ EXPECT_TRUE(target2.flags); |
+} |
+ |
+// One embedder with a clipped child with a tab and transparent background. |
+// |
+// +e-------------+ |
+// | +c---------| Point maps to |
+// | 1 |+a--+ | ----- ------- |
+// | || 2 | 3 | 1 e |
+// | |+b--------| 2 a |
+// | || | 3 e ( transparent area in c ) |
+// | || 4 | 4 b |
+// +--------------+ |
+// |
+TEST_F(HitTestQueryTest, ClippedChildWithTabAndTransparentBackground) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ cc::FrameSinkId c_id = cc::FrameSinkId(2, 2); |
+ cc::FrameSinkId a_id = cc::FrameSinkId(3, 3); |
+ cc::FrameSinkId b_id = cc::FrameSinkId(4, 4); |
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
+ gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
+ gfx::Rect a_bounds_in_c = gfx::Rect(0, 0, 200, 100); |
+ gfx::Rect b_bounds_in_c = gfx::Rect(0, 0, 800, 600); |
+ gfx::Transform transform_e_to_e, transform_e_to_c, transform_c_to_a, |
+ transform_c_to_b; |
+ transform_e_to_c.Translate(-200, -100); |
+ transform_c_to_b.Translate(0, -100); |
+ DisplayHitTestDataList display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 3}, // e |
+ {c_id, c_bounds_in_e, transform_e_to_c, 0 /* HIT_TEST_IGNORE */, 2}, // c |
+ {a_id, a_bounds_in_c, transform_c_to_a, 1 /* HIT_TEST_MINE */, 0}, // a |
+ {b_id, b_bounds_in_c, transform_c_to_b, 1 /* HIT_TEST_MINE */, 0} // b |
+ }; |
+ hit_test_query_.set_display_hit_test_data_list(display_hit_test_data_list); |
+ |
+ // All points are in e's coordinate system when we reach this case. |
+ gfx::Point point1(1, 1); |
+ gfx::Point point2(202, 102); |
+ gfx::Point point3(403, 103); |
+ gfx::Point point4(202, 202); |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id, target1.id); |
+ EXPECT_EQ(point1, target1.location_in_target); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(a_id, target2.id); |
+ EXPECT_EQ(gfx::Point(2, 2), target2.location_in_target); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(e_id, target3.id); |
+ EXPECT_EQ(point3, target3.location_in_target); |
+ EXPECT_TRUE(target3.flags); |
+ |
+ Target target4 = hit_test_query_.FindTargetForLocation(point4); |
+ EXPECT_EQ(b_id, target4.id); |
+ EXPECT_EQ(gfx::Point(2, 2), target4.location_in_target); |
+ EXPECT_TRUE(target4.flags); |
+} |
+ |
+// One embedder with a clipped child with a tab and transparent background, and |
+// a child d under that. |
+// |
+// +e-------------+ |
+// | +d------| |
+// | +c-|-------| Point maps to |
+// | 1 |+a|-+ | ----- ------- |
+// | || 2 | 3 | 1 e |
+// | |+b|-------| 2 a |
+// | || | | 3 d |
+// | || | 4 | 4 b |
+// +--------------+ |
+// |
+TEST_F(HitTestQueryTest, ClippedChildWithChildUnderneath) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ cc::FrameSinkId c_id = cc::FrameSinkId(2, 2); |
+ cc::FrameSinkId a_id = cc::FrameSinkId(3, 3); |
+ cc::FrameSinkId b_id = cc::FrameSinkId(4, 4); |
+ cc::FrameSinkId d_id = cc::FrameSinkId(5, 5); |
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
+ gfx::Rect c_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
+ gfx::Rect a_bounds_in_c = gfx::Rect(0, 0, 200, 100); |
+ gfx::Rect b_bounds_in_c = gfx::Rect(0, 0, 800, 600); |
+ gfx::Rect d_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
+ gfx::Transform transform_e_to_e, transform_e_to_c, transform_c_to_a, |
+ transform_c_to_b, transform_e_to_d; |
+ transform_e_to_c.Translate(-200, -100); |
+ transform_c_to_b.Translate(0, -100); |
+ transform_e_to_d.Translate(-400, -50); |
+ DisplayHitTestDataList display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 4}, // e |
+ {c_id, c_bounds_in_e, transform_e_to_c, 0 /* HIT_TEST_IGNORE */, 2}, // c |
+ {a_id, a_bounds_in_c, transform_c_to_a, 1 /* HIT_TEST_MINE */, 0}, // a |
+ {b_id, b_bounds_in_c, transform_c_to_b, 1 /* HIT_TEST_MINE */, 0}, // b |
+ {d_id, d_bounds_in_e, transform_e_to_d, 1 /* HIT_TEST_MINE */, 0} // d |
+ }; |
+ hit_test_query_.set_display_hit_test_data_list(display_hit_test_data_list); |
+ |
+ // All points are in e's coordinate system when we reach this case. |
+ gfx::Point point1(1, 1); |
+ gfx::Point point2(202, 102); |
+ gfx::Point point3(450, 150); |
+ gfx::Point point4(202, 202); |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id, target1.id); |
+ EXPECT_EQ(point1, target1.location_in_target); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(a_id, target2.id); |
+ EXPECT_EQ(gfx::Point(2, 2), target2.location_in_target); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(d_id, target3.id); |
+ EXPECT_EQ(gfx::Point(50, 100), target3.location_in_target); |
+ EXPECT_TRUE(target3.flags); |
+ |
+ Target target4 = hit_test_query_.FindTargetForLocation(point4); |
+ EXPECT_EQ(b_id, target4.id); |
+ EXPECT_EQ(gfx::Point(2, 2), target4.location_in_target); |
+ EXPECT_TRUE(target4.flags); |
+} |
+ |
+// One embedder with two clipped children with a tab and transparent background. |
+// |
+// +e-------------+ |
+// | +c1--------| Point maps to |
+// | 1 |+a--+ | ----- ------- |
+// | || 2 | 3 | 1 e |
+// | |+b--------| 2 a |
+// | || | 3 e ( transparent area in c1 ) |
+// | || 4 | 4 b |
+// | +----------| 5 g |
+// | +c2--------| 6 e ( transparent area in c2 ) |
+// | |+g--+ | 7 h |
+// | || 5 | 6 | |
+// | |+h--------| |
+// | || | |
+// | || 7 | |
+// +--------------+ |
+// |
+TEST_F(HitTestQueryTest, ClippedChildrenWithTabAndTransparentBackground) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ cc::FrameSinkId c1_id = cc::FrameSinkId(2, 2); |
+ cc::FrameSinkId a_id = cc::FrameSinkId(3, 3); |
+ cc::FrameSinkId b_id = cc::FrameSinkId(4, 4); |
+ cc::FrameSinkId c2_id = cc::FrameSinkId(5, 5); |
+ cc::FrameSinkId g_id = cc::FrameSinkId(6, 6); |
+ cc::FrameSinkId h_id = cc::FrameSinkId(7, 7); |
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 600, 1200); |
+ gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 800, 500); |
+ gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 200, 100); |
+ gfx::Rect b_bounds_in_c1 = gfx::Rect(0, 0, 800, 400); |
+ gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 800, 500); |
+ gfx::Rect g_bounds_in_c2 = gfx::Rect(0, 0, 200, 100); |
+ gfx::Rect h_bounds_in_c2 = gfx::Rect(0, 0, 800, 800); |
+ gfx::Transform transform_e_to_e, transform_e_to_c1, transform_c1_to_a, |
+ transform_c1_to_b, transform_e_to_c2, transform_c2_to_g, |
+ transform_c2_to_h; |
+ transform_e_to_c1.Translate(-200, -100); |
+ transform_c1_to_b.Translate(0, -100); |
+ transform_e_to_c2.Translate(-200, -700); |
+ transform_c2_to_h.Translate(0, -100); |
+ DisplayHitTestDataList display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 6}, // e |
+ {c1_id, c1_bounds_in_e, transform_e_to_c1, 0 /* HIT_TEST_IGNORE */, |
+ 2}, // c1 |
+ {a_id, a_bounds_in_c1, transform_c1_to_a, 1 /* HIT_TEST_MINE */, 0}, // a |
+ {b_id, b_bounds_in_c1, transform_c1_to_b, 1 /* HIT_TEST_MINE */, 0}, // b |
+ {c2_id, c2_bounds_in_e, transform_e_to_c2, 0 /* HIT_TEST_IGNORE */, |
+ 2}, // c2 |
+ {g_id, g_bounds_in_c2, transform_c2_to_g, 1 /* HIT_TEST_MINE */, 0}, // g |
+ {h_id, h_bounds_in_c2, transform_c2_to_h, 1 /* HIT_TEST_MINE */, 0} // h |
+ }; |
+ hit_test_query_.set_display_hit_test_data_list(display_hit_test_data_list); |
+ |
+ // All points are in e's coordinate system when we reach this case. |
+ gfx::Point point1(1, 1); |
+ gfx::Point point2(202, 102); |
+ gfx::Point point3(403, 103); |
+ gfx::Point point4(202, 202); |
+ gfx::Point point5(250, 750); |
+ gfx::Point point6(450, 750); |
+ gfx::Point point7(350, 1100); |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id, target1.id); |
+ EXPECT_EQ(point1, target1.location_in_target); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(a_id, target2.id); |
+ EXPECT_EQ(gfx::Point(2, 2), target2.location_in_target); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(e_id, target3.id); |
+ EXPECT_EQ(point3, target3.location_in_target); |
+ EXPECT_TRUE(target3.flags); |
+ |
+ Target target4 = hit_test_query_.FindTargetForLocation(point4); |
+ EXPECT_EQ(b_id, target4.id); |
+ EXPECT_EQ(gfx::Point(2, 2), target4.location_in_target); |
+ EXPECT_TRUE(target4.flags); |
+ |
+ Target target5 = hit_test_query_.FindTargetForLocation(point5); |
+ EXPECT_EQ(g_id, target5.id); |
+ EXPECT_EQ(gfx::Point(50, 50), target5.location_in_target); |
+ EXPECT_TRUE(target5.flags); |
+ |
+ Target target6 = hit_test_query_.FindTargetForLocation(point6); |
+ EXPECT_EQ(e_id, target6.id); |
+ EXPECT_EQ(point6, target6.location_in_target); |
+ EXPECT_TRUE(target6.flags); |
+ |
+ Target target7 = hit_test_query_.FindTargetForLocation(point7); |
+ EXPECT_EQ(h_id, target7.id); |
+ EXPECT_EQ(gfx::Point(150, 300), target7.location_in_target); |
+ EXPECT_TRUE(target7.flags); |
+} |
+ |
+// Children that are multiple layers deep. |
+// |
+// +e--------------------+ |
+// | +c2--------| Point maps to |
+// | +c1------|----+ | ----- ------- |
+// |1| +a-----|---+| | 1 e |
+// | | |+b----|--+|| | 2 g |
+// | | ||+g--+| ||| | 3 b |
+// | | ||| 2 || 3||| 4 | 4 c2 |
+// | | ||+---+| ||| | |
+// | | |+-----|--+|| | |
+// | | +------| --+| | |
+// | +--------|----+ | |
+// +---------------------+ |
+// |
+TEST_F(HitTestQueryTest, MultipleLayerChild) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ cc::FrameSinkId c1_id = cc::FrameSinkId(2, 2); |
+ cc::FrameSinkId a_id = cc::FrameSinkId(3, 3); |
+ cc::FrameSinkId b_id = cc::FrameSinkId(4, 4); |
+ cc::FrameSinkId g_id = cc::FrameSinkId(5, 5); |
+ cc::FrameSinkId c2_id = cc::FrameSinkId(6, 6); |
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 1000, 1000); |
+ gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
+ gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 700, 700); |
+ gfx::Rect b_bounds_in_a = gfx::Rect(0, 0, 600, 600); |
+ gfx::Rect g_bounds_in_b = gfx::Rect(0, 0, 200, 200); |
+ gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
+ gfx::Transform transform_e_to_e, transform_e_to_c1, transform_c1_to_a, |
+ transform_a_to_b, transform_b_to_g, transform_e_to_c2; |
+ transform_e_to_c1.Translate(-100, -100); |
+ transform_a_to_b.Translate(-50, -30); |
+ transform_b_to_g.Translate(-150, -200); |
+ transform_e_to_c2.Translate(-400, -50); |
+ DisplayHitTestDataList display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 5}, // e |
+ {c1_id, c1_bounds_in_e, transform_e_to_c1, 0 /* HIT_TEST_IGNORE */, |
+ 3}, // c1 |
+ {a_id, a_bounds_in_c1, transform_c1_to_a, 1 /* HIT_TEST_MINE */, 2}, // a |
+ {b_id, b_bounds_in_a, transform_a_to_b, 1 /* HIT_TEST_MINE */, 1}, // b |
+ {g_id, g_bounds_in_b, transform_b_to_g, 1 /* HIT_TEST_MINE */, 0}, // g |
+ {c2_id, c2_bounds_in_e, transform_e_to_c2, 1 /* HIT_TEST_MINE */, |
+ 0} // c2 |
+ }; |
+ hit_test_query_.set_display_hit_test_data_list(display_hit_test_data_list); |
+ |
+ // All points are in e's coordinate system when we reach this case. |
+ gfx::Point point1(1, 1); |
+ gfx::Point point2(300, 350); |
+ gfx::Point point3(550, 350); |
+ gfx::Point point4(900, 350); |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id, target1.id); |
+ EXPECT_EQ(point1, target1.location_in_target); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(g_id, target2.id); |
+ EXPECT_EQ(gfx::Point(0, 20), target2.location_in_target); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(b_id, target3.id); |
+ EXPECT_EQ(gfx::Point(400, 220), target3.location_in_target); |
+ EXPECT_TRUE(target3.flags); |
+ |
+ Target target4 = hit_test_query_.FindTargetForLocation(point4); |
+ EXPECT_EQ(c2_id, target4.id); |
+ EXPECT_EQ(gfx::Point(500, 300), target4.location_in_target); |
+ EXPECT_TRUE(target4.flags); |
+} |
+ |
+// Multiple layers deep of transparent children. |
+// |
+// +e--------------------+ |
+// | +c2--------| Point maps to |
+// | +c1------|----+ | ----- ------- |
+// |1| +a-----|---+| | 1 e |
+// | | |+b----|--+|| | 2 e |
+// | | ||+g--+| ||| | 3 c2 |
+// | | ||| 2 || 3||| 4 | 4 c2 |
+// | | ||+---+| ||| | |
+// | | |+-----|--+|| | |
+// | | +------| --+| | |
+// | +--------|----+ | |
+// +---------------------+ |
+// |
+TEST_F(HitTestQueryTest, MultipleLayerTransparentChild) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ cc::FrameSinkId c1_id = cc::FrameSinkId(2, 2); |
+ cc::FrameSinkId a_id = cc::FrameSinkId(3, 3); |
+ cc::FrameSinkId b_id = cc::FrameSinkId(4, 4); |
+ cc::FrameSinkId g_id = cc::FrameSinkId(5, 5); |
+ cc::FrameSinkId c2_id = cc::FrameSinkId(6, 6); |
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 1000, 1000); |
+ gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
+ gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 700, 700); |
+ gfx::Rect b_bounds_in_a = gfx::Rect(0, 0, 600, 600); |
+ gfx::Rect g_bounds_in_b = gfx::Rect(0, 0, 200, 200); |
+ gfx::Rect c2_bounds_in_e = gfx::Rect(0, 0, 800, 800); |
+ gfx::Transform transform_e_to_e, transform_e_to_c1, transform_c1_to_a, |
+ transform_a_to_b, transform_b_to_g, transform_e_to_c2; |
+ transform_e_to_c1.Translate(-100, -100); |
+ transform_a_to_b.Translate(-50, -30); |
+ transform_b_to_g.Translate(-150, -200); |
+ transform_e_to_c2.Translate(-400, -50); |
+ DisplayHitTestDataList display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 5}, // e |
+ {c1_id, c1_bounds_in_e, transform_e_to_c1, 0 /* HIT_TEST_IGNORE */, |
+ 3}, // c1 |
+ {a_id, a_bounds_in_c1, transform_c1_to_a, 0 /* HIT_TEST_IGNORE */, |
+ 2}, // a |
+ {b_id, b_bounds_in_a, transform_a_to_b, 0 /* HIT_TEST_IGNORE */, 1}, // b |
+ {g_id, g_bounds_in_b, transform_b_to_g, 0 /* HIT_TEST_IGNORE */, 0}, // g |
+ {c2_id, c2_bounds_in_e, transform_e_to_c2, 1 /* HIT_TEST_MINE */, |
+ 0} // c2 |
+ }; |
+ hit_test_query_.set_display_hit_test_data_list(display_hit_test_data_list); |
+ |
+ // All points are in e's coordinate system when we reach this case. |
+ gfx::Point point1(1, 1); |
+ gfx::Point point2(300, 350); |
+ gfx::Point point3(450, 350); |
+ gfx::Point point4(900, 350); |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id, target1.id); |
+ EXPECT_EQ(point1, target1.location_in_target); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(e_id, target2.id); |
+ EXPECT_EQ(point2, target2.location_in_target); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(c2_id, target3.id); |
+ EXPECT_EQ(gfx::Point(50, 300), target3.location_in_target); |
+ EXPECT_TRUE(target3.flags); |
+ |
+ Target target4 = hit_test_query_.FindTargetForLocation(point4); |
+ EXPECT_EQ(c2_id, target4.id); |
+ EXPECT_EQ(gfx::Point(500, 300), target4.location_in_target); |
+ EXPECT_TRUE(target4.flags); |
+} |
+ |
+} // namespace test |
+} // namespace hit_test |
+} // namespace viz |