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..192eb347a1a14c0756890b408c3422b768ad98f0 |
--- /dev/null |
+++ b/components/viz/host/hit_test/hit_test_query_unittest.cc |
@@ -0,0 +1,375 @@ |
+// 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. |
rjkroege
2017/06/15 19:58:36
this is coming very well.
riajiang
2017/06/16 02:56:54
:)
|
+// |
+// +e---------+ |
+// | | |
+// | | |
+// | | |
+// +----------+ |
+// |
+TEST_F(HitTestQueryTest, OneSurface) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ std::vector<DisplayHitTestData> display_hit_test_data_list = { |
+ {e_id, gfx::Rect(0, 0, 600, 600), gfx::Transform(), 1 /* HIT_TEST_MINE */, |
rjkroege
2017/06/15 19:58:36
I would find it easier to read if you made this on
riajiang
2017/06/16 02:56:55
Done.
|
+ 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. |
rjkroege
2017/06/15 19:58:36
is 0,0 in the region?
riajiang
2017/06/16 02:56:55
Ha I thought it's like 600,600 but it is in the re
|
+ gfx::Point point1(1, 1); |
+ gfx::Point point2(600, 600); |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id.ToString(), target1.id.ToString()); |
+ EXPECT_EQ(point1.ToString(), target1.location_in_target.ToString()); |
rjkroege
2017/06/15 19:58:36
Doesn't Point's == operator mean that you don't ne
riajiang
2017/06/16 02:56:55
Yes! And it's not needed for FrameSinkId as well s
|
+ 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().ToString(), target2.id.ToString()); |
+ EXPECT_EQ(gfx::Point().ToString(), target2.location_in_target.ToString()); |
+ EXPECT_FALSE(target2.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); |
+ std::vector<DisplayHitTestData> 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.ToString(), target1.id.ToString()); |
+ EXPECT_EQ(point1.ToString(), target1.location_in_target.ToString()); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(c1_id.ToString(), target2.id.ToString()); |
+ EXPECT_EQ(gfx::Point(50, 50).ToString(), |
+ target2.location_in_target.ToString()); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(c2_id.ToString(), target3.id.ToString()); |
+ EXPECT_EQ(gfx::Point(100, 100).ToString(), |
+ target3.location_in_target.ToString()); |
+ EXPECT_TRUE(target3.flags); |
+ |
+ Target target4 = hit_test_query_.FindTargetForLocation(point4); |
+ EXPECT_EQ(cc::FrameSinkId().ToString(), target4.id.ToString()); |
+ EXPECT_EQ(gfx::Point().ToString(), target4.location_in_target.ToString()); |
+ 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); |
+ |
+ std::vector<DisplayHitTestData> 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.ToString(), target1.id.ToString()); |
+ EXPECT_EQ(point1.ToString(), target1.location_in_target.ToString()); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(c_id.ToString(), target2.id.ToString()); |
+ EXPECT_EQ(gfx::Point(185, 194).ToString(), |
+ target2.location_in_target.ToString()); |
+ EXPECT_TRUE(target2.flags); |
+} |
+ |
+// Children that are multiple layers deep. |
+// |
+// +e--------------------+ Point maps to |
+// | +c1---------+ +c2---| ----- ------- |
+// |1| +a-------+| | | 1 e |
+// | | |+b-----+|| | | 2 g |
+// | | ||+g--+ ||| | | 3 c2 |
+// | | ||| 2 | ||| | 3 | |
+// | | ||+---+ ||| | | |
+// | | |+------+|| | | |
+// | | +--------+| | | |
+// | +-----------+ | | |
+// +---------------------+ |
+// |
+TEST_F(HitTestQueryTest, MultipleLayerChild) { |
+ cc::FrameSinkId e_id = cc::FrameSinkId(1, 1); |
+ cc::FrameSinkId a_id = cc::FrameSinkId(2, 2); |
+ cc::FrameSinkId b_id = cc::FrameSinkId(3, 3); |
+ cc::FrameSinkId g_id = cc::FrameSinkId(4, 4); |
+ cc::FrameSinkId c2_id = cc::FrameSinkId(5, 5); |
+ gfx::Rect e_bounds_in_e = gfx::Rect(0, 0, 1000, 1000); |
+ gfx::Rect c1_bounds_in_e = gfx::Rect(0, 0, 600, 600); |
+ gfx::Rect a_bounds_in_c1 = gfx::Rect(0, 0, 500, 500); |
+ gfx::Rect b_bounds_in_c1 = gfx::Rect(0, 0, 400, 400); |
+ gfx::Rect g_bounds_in_c1 = 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_c1_to_b, transform_c1_to_g, transform_e_to_c2; |
+ transform_e_to_c1.Translate(-100, -100); |
rjkroege
2017/06/15 19:58:36
we need unit tests that handle 3space transformati
|
+ transform_c1_to_b.Translate(-50, -30); |
+ transform_c1_to_g.Translate(-150, -200); |
+ transform_e_to_c2.Translate(-800, -100); |
+ std::vector<DisplayHitTestData> display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 5}, // e |
+ {e_id, c1_bounds_in_e, transform_e_to_c1, 0 /* HIT_TEST_BOUND */, |
+ 3}, // c1 |
+ {a_id, a_bounds_in_c1, transform_c1_to_a, 1 /* HIT_TEST_MINE */, 2}, // a |
+ {b_id, b_bounds_in_c1, transform_c1_to_b, 1 /* HIT_TEST_MINE */, 1}, // b |
+ {g_id, g_bounds_in_c1, transform_c1_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(900, 350); |
+ |
+ Target target1 = hit_test_query_.FindTargetForLocation(point1); |
+ EXPECT_EQ(e_id.ToString(), target1.id.ToString()); |
+ EXPECT_EQ(point1.ToString(), target1.location_in_target.ToString()); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(g_id.ToString(), target2.id.ToString()); |
+ EXPECT_EQ(gfx::Point(0, 20).ToString(), |
+ target2.location_in_target.ToString()); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(c2_id.ToString(), target3.id.ToString()); |
+ EXPECT_EQ(gfx::Point(100, 250).ToString(), |
+ target3.location_in_target.ToString()); |
+ EXPECT_TRUE(target3.flags); |
+} |
+ |
+// One embedder with a clipped child with a tab and transparent background. |
+// |
+// +e-------------+ |
+// | +c---------| Point maps to |
rjkroege
2017/06/15 19:58:36
so... say we have a a d region inside area "3". b
riajiang
2017/06/16 02:56:55
If it's back-to-front (what I'm assuming for now),
|
+// | 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 a_id = cc::FrameSinkId(2, 2); |
+ cc::FrameSinkId b_id = cc::FrameSinkId(3, 3); |
+ 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); |
+ std::vector<DisplayHitTestData> display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 3}, // e |
+ {e_id, c_bounds_in_e, transform_e_to_c, 0 /* HIT_TEST_BOUND */, 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.ToString(), target1.id.ToString()); |
+ EXPECT_EQ(point1.ToString(), target1.location_in_target.ToString()); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(a_id.ToString(), target2.id.ToString()); |
+ EXPECT_EQ(gfx::Point(2, 2).ToString(), target2.location_in_target.ToString()); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(e_id.ToString(), target3.id.ToString()); |
+ EXPECT_EQ(point3.ToString(), target3.location_in_target.ToString()); |
+ EXPECT_TRUE(target3.flags); |
+ |
+ Target target4 = hit_test_query_.FindTargetForLocation(point4); |
+ EXPECT_EQ(b_id.ToString(), target4.id.ToString()); |
+ EXPECT_EQ(gfx::Point(2, 2).ToString(), target4.location_in_target.ToString()); |
+ 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 a_id = cc::FrameSinkId(2, 2); |
+ cc::FrameSinkId b_id = cc::FrameSinkId(3, 3); |
+ cc::FrameSinkId g_id = cc::FrameSinkId(4, 4); |
+ cc::FrameSinkId h_id = cc::FrameSinkId(5, 5); |
+ 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); |
+ std::vector<DisplayHitTestData> display_hit_test_data_list = { |
+ {e_id, e_bounds_in_e, transform_e_to_e, 1 /* HIT_TEST_MINE */, 6}, // e |
+ {e_id, c1_bounds_in_e, transform_e_to_c1, 0 /* HIT_TEST_BOUND */, |
+ 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 |
+ {e_id, c2_bounds_in_e, transform_e_to_c2, 0 /* HIT_TEST_BOUND */, |
+ 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.ToString(), target1.id.ToString()); |
+ EXPECT_EQ(point1.ToString(), target1.location_in_target.ToString()); |
+ EXPECT_TRUE(target1.flags); |
+ |
+ Target target2 = hit_test_query_.FindTargetForLocation(point2); |
+ EXPECT_EQ(a_id.ToString(), target2.id.ToString()); |
+ EXPECT_EQ(gfx::Point(2, 2).ToString(), target2.location_in_target.ToString()); |
+ EXPECT_TRUE(target2.flags); |
+ |
+ Target target3 = hit_test_query_.FindTargetForLocation(point3); |
+ EXPECT_EQ(e_id.ToString(), target3.id.ToString()); |
+ EXPECT_EQ(point3.ToString(), target3.location_in_target.ToString()); |
+ EXPECT_TRUE(target3.flags); |
+ |
+ Target target4 = hit_test_query_.FindTargetForLocation(point4); |
+ EXPECT_EQ(b_id.ToString(), target4.id.ToString()); |
+ EXPECT_EQ(gfx::Point(2, 2).ToString(), target4.location_in_target.ToString()); |
+ EXPECT_TRUE(target4.flags); |
+ |
+ Target target5 = hit_test_query_.FindTargetForLocation(point5); |
+ EXPECT_EQ(g_id.ToString(), target5.id.ToString()); |
+ EXPECT_EQ(gfx::Point(50, 50).ToString(), |
+ target5.location_in_target.ToString()); |
+ EXPECT_TRUE(target5.flags); |
+ |
+ Target target6 = hit_test_query_.FindTargetForLocation(point6); |
+ EXPECT_EQ(e_id.ToString(), target6.id.ToString()); |
+ EXPECT_EQ(point6.ToString(), target6.location_in_target.ToString()); |
+ EXPECT_TRUE(target6.flags); |
+ |
+ Target target7 = hit_test_query_.FindTargetForLocation(point7); |
+ EXPECT_EQ(h_id.ToString(), target7.id.ToString()); |
+ EXPECT_EQ(gfx::Point(150, 300).ToString(), |
+ target7.location_in_target.ToString()); |
+ EXPECT_TRUE(target7.flags); |
+} |
+ |
+} // namespace test |
+} // namespace hit_test |
+} // namespace viz |