Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: cc/trees/layer_tree_host_common_unittest.cc

Issue 266913021: Hit test on the layer tree rather than the RSLL (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Minor cleanups. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/trees/layer_tree_host_common.h" 5 #include "cc/trees/layer_tree_host_common.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "cc/animation/layer_animation_controller.h" 9 #include "cc/animation/layer_animation_controller.h"
10 #include "cc/animation/transform_operations.h" 10 #include "cc/animation/transform_operations.h"
11 #include "cc/base/math_util.h" 11 #include "cc/base/math_util.h"
12 #include "cc/layers/content_layer.h" 12 #include "cc/layers/content_layer.h"
13 #include "cc/layers/content_layer_client.h" 13 #include "cc/layers/content_layer_client.h"
14 #include "cc/layers/heads_up_display_layer_impl.h"
15 #include "cc/layers/layer.h" 14 #include "cc/layers/layer.h"
16 #include "cc/layers/layer_client.h" 15 #include "cc/layers/layer_client.h"
17 #include "cc/layers/layer_impl.h" 16 #include "cc/layers/layer_impl.h"
18 #include "cc/layers/layer_iterator.h" 17 #include "cc/layers/layer_iterator.h"
19 #include "cc/layers/render_surface.h" 18 #include "cc/layers/render_surface.h"
20 #include "cc/layers/render_surface_impl.h" 19 #include "cc/layers/render_surface_impl.h"
21 #include "cc/output/copy_output_request.h" 20 #include "cc/output/copy_output_request.h"
22 #include "cc/output/copy_output_result.h" 21 #include "cc/output/copy_output_result.h"
23 #include "cc/test/animation_test_common.h" 22 #include "cc/test/animation_test_common.h"
24 #include "cc/test/fake_impl_proxy.h" 23 #include "cc/test/fake_impl_proxy.h"
25 #include "cc/test/fake_layer_tree_host.h" 24 #include "cc/test/fake_layer_tree_host.h"
26 #include "cc/test/fake_layer_tree_host_impl.h" 25 #include "cc/test/fake_layer_tree_host_impl.h"
27 #include "cc/test/geometry_test_utils.h" 26 #include "cc/test/geometry_test_utils.h"
27 #include "cc/test/layer_tree_host_common_test.h"
28 #include "cc/trees/layer_tree_impl.h" 28 #include "cc/trees/layer_tree_impl.h"
29 #include "cc/trees/proxy.h" 29 #include "cc/trees/proxy.h"
30 #include "cc/trees/single_thread_proxy.h" 30 #include "cc/trees/single_thread_proxy.h"
31 #include "testing/gmock/include/gmock/gmock.h" 31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "ui/gfx/quad_f.h" 33 #include "ui/gfx/quad_f.h"
34 #include "ui/gfx/size_conversions.h"
35 #include "ui/gfx/transform.h" 34 #include "ui/gfx/transform.h"
36 35
37 namespace cc { 36 namespace cc {
38 namespace { 37 namespace {
39 38
40 class LayerTreeHostCommonTestBase {
41 protected:
42 LayerTreeHostCommonTestBase() : render_surface_layer_list_count_(0) {}
43
44 template <typename LayerType>
45 void SetLayerPropertiesForTestingInternal(
46 LayerType* layer,
47 const gfx::Transform& transform,
48 const gfx::PointF& anchor,
49 const gfx::PointF& position,
50 const gfx::Size& bounds,
51 bool flatten_transform,
52 bool is_3d_sorted) {
53 layer->SetTransform(transform);
54 layer->SetAnchorPoint(anchor);
55 layer->SetPosition(position);
56 layer->SetBounds(bounds);
57 layer->SetShouldFlattenTransform(flatten_transform);
58 layer->SetIs3dSorted(is_3d_sorted);
59 }
60
61 void SetLayerPropertiesForTesting(Layer* layer,
62 const gfx::Transform& transform,
63 const gfx::PointF& anchor,
64 const gfx::PointF& position,
65 const gfx::Size& bounds,
66 bool flatten_transform,
67 bool is_3d_sorted) {
68 SetLayerPropertiesForTestingInternal<Layer>(layer,
69 transform,
70 anchor,
71 position,
72 bounds,
73 flatten_transform,
74 is_3d_sorted);
75 }
76
77 void SetLayerPropertiesForTesting(LayerImpl* layer,
78 const gfx::Transform& transform,
79 const gfx::PointF& anchor,
80 const gfx::PointF& position,
81 const gfx::Size& bounds,
82 bool flatten_transform,
83 bool is_3d_sorted) {
84 SetLayerPropertiesForTestingInternal<LayerImpl>(layer,
85 transform,
86 anchor,
87 position,
88 bounds,
89 flatten_transform,
90 is_3d_sorted);
91 layer->SetContentBounds(bounds);
92 }
93
94 void ExecuteCalculateDrawProperties(Layer* root_layer,
95 float device_scale_factor,
96 float page_scale_factor,
97 Layer* page_scale_application_layer,
98 bool can_use_lcd_text) {
99 EXPECT_TRUE(page_scale_application_layer || (page_scale_factor == 1.f));
100 gfx::Transform identity_matrix;
101 gfx::Size device_viewport_size =
102 gfx::Size(root_layer->bounds().width() * device_scale_factor,
103 root_layer->bounds().height() * device_scale_factor);
104
105 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
106
107 // We are probably not testing what is intended if the root_layer bounds are
108 // empty.
109 DCHECK(!root_layer->bounds().IsEmpty());
110 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
111 root_layer, device_viewport_size, render_surface_layer_list_.get());
112 inputs.device_scale_factor = device_scale_factor;
113 inputs.page_scale_factor = page_scale_factor;
114 inputs.page_scale_application_layer = page_scale_application_layer;
115 inputs.can_use_lcd_text = can_use_lcd_text;
116 inputs.can_adjust_raster_scales = true;
117 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
118 }
119
120 void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
121 float device_scale_factor,
122 float page_scale_factor,
123 LayerImpl* page_scale_application_layer,
124 bool can_use_lcd_text) {
125 gfx::Transform identity_matrix;
126 gfx::Size device_viewport_size =
127 gfx::Size(root_layer->bounds().width() * device_scale_factor,
128 root_layer->bounds().height() * device_scale_factor);
129
130 render_surface_layer_list_impl_.reset(new LayerImplList);
131
132 // We are probably not testing what is intended if the root_layer bounds are
133 // empty.
134 DCHECK(!root_layer->bounds().IsEmpty());
135 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
136 root_layer,
137 device_viewport_size,
138 render_surface_layer_list_impl_.get());
139 inputs.device_scale_factor = device_scale_factor;
140 inputs.page_scale_factor = page_scale_factor;
141 inputs.page_scale_application_layer = page_scale_application_layer;
142 inputs.can_use_lcd_text = can_use_lcd_text;
143 inputs.can_adjust_raster_scales = true;
144
145 ++render_surface_layer_list_count_;
146 inputs.current_render_surface_layer_list_id =
147 render_surface_layer_list_count_;
148
149 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
150 }
151
152 template <class LayerType>
153 void ExecuteCalculateDrawProperties(LayerType* root_layer) {
154 LayerType* page_scale_application_layer = NULL;
155 ExecuteCalculateDrawProperties(
156 root_layer, 1.f, 1.f, page_scale_application_layer, false);
157 }
158
159 template <class LayerType>
160 void ExecuteCalculateDrawProperties(LayerType* root_layer,
161 float device_scale_factor) {
162 LayerType* page_scale_application_layer = NULL;
163 ExecuteCalculateDrawProperties(root_layer,
164 device_scale_factor,
165 1.f,
166 page_scale_application_layer,
167 false);
168 }
169
170 template <class LayerType>
171 void ExecuteCalculateDrawProperties(LayerType* root_layer,
172 float device_scale_factor,
173 float page_scale_factor,
174 LayerType* page_scale_application_layer) {
175 ExecuteCalculateDrawProperties(root_layer,
176 device_scale_factor,
177 page_scale_factor,
178 page_scale_application_layer,
179 false);
180 }
181
182 RenderSurfaceLayerList* render_surface_layer_list() const {
183 return render_surface_layer_list_.get();
184 }
185
186 LayerImplList* render_surface_layer_list_impl() const {
187 return render_surface_layer_list_impl_.get();
188 }
189
190 int render_surface_layer_list_count() const {
191 return render_surface_layer_list_count_;
192 }
193
194 private:
195 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
196 scoped_ptr<LayerImplList> render_surface_layer_list_impl_;
197
198 int render_surface_layer_list_count_;
199 };
200
201 class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase,
202 public testing::Test {
203 };
204
205 class LayerWithForcedDrawsContent : public Layer { 39 class LayerWithForcedDrawsContent : public Layer {
206 public: 40 public:
207 LayerWithForcedDrawsContent() : Layer(), last_device_scale_factor_(0.f) {} 41 LayerWithForcedDrawsContent() : Layer(), last_device_scale_factor_(0.f) {}
208 42
209 virtual bool DrawsContent() const OVERRIDE; 43 virtual bool DrawsContent() const OVERRIDE;
210 virtual void CalculateContentsScale(float ideal_contents_scale, 44 virtual void CalculateContentsScale(float ideal_contents_scale,
211 float device_scale_factor, 45 float device_scale_factor,
212 float page_scale_factor, 46 float page_scale_factor,
213 float maximum_animation_contents_scale, 47 float maximum_animation_contents_scale,
214 bool animating_transform_to_screen, 48 bool animating_transform_to_screen,
(...skipping 3939 matching lines...) Expand 10 before | Expand all | Expand 10 after
4154 2u, 3988 2u,
4155 render_surface_layer_list.at(1)->render_surface()->layer_list().size()); 3989 render_surface_layer_list.at(1)->render_surface()->layer_list().size());
4156 EXPECT_EQ(front_facing_surface->id(), 3990 EXPECT_EQ(front_facing_surface->id(),
4157 render_surface_layer_list.at(1) 3991 render_surface_layer_list.at(1)
4158 ->render_surface()->layer_list().at(0)->id()); 3992 ->render_surface()->layer_list().at(0)->id());
4159 EXPECT_EQ(child1->id(), 3993 EXPECT_EQ(child1->id(),
4160 render_surface_layer_list.at(1) 3994 render_surface_layer_list.at(1)
4161 ->render_surface()->layer_list().at(1)->id()); 3995 ->render_surface()->layer_list().at(1)->id());
4162 } 3996 }
4163 3997
4164
4165 TEST_F(LayerTreeHostCommonTest, HitTestingForEmptyLayerList) {
4166 // Hit testing on an empty render_surface_layer_list should return a null
4167 // pointer.
4168 LayerImplList render_surface_layer_list;
4169
4170 gfx::Point test_point(0, 0);
4171 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4172 test_point, render_surface_layer_list);
4173 EXPECT_FALSE(result_layer);
4174
4175 test_point = gfx::Point(10, 20);
4176 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4177 test_point, render_surface_layer_list);
4178 EXPECT_FALSE(result_layer);
4179 }
4180
4181 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleLayer) {
4182 FakeImplProxy proxy;
4183 TestSharedBitmapManager shared_bitmap_manager;
4184 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4185 scoped_ptr<LayerImpl> root =
4186 LayerImpl::Create(host_impl.active_tree(), 12345);
4187
4188 gfx::Transform identity_matrix;
4189 gfx::PointF anchor;
4190 gfx::PointF position;
4191 gfx::Size bounds(100, 100);
4192 SetLayerPropertiesForTesting(root.get(),
4193 identity_matrix,
4194 anchor,
4195 position,
4196 bounds,
4197 true,
4198 false);
4199 root->SetDrawsContent(true);
4200
4201 LayerImplList render_surface_layer_list;
4202 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4203 root.get(), root->bounds(), &render_surface_layer_list);
4204 inputs.can_adjust_raster_scales = true;
4205 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4206
4207 // Sanity check the scenario we just created.
4208 ASSERT_EQ(1u, render_surface_layer_list.size());
4209 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4210
4211 // Hit testing for a point outside the layer should return a null pointer.
4212 gfx::Point test_point(101, 101);
4213 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4214 test_point, render_surface_layer_list);
4215 EXPECT_FALSE(result_layer);
4216
4217 test_point = gfx::Point(-1, -1);
4218 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4219 test_point, render_surface_layer_list);
4220 EXPECT_FALSE(result_layer);
4221
4222 // Hit testing for a point inside should return the root layer.
4223 test_point = gfx::Point(1, 1);
4224 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4225 test_point, render_surface_layer_list);
4226 ASSERT_TRUE(result_layer);
4227 EXPECT_EQ(12345, result_layer->id());
4228
4229 test_point = gfx::Point(99, 99);
4230 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4231 test_point, render_surface_layer_list);
4232 ASSERT_TRUE(result_layer);
4233 EXPECT_EQ(12345, result_layer->id());
4234 }
4235
4236 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleLayerAndHud) {
4237 FakeImplProxy proxy;
4238 TestSharedBitmapManager shared_bitmap_manager;
4239 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4240 scoped_ptr<LayerImpl> root =
4241 LayerImpl::Create(host_impl.active_tree(), 12345);
4242 scoped_ptr<HeadsUpDisplayLayerImpl> hud =
4243 HeadsUpDisplayLayerImpl::Create(host_impl.active_tree(), 11111);
4244
4245 gfx::Transform identity_matrix;
4246 gfx::PointF anchor;
4247 gfx::PointF position;
4248 gfx::Size bounds(100, 100);
4249 SetLayerPropertiesForTesting(root.get(),
4250 identity_matrix,
4251 anchor,
4252 position,
4253 bounds,
4254 true,
4255 false);
4256 root->SetDrawsContent(true);
4257
4258 // Create hud and add it as a child of root.
4259 gfx::Size hud_bounds(200, 200);
4260 SetLayerPropertiesForTesting(hud.get(),
4261 identity_matrix,
4262 anchor,
4263 position,
4264 hud_bounds,
4265 true,
4266 false);
4267 hud->SetDrawsContent(true);
4268
4269 host_impl.active_tree()->set_hud_layer(hud.get());
4270 root->AddChild(hud.PassAs<LayerImpl>());
4271
4272 LayerImplList render_surface_layer_list;
4273 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4274 root.get(), hud_bounds, &render_surface_layer_list);
4275 inputs.can_adjust_raster_scales = true;
4276 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4277
4278 // Sanity check the scenario we just created.
4279 ASSERT_EQ(1u, render_surface_layer_list.size());
4280 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
4281
4282 // Hit testing for a point inside HUD, but outside root should return null
4283 gfx::Point test_point(101, 101);
4284 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4285 test_point, render_surface_layer_list);
4286 EXPECT_FALSE(result_layer);
4287
4288 test_point = gfx::Point(-1, -1);
4289 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4290 test_point, render_surface_layer_list);
4291 EXPECT_FALSE(result_layer);
4292
4293 // Hit testing for a point inside should return the root layer, never the HUD
4294 // layer.
4295 test_point = gfx::Point(1, 1);
4296 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4297 test_point, render_surface_layer_list);
4298 ASSERT_TRUE(result_layer);
4299 EXPECT_EQ(12345, result_layer->id());
4300
4301 test_point = gfx::Point(99, 99);
4302 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4303 test_point, render_surface_layer_list);
4304 ASSERT_TRUE(result_layer);
4305 EXPECT_EQ(12345, result_layer->id());
4306 }
4307
4308 TEST_F(LayerTreeHostCommonTest, HitTestingForUninvertibleTransform) {
4309 FakeImplProxy proxy;
4310 TestSharedBitmapManager shared_bitmap_manager;
4311 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4312 scoped_ptr<LayerImpl> root =
4313 LayerImpl::Create(host_impl.active_tree(), 12345);
4314
4315 gfx::Transform uninvertible_transform;
4316 uninvertible_transform.matrix().set(0, 0, 0.0);
4317 uninvertible_transform.matrix().set(1, 1, 0.0);
4318 uninvertible_transform.matrix().set(2, 2, 0.0);
4319 uninvertible_transform.matrix().set(3, 3, 0.0);
4320 ASSERT_FALSE(uninvertible_transform.IsInvertible());
4321
4322 gfx::Transform identity_matrix;
4323 gfx::PointF anchor;
4324 gfx::PointF position;
4325 gfx::Size bounds(100, 100);
4326 SetLayerPropertiesForTesting(root.get(),
4327 uninvertible_transform,
4328 anchor,
4329 position,
4330 bounds,
4331 true,
4332 false);
4333 root->SetDrawsContent(true);
4334
4335 LayerImplList render_surface_layer_list;
4336 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4337 root.get(), root->bounds(), &render_surface_layer_list);
4338 inputs.can_adjust_raster_scales = true;
4339 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4340
4341 // Sanity check the scenario we just created.
4342 ASSERT_EQ(1u, render_surface_layer_list.size());
4343 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4344 ASSERT_FALSE(root->screen_space_transform().IsInvertible());
4345
4346 // Hit testing any point should not hit the layer. If the invertible matrix is
4347 // accidentally ignored and treated like an identity, then the hit testing
4348 // will incorrectly hit the layer when it shouldn't.
4349 gfx::Point test_point(1, 1);
4350 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4351 test_point, render_surface_layer_list);
4352 EXPECT_FALSE(result_layer);
4353
4354 test_point = gfx::Point(10, 10);
4355 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4356 test_point, render_surface_layer_list);
4357 EXPECT_FALSE(result_layer);
4358
4359 test_point = gfx::Point(10, 30);
4360 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4361 test_point, render_surface_layer_list);
4362 EXPECT_FALSE(result_layer);
4363
4364 test_point = gfx::Point(50, 50);
4365 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4366 test_point, render_surface_layer_list);
4367 EXPECT_FALSE(result_layer);
4368
4369 test_point = gfx::Point(67, 48);
4370 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4371 test_point, render_surface_layer_list);
4372 EXPECT_FALSE(result_layer);
4373
4374 test_point = gfx::Point(99, 99);
4375 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4376 test_point, render_surface_layer_list);
4377 EXPECT_FALSE(result_layer);
4378
4379 test_point = gfx::Point(-1, -1);
4380 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4381 test_point, render_surface_layer_list);
4382 EXPECT_FALSE(result_layer);
4383 }
4384
4385 TEST_F(LayerTreeHostCommonTest, HitTestingForSinglePositionedLayer) {
4386 FakeImplProxy proxy;
4387 TestSharedBitmapManager shared_bitmap_manager;
4388 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4389 scoped_ptr<LayerImpl> root =
4390 LayerImpl::Create(host_impl.active_tree(), 12345);
4391
4392 gfx::Transform identity_matrix;
4393 gfx::PointF anchor;
4394 // this layer is positioned, and hit testing should correctly know where the
4395 // layer is located.
4396 gfx::PointF position(50.f, 50.f);
4397 gfx::Size bounds(100, 100);
4398 SetLayerPropertiesForTesting(root.get(),
4399 identity_matrix,
4400 anchor,
4401 position,
4402 bounds,
4403 true,
4404 false);
4405 root->SetDrawsContent(true);
4406
4407 LayerImplList render_surface_layer_list;
4408 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4409 root.get(), root->bounds(), &render_surface_layer_list);
4410 inputs.can_adjust_raster_scales = true;
4411 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4412
4413 // Sanity check the scenario we just created.
4414 ASSERT_EQ(1u, render_surface_layer_list.size());
4415 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4416
4417 // Hit testing for a point outside the layer should return a null pointer.
4418 gfx::Point test_point(49, 49);
4419 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4420 test_point, render_surface_layer_list);
4421 EXPECT_FALSE(result_layer);
4422
4423 // Even though the layer exists at (101, 101), it should not be visible there
4424 // since the root render surface would clamp it.
4425 test_point = gfx::Point(101, 101);
4426 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4427 test_point, render_surface_layer_list);
4428 EXPECT_FALSE(result_layer);
4429
4430 // Hit testing for a point inside should return the root layer.
4431 test_point = gfx::Point(51, 51);
4432 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4433 test_point, render_surface_layer_list);
4434 ASSERT_TRUE(result_layer);
4435 EXPECT_EQ(12345, result_layer->id());
4436
4437 test_point = gfx::Point(99, 99);
4438 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4439 test_point, render_surface_layer_list);
4440 ASSERT_TRUE(result_layer);
4441 EXPECT_EQ(12345, result_layer->id());
4442 }
4443
4444 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleRotatedLayer) {
4445 FakeImplProxy proxy;
4446 TestSharedBitmapManager shared_bitmap_manager;
4447 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4448 scoped_ptr<LayerImpl> root =
4449 LayerImpl::Create(host_impl.active_tree(), 12345);
4450
4451 gfx::Transform identity_matrix;
4452 gfx::Transform rotation45_degrees_about_center;
4453 rotation45_degrees_about_center.Translate(50.0, 50.0);
4454 rotation45_degrees_about_center.RotateAboutZAxis(45.0);
4455 rotation45_degrees_about_center.Translate(-50.0, -50.0);
4456 gfx::PointF anchor;
4457 gfx::PointF position;
4458 gfx::Size bounds(100, 100);
4459 SetLayerPropertiesForTesting(root.get(),
4460 rotation45_degrees_about_center,
4461 anchor,
4462 position,
4463 bounds,
4464 true,
4465 false);
4466 root->SetDrawsContent(true);
4467
4468 LayerImplList render_surface_layer_list;
4469 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4470 root.get(), root->bounds(), &render_surface_layer_list);
4471 inputs.can_adjust_raster_scales = true;
4472 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4473
4474 // Sanity check the scenario we just created.
4475 ASSERT_EQ(1u, render_surface_layer_list.size());
4476 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4477
4478 // Hit testing for points outside the layer.
4479 // These corners would have been inside the un-transformed layer, but they
4480 // should not hit the correctly transformed layer.
4481 gfx::Point test_point(99, 99);
4482 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4483 test_point, render_surface_layer_list);
4484 EXPECT_FALSE(result_layer);
4485
4486 test_point = gfx::Point(1, 1);
4487 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4488 test_point, render_surface_layer_list);
4489 EXPECT_FALSE(result_layer);
4490
4491 // Hit testing for a point inside should return the root layer.
4492 test_point = gfx::Point(1, 50);
4493 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4494 test_point, render_surface_layer_list);
4495 ASSERT_TRUE(result_layer);
4496 EXPECT_EQ(12345, result_layer->id());
4497
4498 // Hit testing the corners that would overlap the unclipped layer, but are
4499 // outside the clipped region.
4500 test_point = gfx::Point(50, -1);
4501 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4502 test_point, render_surface_layer_list);
4503 ASSERT_FALSE(result_layer);
4504
4505 test_point = gfx::Point(-1, 50);
4506 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4507 test_point, render_surface_layer_list);
4508 ASSERT_FALSE(result_layer);
4509 }
4510
4511 TEST_F(LayerTreeHostCommonTest, HitTestingForSinglePerspectiveLayer) {
4512 FakeImplProxy proxy;
4513 TestSharedBitmapManager shared_bitmap_manager;
4514 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4515 scoped_ptr<LayerImpl> root =
4516 LayerImpl::Create(host_impl.active_tree(), 12345);
4517
4518 gfx::Transform identity_matrix;
4519
4520 // perspective_projection_about_center * translation_by_z is designed so that
4521 // the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50).
4522 gfx::Transform perspective_projection_about_center;
4523 perspective_projection_about_center.Translate(50.0, 50.0);
4524 perspective_projection_about_center.ApplyPerspectiveDepth(1.0);
4525 perspective_projection_about_center.Translate(-50.0, -50.0);
4526 gfx::Transform translation_by_z;
4527 translation_by_z.Translate3d(0.0, 0.0, -1.0);
4528
4529 gfx::PointF anchor;
4530 gfx::PointF position;
4531 gfx::Size bounds(100, 100);
4532 SetLayerPropertiesForTesting(
4533 root.get(),
4534 perspective_projection_about_center * translation_by_z,
4535 anchor,
4536 position,
4537 bounds,
4538 true,
4539 false);
4540 root->SetDrawsContent(true);
4541
4542 LayerImplList render_surface_layer_list;
4543 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4544 root.get(), root->bounds(), &render_surface_layer_list);
4545 inputs.can_adjust_raster_scales = true;
4546 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4547
4548 // Sanity check the scenario we just created.
4549 ASSERT_EQ(1u, render_surface_layer_list.size());
4550 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4551
4552 // Hit testing for points outside the layer.
4553 // These corners would have been inside the un-transformed layer, but they
4554 // should not hit the correctly transformed layer.
4555 gfx::Point test_point(24, 24);
4556 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4557 test_point, render_surface_layer_list);
4558 EXPECT_FALSE(result_layer);
4559
4560 test_point = gfx::Point(76, 76);
4561 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4562 test_point, render_surface_layer_list);
4563 EXPECT_FALSE(result_layer);
4564
4565 // Hit testing for a point inside should return the root layer.
4566 test_point = gfx::Point(26, 26);
4567 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4568 test_point, render_surface_layer_list);
4569 ASSERT_TRUE(result_layer);
4570 EXPECT_EQ(12345, result_layer->id());
4571
4572 test_point = gfx::Point(74, 74);
4573 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4574 test_point, render_surface_layer_list);
4575 ASSERT_TRUE(result_layer);
4576 EXPECT_EQ(12345, result_layer->id());
4577 }
4578
4579 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleLayerWithScaledContents) {
4580 // A layer's visible content rect is actually in the layer's content space.
4581 // The screen space transform converts from the layer's origin space to screen
4582 // space. This test makes sure that hit testing works correctly accounts for
4583 // the contents scale. A contents scale that is not 1 effectively forces a
4584 // non-identity transform between layer's content space and layer's origin
4585 // space. The hit testing code must take this into account.
4586 //
4587 // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
4588 // contents scale is ignored, then hit testing will mis-interpret the visible
4589 // content rect as being larger than the actual bounds of the layer.
4590 //
4591 FakeImplProxy proxy;
4592 TestSharedBitmapManager shared_bitmap_manager;
4593 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4594 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
4595
4596 gfx::Transform identity_matrix;
4597 gfx::PointF anchor;
4598
4599 SetLayerPropertiesForTesting(root.get(),
4600 identity_matrix,
4601 anchor,
4602 gfx::PointF(),
4603 gfx::Size(100, 100),
4604 true,
4605 false);
4606 {
4607 gfx::PointF position(25.f, 25.f);
4608 gfx::Size bounds(50, 50);
4609 scoped_ptr<LayerImpl> test_layer =
4610 LayerImpl::Create(host_impl.active_tree(), 12345);
4611 SetLayerPropertiesForTesting(test_layer.get(),
4612 identity_matrix,
4613 anchor,
4614 position,
4615 bounds,
4616 true,
4617 false);
4618
4619 // override content bounds and contents scale
4620 test_layer->SetContentBounds(gfx::Size(100, 100));
4621 test_layer->SetContentsScale(2, 2);
4622
4623 test_layer->SetDrawsContent(true);
4624 root->AddChild(test_layer.Pass());
4625 }
4626
4627 LayerImplList render_surface_layer_list;
4628 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4629 root.get(), root->bounds(), &render_surface_layer_list);
4630 inputs.can_adjust_raster_scales = true;
4631 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4632
4633 // Sanity check the scenario we just created.
4634 // The visible content rect for test_layer is actually 100x100, even though
4635 // its layout size is 50x50, positioned at 25x25.
4636 LayerImpl* test_layer = root->children()[0];
4637 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4638 test_layer->visible_content_rect());
4639 ASSERT_EQ(1u, render_surface_layer_list.size());
4640 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4641
4642 // Hit testing for a point outside the layer should return a null pointer (the
4643 // root layer does not draw content, so it will not be hit tested either).
4644 gfx::Point test_point(101, 101);
4645 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4646 test_point, render_surface_layer_list);
4647 EXPECT_FALSE(result_layer);
4648
4649 test_point = gfx::Point(24, 24);
4650 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4651 test_point, render_surface_layer_list);
4652 EXPECT_FALSE(result_layer);
4653
4654 test_point = gfx::Point(76, 76);
4655 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4656 test_point, render_surface_layer_list);
4657 EXPECT_FALSE(result_layer);
4658
4659 // Hit testing for a point inside should return the test layer.
4660 test_point = gfx::Point(26, 26);
4661 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4662 test_point, render_surface_layer_list);
4663 ASSERT_TRUE(result_layer);
4664 EXPECT_EQ(12345, result_layer->id());
4665
4666 test_point = gfx::Point(74, 74);
4667 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4668 test_point, render_surface_layer_list);
4669 ASSERT_TRUE(result_layer);
4670 EXPECT_EQ(12345, result_layer->id());
4671 }
4672
4673 TEST_F(LayerTreeHostCommonTest, HitTestingForSimpleClippedLayer) {
4674 // Test that hit-testing will only work for the visible portion of a layer,
4675 // and not the entire layer bounds. Here we just test the simple axis-aligned
4676 // case.
4677 gfx::Transform identity_matrix;
4678 gfx::PointF anchor;
4679
4680 FakeImplProxy proxy;
4681 TestSharedBitmapManager shared_bitmap_manager;
4682 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4683 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
4684 SetLayerPropertiesForTesting(root.get(),
4685 identity_matrix,
4686 anchor,
4687 gfx::PointF(),
4688 gfx::Size(100, 100),
4689 true,
4690 false);
4691 {
4692 scoped_ptr<LayerImpl> clipping_layer =
4693 LayerImpl::Create(host_impl.active_tree(), 123);
4694 // this layer is positioned, and hit testing should correctly know where the
4695 // layer is located.
4696 gfx::PointF position(25.f, 25.f);
4697 gfx::Size bounds(50, 50);
4698 SetLayerPropertiesForTesting(clipping_layer.get(),
4699 identity_matrix,
4700 anchor,
4701 position,
4702 bounds,
4703 true,
4704 false);
4705 clipping_layer->SetMasksToBounds(true);
4706
4707 scoped_ptr<LayerImpl> child =
4708 LayerImpl::Create(host_impl.active_tree(), 456);
4709 position = gfx::PointF(-50.f, -50.f);
4710 bounds = gfx::Size(300, 300);
4711 SetLayerPropertiesForTesting(child.get(),
4712 identity_matrix,
4713 anchor,
4714 position,
4715 bounds,
4716 true,
4717 false);
4718 child->SetDrawsContent(true);
4719 clipping_layer->AddChild(child.Pass());
4720 root->AddChild(clipping_layer.Pass());
4721 }
4722
4723 LayerImplList render_surface_layer_list;
4724 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4725 root.get(), root->bounds(), &render_surface_layer_list);
4726 inputs.can_adjust_raster_scales = true;
4727 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4728
4729 // Sanity check the scenario we just created.
4730 ASSERT_EQ(1u, render_surface_layer_list.size());
4731 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4732 ASSERT_EQ(456, root->render_surface()->layer_list().at(0)->id());
4733
4734 // Hit testing for a point outside the layer should return a null pointer.
4735 // Despite the child layer being very large, it should be clipped to the root
4736 // layer's bounds.
4737 gfx::Point test_point(24, 24);
4738 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4739 test_point, render_surface_layer_list);
4740 EXPECT_FALSE(result_layer);
4741
4742 // Even though the layer exists at (101, 101), it should not be visible there
4743 // since the clipping_layer would clamp it.
4744 test_point = gfx::Point(76, 76);
4745 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4746 test_point, render_surface_layer_list);
4747 EXPECT_FALSE(result_layer);
4748
4749 // Hit testing for a point inside should return the child layer.
4750 test_point = gfx::Point(26, 26);
4751 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4752 test_point, render_surface_layer_list);
4753 ASSERT_TRUE(result_layer);
4754 EXPECT_EQ(456, result_layer->id());
4755
4756 test_point = gfx::Point(74, 74);
4757 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4758 test_point, render_surface_layer_list);
4759 ASSERT_TRUE(result_layer);
4760 EXPECT_EQ(456, result_layer->id());
4761 }
4762
4763 TEST_F(LayerTreeHostCommonTest, HitTestingForMultiClippedRotatedLayer) {
4764 // This test checks whether hit testing correctly avoids hit testing with
4765 // multiple ancestors that clip in non axis-aligned ways. To pass this test,
4766 // the hit testing algorithm needs to recognize that multiple parent layers
4767 // may clip the layer, and should not actually hit those clipped areas.
4768 //
4769 // The child and grand_child layers are both initialized to clip the
4770 // rotated_leaf. The child layer is rotated about the top-left corner, so that
4771 // the root + child clips combined create a triangle. The rotated_leaf will
4772 // only be visible where it overlaps this triangle.
4773 //
4774 FakeImplProxy proxy;
4775 TestSharedBitmapManager shared_bitmap_manager;
4776 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4777 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 123);
4778
4779 gfx::Transform identity_matrix;
4780 gfx::PointF anchor;
4781 gfx::PointF position;
4782 gfx::Size bounds(100, 100);
4783 SetLayerPropertiesForTesting(root.get(),
4784 identity_matrix,
4785 anchor,
4786 position,
4787 bounds,
4788 true,
4789 false);
4790 root->SetMasksToBounds(true);
4791 {
4792 scoped_ptr<LayerImpl> child =
4793 LayerImpl::Create(host_impl.active_tree(), 456);
4794 scoped_ptr<LayerImpl> grand_child =
4795 LayerImpl::Create(host_impl.active_tree(), 789);
4796 scoped_ptr<LayerImpl> rotated_leaf =
4797 LayerImpl::Create(host_impl.active_tree(), 2468);
4798
4799 position = gfx::PointF(10.f, 10.f);
4800 bounds = gfx::Size(80, 80);
4801 SetLayerPropertiesForTesting(child.get(),
4802 identity_matrix,
4803 anchor,
4804 position,
4805 bounds,
4806 true,
4807 false);
4808 child->SetMasksToBounds(true);
4809
4810 gfx::Transform rotation45_degrees_about_corner;
4811 rotation45_degrees_about_corner.RotateAboutZAxis(45.0);
4812
4813 // remember, positioned with respect to its parent which is already at 10,
4814 // 10
4815 position = gfx::PointF();
4816 bounds =
4817 gfx::Size(200, 200); // to ensure it covers at least sqrt(2) * 100.
4818 SetLayerPropertiesForTesting(grand_child.get(),
4819 rotation45_degrees_about_corner,
4820 anchor,
4821 position,
4822 bounds,
4823 true,
4824 false);
4825 grand_child->SetMasksToBounds(true);
4826
4827 // Rotates about the center of the layer
4828 gfx::Transform rotated_leaf_transform;
4829 rotated_leaf_transform.Translate(
4830 -10.0, -10.0); // cancel out the grand_parent's position
4831 rotated_leaf_transform.RotateAboutZAxis(
4832 -45.0); // cancel out the corner 45-degree rotation of the parent.
4833 rotated_leaf_transform.Translate(50.0, 50.0);
4834 rotated_leaf_transform.RotateAboutZAxis(45.0);
4835 rotated_leaf_transform.Translate(-50.0, -50.0);
4836 position = gfx::PointF();
4837 bounds = gfx::Size(100, 100);
4838 SetLayerPropertiesForTesting(rotated_leaf.get(),
4839 rotated_leaf_transform,
4840 anchor,
4841 position,
4842 bounds,
4843 true,
4844 false);
4845 rotated_leaf->SetDrawsContent(true);
4846
4847 grand_child->AddChild(rotated_leaf.Pass());
4848 child->AddChild(grand_child.Pass());
4849 root->AddChild(child.Pass());
4850 }
4851
4852 LayerImplList render_surface_layer_list;
4853 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4854 root.get(), root->bounds(), &render_surface_layer_list);
4855 inputs.can_adjust_raster_scales = true;
4856 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4857
4858 // Sanity check the scenario we just created.
4859 // The grand_child is expected to create a render surface because it
4860 // MasksToBounds and is not axis aligned.
4861 ASSERT_EQ(2u, render_surface_layer_list.size());
4862 ASSERT_EQ(
4863 1u,
4864 render_surface_layer_list.at(0)->render_surface()->layer_list().size());
4865 ASSERT_EQ(789,
4866 render_surface_layer_list.at(0)->render_surface()->layer_list().at(
4867 0)->id()); // grand_child's surface.
4868 ASSERT_EQ(
4869 1u,
4870 render_surface_layer_list.at(1)->render_surface()->layer_list().size());
4871 ASSERT_EQ(
4872 2468,
4873 render_surface_layer_list[1]->render_surface()->layer_list().at(0)->id());
4874
4875 // (11, 89) is close to the the bottom left corner within the clip, but it is
4876 // not inside the layer.
4877 gfx::Point test_point(11, 89);
4878 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4879 test_point, render_surface_layer_list);
4880 EXPECT_FALSE(result_layer);
4881
4882 // Closer inwards from the bottom left will overlap the layer.
4883 test_point = gfx::Point(25, 75);
4884 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4885 test_point, render_surface_layer_list);
4886 ASSERT_TRUE(result_layer);
4887 EXPECT_EQ(2468, result_layer->id());
4888
4889 // (4, 50) is inside the unclipped layer, but that corner of the layer should
4890 // be clipped away by the grandparent and should not get hit. If hit testing
4891 // blindly uses visible content rect without considering how parent may clip
4892 // the layer, then hit testing would accidentally think that the point
4893 // successfully hits the layer.
4894 test_point = gfx::Point(4, 50);
4895 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4896 test_point, render_surface_layer_list);
4897 EXPECT_FALSE(result_layer);
4898
4899 // (11, 50) is inside the layer and within the clipped area.
4900 test_point = gfx::Point(11, 50);
4901 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4902 test_point, render_surface_layer_list);
4903 ASSERT_TRUE(result_layer);
4904 EXPECT_EQ(2468, result_layer->id());
4905
4906 // Around the middle, just to the right and up, would have hit the layer
4907 // except that that area should be clipped away by the parent.
4908 test_point = gfx::Point(51, 49);
4909 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4910 test_point, render_surface_layer_list);
4911 EXPECT_FALSE(result_layer);
4912
4913 // Around the middle, just to the left and down, should successfully hit the
4914 // layer.
4915 test_point = gfx::Point(49, 51);
4916 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4917 test_point, render_surface_layer_list);
4918 ASSERT_TRUE(result_layer);
4919 EXPECT_EQ(2468, result_layer->id());
4920 }
4921
4922 TEST_F(LayerTreeHostCommonTest, HitTestingForNonClippingIntermediateLayer) {
4923 // This test checks that hit testing code does not accidentally clip to layer
4924 // bounds for a layer that actually does not clip.
4925 gfx::Transform identity_matrix;
4926 gfx::PointF anchor;
4927
4928 FakeImplProxy proxy;
4929 TestSharedBitmapManager shared_bitmap_manager;
4930 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
4931 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
4932 SetLayerPropertiesForTesting(root.get(),
4933 identity_matrix,
4934 anchor,
4935 gfx::PointF(),
4936 gfx::Size(100, 100),
4937 true,
4938 false);
4939 {
4940 scoped_ptr<LayerImpl> intermediate_layer =
4941 LayerImpl::Create(host_impl.active_tree(), 123);
4942 // this layer is positioned, and hit testing should correctly know where the
4943 // layer is located.
4944 gfx::PointF position(10.f, 10.f);
4945 gfx::Size bounds(50, 50);
4946 SetLayerPropertiesForTesting(intermediate_layer.get(),
4947 identity_matrix,
4948 anchor,
4949 position,
4950 bounds,
4951 true,
4952 false);
4953 // Sanity check the intermediate layer should not clip.
4954 ASSERT_FALSE(intermediate_layer->masks_to_bounds());
4955 ASSERT_FALSE(intermediate_layer->mask_layer());
4956
4957 // The child of the intermediate_layer is translated so that it does not
4958 // overlap intermediate_layer at all. If child is incorrectly clipped, we
4959 // would not be able to hit it successfully.
4960 scoped_ptr<LayerImpl> child =
4961 LayerImpl::Create(host_impl.active_tree(), 456);
4962 position = gfx::PointF(60.f, 60.f); // 70, 70 in screen space
4963 bounds = gfx::Size(20, 20);
4964 SetLayerPropertiesForTesting(child.get(),
4965 identity_matrix,
4966 anchor,
4967 position,
4968 bounds,
4969 true,
4970 false);
4971 child->SetDrawsContent(true);
4972 intermediate_layer->AddChild(child.Pass());
4973 root->AddChild(intermediate_layer.Pass());
4974 }
4975
4976 LayerImplList render_surface_layer_list;
4977 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4978 root.get(), root->bounds(), &render_surface_layer_list);
4979 inputs.can_adjust_raster_scales = true;
4980 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4981
4982 // Sanity check the scenario we just created.
4983 ASSERT_EQ(1u, render_surface_layer_list.size());
4984 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4985 ASSERT_EQ(456, root->render_surface()->layer_list().at(0)->id());
4986
4987 // Hit testing for a point outside the layer should return a null pointer.
4988 gfx::Point test_point(69, 69);
4989 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4990 test_point, render_surface_layer_list);
4991 EXPECT_FALSE(result_layer);
4992
4993 test_point = gfx::Point(91, 91);
4994 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4995 test_point, render_surface_layer_list);
4996 EXPECT_FALSE(result_layer);
4997
4998 // Hit testing for a point inside should return the child layer.
4999 test_point = gfx::Point(71, 71);
5000 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5001 test_point, render_surface_layer_list);
5002 ASSERT_TRUE(result_layer);
5003 EXPECT_EQ(456, result_layer->id());
5004
5005 test_point = gfx::Point(89, 89);
5006 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5007 test_point, render_surface_layer_list);
5008 ASSERT_TRUE(result_layer);
5009 EXPECT_EQ(456, result_layer->id());
5010 }
5011
5012 TEST_F(LayerTreeHostCommonTest, HitTestingForMultipleLayers) {
5013 FakeImplProxy proxy;
5014 TestSharedBitmapManager shared_bitmap_manager;
5015 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
5016 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5017
5018 gfx::Transform identity_matrix;
5019 gfx::PointF anchor;
5020 gfx::PointF position;
5021 gfx::Size bounds(100, 100);
5022 SetLayerPropertiesForTesting(root.get(),
5023 identity_matrix,
5024 anchor,
5025 position,
5026 bounds,
5027 true,
5028 false);
5029 root->SetDrawsContent(true);
5030 {
5031 // child 1 and child2 are initialized to overlap between x=50 and x=60.
5032 // grand_child is set to overlap both child1 and child2 between y=50 and
5033 // y=60. The expected stacking order is: (front) child2, (second)
5034 // grand_child, (third) child1, and (back) the root layer behind all other
5035 // layers.
5036
5037 scoped_ptr<LayerImpl> child1 =
5038 LayerImpl::Create(host_impl.active_tree(), 2);
5039 scoped_ptr<LayerImpl> child2 =
5040 LayerImpl::Create(host_impl.active_tree(), 3);
5041 scoped_ptr<LayerImpl> grand_child1 =
5042 LayerImpl::Create(host_impl.active_tree(), 4);
5043
5044 position = gfx::PointF(10.f, 10.f);
5045 bounds = gfx::Size(50, 50);
5046 SetLayerPropertiesForTesting(child1.get(),
5047 identity_matrix,
5048 anchor,
5049 position,
5050 bounds,
5051 true,
5052 false);
5053 child1->SetDrawsContent(true);
5054
5055 position = gfx::PointF(50.f, 10.f);
5056 bounds = gfx::Size(50, 50);
5057 SetLayerPropertiesForTesting(child2.get(),
5058 identity_matrix,
5059 anchor,
5060 position,
5061 bounds,
5062 true,
5063 false);
5064 child2->SetDrawsContent(true);
5065
5066 // Remember that grand_child is positioned with respect to its parent (i.e.
5067 // child1). In screen space, the intended position is (10, 50), with size
5068 // 100 x 50.
5069 position = gfx::PointF(0.f, 40.f);
5070 bounds = gfx::Size(100, 50);
5071 SetLayerPropertiesForTesting(grand_child1.get(),
5072 identity_matrix,
5073 anchor,
5074 position,
5075 bounds,
5076 true,
5077 false);
5078 grand_child1->SetDrawsContent(true);
5079
5080 child1->AddChild(grand_child1.Pass());
5081 root->AddChild(child1.Pass());
5082 root->AddChild(child2.Pass());
5083 }
5084
5085 LayerImpl* child1 = root->children()[0];
5086 LayerImpl* child2 = root->children()[1];
5087 LayerImpl* grand_child1 = child1->children()[0];
5088
5089 LayerImplList render_surface_layer_list;
5090 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5091 root.get(), root->bounds(), &render_surface_layer_list);
5092 inputs.can_adjust_raster_scales = true;
5093 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5094
5095 // Sanity check the scenario we just created.
5096 ASSERT_TRUE(child1);
5097 ASSERT_TRUE(child2);
5098 ASSERT_TRUE(grand_child1);
5099 ASSERT_EQ(1u, render_surface_layer_list.size());
5100
5101 RenderSurfaceImpl* root_render_surface = root->render_surface();
5102 ASSERT_EQ(4u, root_render_surface->layer_list().size());
5103 ASSERT_EQ(1, root_render_surface->layer_list().at(0)->id()); // root layer
5104 ASSERT_EQ(2, root_render_surface->layer_list().at(1)->id()); // child1
5105 ASSERT_EQ(4, root_render_surface->layer_list().at(2)->id()); // grand_child1
5106 ASSERT_EQ(3, root_render_surface->layer_list().at(3)->id()); // child2
5107
5108 // Nothing overlaps the root_layer at (1, 1), so hit testing there should find
5109 // the root layer.
5110 gfx::Point test_point = gfx::Point(1, 1);
5111 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5112 test_point, render_surface_layer_list);
5113 ASSERT_TRUE(result_layer);
5114 EXPECT_EQ(1, result_layer->id());
5115
5116 // At (15, 15), child1 and root are the only layers. child1 is expected to be
5117 // on top.
5118 test_point = gfx::Point(15, 15);
5119 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5120 test_point, render_surface_layer_list);
5121 ASSERT_TRUE(result_layer);
5122 EXPECT_EQ(2, result_layer->id());
5123
5124 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
5125 test_point = gfx::Point(51, 20);
5126 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5127 test_point, render_surface_layer_list);
5128 ASSERT_TRUE(result_layer);
5129 EXPECT_EQ(3, result_layer->id());
5130
5131 // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
5132 // top.
5133 test_point = gfx::Point(80, 51);
5134 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5135 test_point, render_surface_layer_list);
5136 ASSERT_TRUE(result_layer);
5137 EXPECT_EQ(3, result_layer->id());
5138
5139 // At (51, 51), all layers overlap each other. child2 is expected to be on top
5140 // of all other layers.
5141 test_point = gfx::Point(51, 51);
5142 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5143 test_point, render_surface_layer_list);
5144 ASSERT_TRUE(result_layer);
5145 EXPECT_EQ(3, result_layer->id());
5146
5147 // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
5148 // be on top.
5149 test_point = gfx::Point(20, 51);
5150 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5151 test_point, render_surface_layer_list);
5152 ASSERT_TRUE(result_layer);
5153 EXPECT_EQ(4, result_layer->id());
5154 }
5155
5156 TEST_F(LayerTreeHostCommonTest, HitTestingForMultipleLayerLists) {
5157 //
5158 // The geometry is set up similarly to the previous case, but
5159 // all layers are forced to be render surfaces now.
5160 //
5161 FakeImplProxy proxy;
5162 TestSharedBitmapManager shared_bitmap_manager;
5163 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
5164 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5165
5166 gfx::Transform identity_matrix;
5167 gfx::PointF anchor;
5168 gfx::PointF position;
5169 gfx::Size bounds(100, 100);
5170 SetLayerPropertiesForTesting(root.get(),
5171 identity_matrix,
5172 anchor,
5173 position,
5174 bounds,
5175 true,
5176 false);
5177 root->SetDrawsContent(true);
5178 {
5179 // child 1 and child2 are initialized to overlap between x=50 and x=60.
5180 // grand_child is set to overlap both child1 and child2 between y=50 and
5181 // y=60. The expected stacking order is: (front) child2, (second)
5182 // grand_child, (third) child1, and (back) the root layer behind all other
5183 // layers.
5184
5185 scoped_ptr<LayerImpl> child1 =
5186 LayerImpl::Create(host_impl.active_tree(), 2);
5187 scoped_ptr<LayerImpl> child2 =
5188 LayerImpl::Create(host_impl.active_tree(), 3);
5189 scoped_ptr<LayerImpl> grand_child1 =
5190 LayerImpl::Create(host_impl.active_tree(), 4);
5191
5192 position = gfx::PointF(10.f, 10.f);
5193 bounds = gfx::Size(50, 50);
5194 SetLayerPropertiesForTesting(child1.get(),
5195 identity_matrix,
5196 anchor,
5197 position,
5198 bounds,
5199 true,
5200 false);
5201 child1->SetDrawsContent(true);
5202 child1->SetForceRenderSurface(true);
5203
5204 position = gfx::PointF(50.f, 10.f);
5205 bounds = gfx::Size(50, 50);
5206 SetLayerPropertiesForTesting(child2.get(),
5207 identity_matrix,
5208 anchor,
5209 position,
5210 bounds,
5211 true,
5212 false);
5213 child2->SetDrawsContent(true);
5214 child2->SetForceRenderSurface(true);
5215
5216 // Remember that grand_child is positioned with respect to its parent (i.e.
5217 // child1). In screen space, the intended position is (10, 50), with size
5218 // 100 x 50.
5219 position = gfx::PointF(0.f, 40.f);
5220 bounds = gfx::Size(100, 50);
5221 SetLayerPropertiesForTesting(grand_child1.get(),
5222 identity_matrix,
5223 anchor,
5224 position,
5225 bounds,
5226 true,
5227 false);
5228 grand_child1->SetDrawsContent(true);
5229 grand_child1->SetForceRenderSurface(true);
5230
5231 child1->AddChild(grand_child1.Pass());
5232 root->AddChild(child1.Pass());
5233 root->AddChild(child2.Pass());
5234 }
5235
5236 LayerImpl* child1 = root->children()[0];
5237 LayerImpl* child2 = root->children()[1];
5238 LayerImpl* grand_child1 = child1->children()[0];
5239
5240 LayerImplList render_surface_layer_list;
5241 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5242 root.get(), root->bounds(), &render_surface_layer_list);
5243 inputs.can_adjust_raster_scales = true;
5244 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5245
5246 // Sanity check the scenario we just created.
5247 ASSERT_TRUE(child1);
5248 ASSERT_TRUE(child2);
5249 ASSERT_TRUE(grand_child1);
5250 ASSERT_TRUE(child1->render_surface());
5251 ASSERT_TRUE(child2->render_surface());
5252 ASSERT_TRUE(grand_child1->render_surface());
5253 ASSERT_EQ(4u, render_surface_layer_list.size());
5254 // The root surface has the root layer, and child1's and child2's render
5255 // surfaces.
5256 ASSERT_EQ(3u, root->render_surface()->layer_list().size());
5257 // The child1 surface has the child1 layer and grand_child1's render surface.
5258 ASSERT_EQ(2u, child1->render_surface()->layer_list().size());
5259 ASSERT_EQ(1u, child2->render_surface()->layer_list().size());
5260 ASSERT_EQ(1u, grand_child1->render_surface()->layer_list().size());
5261 ASSERT_EQ(1, render_surface_layer_list.at(0)->id()); // root layer
5262 ASSERT_EQ(2, render_surface_layer_list[1]->id()); // child1
5263 ASSERT_EQ(4, render_surface_layer_list.at(2)->id()); // grand_child1
5264 ASSERT_EQ(3, render_surface_layer_list[3]->id()); // child2
5265
5266 // Nothing overlaps the root_layer at (1, 1), so hit testing there should find
5267 // the root layer.
5268 gfx::Point test_point = gfx::Point(1, 1);
5269 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5270 test_point, render_surface_layer_list);
5271 ASSERT_TRUE(result_layer);
5272 EXPECT_EQ(1, result_layer->id());
5273
5274 // At (15, 15), child1 and root are the only layers. child1 is expected to be
5275 // on top.
5276 test_point = gfx::Point(15, 15);
5277 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5278 test_point, render_surface_layer_list);
5279 ASSERT_TRUE(result_layer);
5280 EXPECT_EQ(2, result_layer->id());
5281
5282 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
5283 test_point = gfx::Point(51, 20);
5284 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5285 test_point, render_surface_layer_list);
5286 ASSERT_TRUE(result_layer);
5287 EXPECT_EQ(3, result_layer->id());
5288
5289 // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
5290 // top.
5291 test_point = gfx::Point(80, 51);
5292 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5293 test_point, render_surface_layer_list);
5294 ASSERT_TRUE(result_layer);
5295 EXPECT_EQ(3, result_layer->id());
5296
5297 // At (51, 51), all layers overlap each other. child2 is expected to be on top
5298 // of all other layers.
5299 test_point = gfx::Point(51, 51);
5300 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5301 test_point, render_surface_layer_list);
5302 ASSERT_TRUE(result_layer);
5303 EXPECT_EQ(3, result_layer->id());
5304
5305 // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
5306 // be on top.
5307 test_point = gfx::Point(20, 51);
5308 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5309 test_point, render_surface_layer_list);
5310 ASSERT_TRUE(result_layer);
5311 EXPECT_EQ(4, result_layer->id());
5312 }
5313
5314 TEST_F(LayerTreeHostCommonTest, HitTestingForEmptyLayers) {
5315 FakeImplProxy proxy;
5316 TestSharedBitmapManager shared_bitmap_manager;
5317 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
5318
5319 // Layer 1 - root
5320 scoped_ptr<LayerImpl> root =
5321 LayerImpl::Create(host_impl.active_tree(), 1);
5322 gfx::Transform identity_matrix;
5323 gfx::PointF anchor;
5324 gfx::PointF position;
5325 gfx::Size bounds(100, 100);
5326 SetLayerPropertiesForTesting(root.get(),
5327 identity_matrix,
5328 anchor,
5329 position,
5330 bounds,
5331 true,
5332 false);
5333 root->SetDrawsContent(true);
5334
5335 {
5336 // Layer 2 - empty: drawsContent=false
5337 gfx::PointF position(10.f, 10.f);
5338 gfx::Size bounds(30, 30);
5339 scoped_ptr<LayerImpl> empty_layer =
5340 LayerImpl::Create(host_impl.active_tree(), 2);
5341 SetLayerPropertiesForTesting(empty_layer.get(),
5342 identity_matrix,
5343 anchor,
5344 position,
5345 bounds,
5346 true,
5347 false);
5348
5349 empty_layer->SetDrawsContent(false);
5350 root->AddChild(empty_layer.Pass());
5351 }
5352
5353 {
5354 // Layer 3 - empty, but has touch handler
5355 gfx::PointF position(10.f, 60.f);
5356 gfx::Size bounds(30, 30);
5357 scoped_ptr<LayerImpl> test_layer =
5358 LayerImpl::Create(host_impl.active_tree(), 3);
5359 SetLayerPropertiesForTesting(test_layer.get(),
5360 identity_matrix,
5361 anchor,
5362 position,
5363 bounds,
5364 true,
5365 false);
5366
5367 test_layer->SetDrawsContent(false);
5368 Region touch_handler_region(gfx::Rect(10, 10, 10, 10));
5369 test_layer->SetTouchEventHandlerRegion(touch_handler_region);
5370 root->AddChild(test_layer.Pass());
5371 }
5372
5373 {
5374 // Layer 4 - empty, but has mousewheel handler
5375 gfx::PointF position(60.f, 60.f);
5376 gfx::Size bounds(30, 30);
5377 scoped_ptr<LayerImpl> test_layer =
5378 LayerImpl::Create(host_impl.active_tree(), 4);
5379 SetLayerPropertiesForTesting(test_layer.get(),
5380 identity_matrix,
5381 anchor,
5382 position,
5383 bounds,
5384 true,
5385 false);
5386
5387 test_layer->SetDrawsContent(false);
5388 test_layer->SetHaveWheelEventHandlers(true);
5389 root->AddChild(test_layer.Pass());
5390 }
5391
5392 LayerImplList render_surface_layer_list;
5393 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5394 root.get(), root->bounds(), &render_surface_layer_list);
5395 inputs.can_adjust_raster_scales = true;
5396 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5397
5398 // Verify that the root layer and empty layers with touch/wheel handlers
5399 // (but not the empty layer without a touch handler) are in the RSSL.
5400 ASSERT_EQ(1u, render_surface_layer_list.size());
5401 EXPECT_EQ(1, render_surface_layer_list[0]->id());
5402 ASSERT_EQ(3u, root->render_surface()->layer_list().size());
5403 EXPECT_EQ(1, root->render_surface()->layer_list().at(0)->id());
5404 EXPECT_EQ(3, root->render_surface()->layer_list().at(1)->id());
5405 EXPECT_EQ(4, root->render_surface()->layer_list().at(2)->id());
5406
5407 // Hit testing for a point inside the empty no-handlers layer should return
5408 // the root layer.
5409 gfx::Point test_point = gfx::Point(15, 15);
5410 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5411 test_point, render_surface_layer_list);
5412 ASSERT_TRUE(result_layer);
5413 EXPECT_EQ(1, result_layer->id());
5414
5415 // Hit testing for a point inside the touch handler layer should return it.
5416 test_point = gfx::Point(15, 75);
5417 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5418 test_point, render_surface_layer_list);
5419 ASSERT_TRUE(result_layer);
5420 EXPECT_EQ(3, result_layer->id());
5421
5422 // Hit testing for a point inside the mousewheel layer should return it.
5423 test_point = gfx::Point(75, 75);
5424 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5425 test_point, render_surface_layer_list);
5426 ASSERT_TRUE(result_layer);
5427 EXPECT_EQ(4, result_layer->id());
5428 }
5429
5430 TEST_F(LayerTreeHostCommonTest,
5431 HitCheckingTouchHandlerRegionsForEmptyLayerList) {
5432 // Hit checking on an empty render_surface_layer_list should return a null
5433 // pointer.
5434 LayerImplList render_surface_layer_list;
5435
5436 gfx::Point test_point(0, 0);
5437 LayerImpl* result_layer =
5438 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5439 test_point, render_surface_layer_list);
5440 EXPECT_FALSE(result_layer);
5441
5442 test_point = gfx::Point(10, 20);
5443 result_layer =
5444 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5445 test_point, render_surface_layer_list);
5446 EXPECT_FALSE(result_layer);
5447 }
5448
5449 TEST_F(LayerTreeHostCommonTest, HitCheckingTouchHandlerRegionsForSingleLayer) {
5450 FakeImplProxy proxy;
5451 TestSharedBitmapManager shared_bitmap_manager;
5452 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
5453 scoped_ptr<LayerImpl> root =
5454 LayerImpl::Create(host_impl.active_tree(), 12345);
5455
5456 gfx::Transform identity_matrix;
5457 Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
5458 gfx::PointF anchor;
5459 gfx::PointF position;
5460 gfx::Size bounds(100, 100);
5461 SetLayerPropertiesForTesting(root.get(),
5462 identity_matrix,
5463 anchor,
5464 position,
5465 bounds,
5466 true,
5467 false);
5468 root->SetDrawsContent(true);
5469
5470 LayerImplList render_surface_layer_list;
5471 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5472 root.get(), root->bounds(), &render_surface_layer_list);
5473 inputs.can_adjust_raster_scales = true;
5474 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5475
5476 // Sanity check the scenario we just created.
5477 ASSERT_EQ(1u, render_surface_layer_list.size());
5478 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5479
5480 // Hit checking for any point should return a null pointer for a layer without
5481 // any touch event handler regions.
5482 gfx::Point test_point(11, 11);
5483 LayerImpl* result_layer =
5484 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5485 test_point, render_surface_layer_list);
5486 EXPECT_FALSE(result_layer);
5487
5488 root->SetTouchEventHandlerRegion(touch_handler_region);
5489 // Hit checking for a point outside the layer should return a null pointer.
5490 test_point = gfx::Point(101, 101);
5491 result_layer =
5492 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5493 test_point, render_surface_layer_list);
5494 EXPECT_FALSE(result_layer);
5495
5496 test_point = gfx::Point(-1, -1);
5497 result_layer =
5498 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5499 test_point, render_surface_layer_list);
5500 EXPECT_FALSE(result_layer);
5501
5502 // Hit checking for a point inside the layer, but outside the touch handler
5503 // region should return a null pointer.
5504 test_point = gfx::Point(1, 1);
5505 result_layer =
5506 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5507 test_point, render_surface_layer_list);
5508 EXPECT_FALSE(result_layer);
5509
5510 test_point = gfx::Point(99, 99);
5511 result_layer =
5512 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5513 test_point, render_surface_layer_list);
5514 EXPECT_FALSE(result_layer);
5515
5516 // Hit checking for a point inside the touch event handler region should
5517 // return the root layer.
5518 test_point = gfx::Point(11, 11);
5519 result_layer =
5520 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5521 test_point, render_surface_layer_list);
5522 ASSERT_TRUE(result_layer);
5523 EXPECT_EQ(12345, result_layer->id());
5524
5525 test_point = gfx::Point(59, 59);
5526 result_layer =
5527 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5528 test_point, render_surface_layer_list);
5529 ASSERT_TRUE(result_layer);
5530 EXPECT_EQ(12345, result_layer->id());
5531 }
5532
5533 TEST_F(LayerTreeHostCommonTest,
5534 HitCheckingTouchHandlerRegionsForUninvertibleTransform) {
5535 FakeImplProxy proxy;
5536 TestSharedBitmapManager shared_bitmap_manager;
5537 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
5538 scoped_ptr<LayerImpl> root =
5539 LayerImpl::Create(host_impl.active_tree(), 12345);
5540
5541 gfx::Transform uninvertible_transform;
5542 uninvertible_transform.matrix().set(0, 0, 0.0);
5543 uninvertible_transform.matrix().set(1, 1, 0.0);
5544 uninvertible_transform.matrix().set(2, 2, 0.0);
5545 uninvertible_transform.matrix().set(3, 3, 0.0);
5546 ASSERT_FALSE(uninvertible_transform.IsInvertible());
5547
5548 gfx::Transform identity_matrix;
5549 Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
5550 gfx::PointF anchor;
5551 gfx::PointF position;
5552 gfx::Size bounds(100, 100);
5553 SetLayerPropertiesForTesting(root.get(),
5554 uninvertible_transform,
5555 anchor,
5556 position,
5557 bounds,
5558 true,
5559 false);
5560 root->SetDrawsContent(true);
5561 root->SetTouchEventHandlerRegion(touch_handler_region);
5562
5563 LayerImplList render_surface_layer_list;
5564 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5565 root.get(), root->bounds(), &render_surface_layer_list);
5566 inputs.can_adjust_raster_scales = true;
5567 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5568
5569 // Sanity check the scenario we just created.
5570 ASSERT_EQ(1u, render_surface_layer_list.size());
5571 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5572 ASSERT_FALSE(root->screen_space_transform().IsInvertible());
5573
5574 // Hit checking any point should not hit the touch handler region on the
5575 // layer. If the invertible matrix is accidentally ignored and treated like an
5576 // identity, then the hit testing will incorrectly hit the layer when it
5577 // shouldn't.
5578 gfx::Point test_point(1, 1);
5579 LayerImpl* result_layer =
5580 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5581 test_point, render_surface_layer_list);
5582 EXPECT_FALSE(result_layer);
5583
5584 test_point = gfx::Point(10, 10);
5585 result_layer =
5586 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5587 test_point, render_surface_layer_list);
5588 EXPECT_FALSE(result_layer);
5589
5590 test_point = gfx::Point(10, 30);
5591 result_layer =
5592 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5593 test_point, render_surface_layer_list);
5594 EXPECT_FALSE(result_layer);
5595
5596 test_point = gfx::Point(50, 50);
5597 result_layer =
5598 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5599 test_point, render_surface_layer_list);
5600 EXPECT_FALSE(result_layer);
5601
5602 test_point = gfx::Point(67, 48);
5603 result_layer =
5604 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5605 test_point, render_surface_layer_list);
5606 EXPECT_FALSE(result_layer);
5607
5608 test_point = gfx::Point(99, 99);
5609 result_layer =
5610 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5611 test_point, render_surface_layer_list);
5612 EXPECT_FALSE(result_layer);
5613
5614 test_point = gfx::Point(-1, -1);
5615 result_layer =
5616 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5617 test_point, render_surface_layer_list);
5618 EXPECT_FALSE(result_layer);
5619 }
5620
5621 TEST_F(LayerTreeHostCommonTest,
5622 HitCheckingTouchHandlerRegionsForSinglePositionedLayer) {
5623 FakeImplProxy proxy;
5624 TestSharedBitmapManager shared_bitmap_manager;
5625 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
5626 scoped_ptr<LayerImpl> root =
5627 LayerImpl::Create(host_impl.active_tree(), 12345);
5628
5629 gfx::Transform identity_matrix;
5630 Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
5631 gfx::PointF anchor;
5632 // this layer is positioned, and hit testing should correctly know where the
5633 // layer is located.
5634 gfx::PointF position(50.f, 50.f);
5635 gfx::Size bounds(100, 100);
5636 SetLayerPropertiesForTesting(root.get(),
5637 identity_matrix,
5638 anchor,
5639 position,
5640 bounds,
5641 true,
5642 false);
5643 root->SetDrawsContent(true);
5644 root->SetTouchEventHandlerRegion(touch_handler_region);
5645
5646 LayerImplList render_surface_layer_list;
5647 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5648 root.get(), root->bounds(), &render_surface_layer_list);
5649 inputs.can_adjust_raster_scales = true;
5650 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5651
5652 // Sanity check the scenario we just created.
5653 ASSERT_EQ(1u, render_surface_layer_list.size());
5654 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5655
5656 // Hit checking for a point outside the layer should return a null pointer.
5657 gfx::Point test_point(49, 49);
5658 LayerImpl* result_layer =
5659 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5660 test_point, render_surface_layer_list);
5661 EXPECT_FALSE(result_layer);
5662
5663 // Even though the layer has a touch handler region containing (101, 101), it
5664 // should not be visible there since the root render surface would clamp it.
5665 test_point = gfx::Point(101, 101);
5666 result_layer =
5667 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5668 test_point, render_surface_layer_list);
5669 EXPECT_FALSE(result_layer);
5670
5671 // Hit checking for a point inside the layer, but outside the touch handler
5672 // region should return a null pointer.
5673 test_point = gfx::Point(51, 51);
5674 result_layer =
5675 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5676 test_point, render_surface_layer_list);
5677 EXPECT_FALSE(result_layer);
5678
5679 // Hit checking for a point inside the touch event handler region should
5680 // return the root layer.
5681 test_point = gfx::Point(61, 61);
5682 result_layer =
5683 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5684 test_point, render_surface_layer_list);
5685 ASSERT_TRUE(result_layer);
5686 EXPECT_EQ(12345, result_layer->id());
5687
5688 test_point = gfx::Point(99, 99);
5689 result_layer =
5690 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5691 test_point, render_surface_layer_list);
5692 ASSERT_TRUE(result_layer);
5693 EXPECT_EQ(12345, result_layer->id());
5694 }
5695
5696 TEST_F(LayerTreeHostCommonTest,
5697 HitCheckingTouchHandlerRegionsForSingleLayerWithScaledContents) {
5698 // A layer's visible content rect is actually in the layer's content space.
5699 // The screen space transform converts from the layer's origin space to screen
5700 // space. This test makes sure that hit testing works correctly accounts for
5701 // the contents scale. A contents scale that is not 1 effectively forces a
5702 // non-identity transform between layer's content space and layer's origin
5703 // space. The hit testing code must take this into account.
5704 //
5705 // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
5706 // contents scale is ignored, then hit checking will mis-interpret the visible
5707 // content rect as being larger than the actual bounds of the layer.
5708 //
5709 FakeImplProxy proxy;
5710 TestSharedBitmapManager shared_bitmap_manager;
5711 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
5712 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5713
5714 gfx::Transform identity_matrix;
5715 gfx::PointF anchor;
5716
5717 SetLayerPropertiesForTesting(root.get(),
5718 identity_matrix,
5719 anchor,
5720 gfx::PointF(),
5721 gfx::Size(100, 100),
5722 true,
5723 false);
5724 {
5725 Region touch_handler_region(gfx::Rect(10, 10, 30, 30));
5726 gfx::PointF position(25.f, 25.f);
5727 gfx::Size bounds(50, 50);
5728 scoped_ptr<LayerImpl> test_layer =
5729 LayerImpl::Create(host_impl.active_tree(), 12345);
5730 SetLayerPropertiesForTesting(test_layer.get(),
5731 identity_matrix,
5732 anchor,
5733 position,
5734 bounds,
5735 true,
5736 false);
5737
5738 // override content bounds and contents scale
5739 test_layer->SetContentBounds(gfx::Size(100, 100));
5740 test_layer->SetContentsScale(2, 2);
5741
5742 test_layer->SetDrawsContent(true);
5743 test_layer->SetTouchEventHandlerRegion(touch_handler_region);
5744 root->AddChild(test_layer.Pass());
5745 }
5746
5747 LayerImplList render_surface_layer_list;
5748 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5749 root.get(), root->bounds(), &render_surface_layer_list);
5750 inputs.can_adjust_raster_scales = true;
5751 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5752
5753 // Sanity check the scenario we just created.
5754 // The visible content rect for test_layer is actually 100x100, even though
5755 // its layout size is 50x50, positioned at 25x25.
5756 LayerImpl* test_layer = root->children()[0];
5757 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), test_layer->visible_content_rect());
5758 ASSERT_EQ(1u, render_surface_layer_list.size());
5759 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5760
5761 // Hit checking for a point outside the layer should return a null pointer
5762 // (the root layer does not draw content, so it will not be tested either).
5763 gfx::Point test_point(76, 76);
5764 LayerImpl* result_layer =
5765 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5766 test_point, render_surface_layer_list);
5767 EXPECT_FALSE(result_layer);
5768
5769 // Hit checking for a point inside the layer, but outside the touch handler
5770 // region should return a null pointer.
5771 test_point = gfx::Point(26, 26);
5772 result_layer =
5773 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5774 test_point, render_surface_layer_list);
5775 EXPECT_FALSE(result_layer);
5776
5777 test_point = gfx::Point(34, 34);
5778 result_layer =
5779 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5780 test_point, render_surface_layer_list);
5781 EXPECT_FALSE(result_layer);
5782
5783 test_point = gfx::Point(65, 65);
5784 result_layer =
5785 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5786 test_point, render_surface_layer_list);
5787 EXPECT_FALSE(result_layer);
5788
5789 test_point = gfx::Point(74, 74);
5790 result_layer =
5791 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5792 test_point, render_surface_layer_list);
5793 EXPECT_FALSE(result_layer);
5794
5795 // Hit checking for a point inside the touch event handler region should
5796 // return the root layer.
5797 test_point = gfx::Point(35, 35);
5798 result_layer =
5799 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5800 test_point, render_surface_layer_list);
5801 ASSERT_TRUE(result_layer);
5802 EXPECT_EQ(12345, result_layer->id());
5803
5804 test_point = gfx::Point(64, 64);
5805 result_layer =
5806 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5807 test_point, render_surface_layer_list);
5808 ASSERT_TRUE(result_layer);
5809 EXPECT_EQ(12345, result_layer->id());
5810 }
5811
5812 TEST_F(LayerTreeHostCommonTest,
5813 HitCheckingTouchHandlerRegionsForSingleLayerWithDeviceScale) {
5814 // The layer's device_scale_factor and page_scale_factor should scale the
5815 // content rect and we should be able to hit the touch handler region by
5816 // scaling the points accordingly.
5817 FakeImplProxy proxy;
5818 TestSharedBitmapManager shared_bitmap_manager;
5819 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
5820 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5821
5822 gfx::Transform identity_matrix;
5823 gfx::PointF anchor;
5824 // Set the bounds of the root layer big enough to fit the child when scaled.
5825 SetLayerPropertiesForTesting(root.get(),
5826 identity_matrix,
5827 anchor,
5828 gfx::PointF(),
5829 gfx::Size(100, 100),
5830 true,
5831 false);
5832 {
5833 Region touch_handler_region(gfx::Rect(10, 10, 30, 30));
5834 gfx::PointF position(25.f, 25.f);
5835 gfx::Size bounds(50, 50);
5836 scoped_ptr<LayerImpl> test_layer =
5837 LayerImpl::Create(host_impl.active_tree(), 12345);
5838 SetLayerPropertiesForTesting(test_layer.get(),
5839 identity_matrix,
5840 anchor,
5841 position,
5842 bounds,
5843 true,
5844 false);
5845
5846 test_layer->SetDrawsContent(true);
5847 test_layer->SetTouchEventHandlerRegion(touch_handler_region);
5848 root->AddChild(test_layer.Pass());
5849 }
5850
5851 LayerImplList render_surface_layer_list;
5852 float device_scale_factor = 3.f;
5853 float page_scale_factor = 5.f;
5854 gfx::Size scaled_bounds_for_root = gfx::ToCeiledSize(
5855 gfx::ScaleSize(root->bounds(), device_scale_factor * page_scale_factor));
5856
5857 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5858 root.get(), scaled_bounds_for_root, &render_surface_layer_list);
5859 inputs.device_scale_factor = device_scale_factor;
5860 inputs.page_scale_factor = page_scale_factor;
5861 inputs.page_scale_application_layer = root.get();
5862 inputs.can_adjust_raster_scales = true;
5863 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5864
5865 // Sanity check the scenario we just created.
5866 // The visible content rect for test_layer is actually 100x100, even though
5867 // its layout size is 50x50, positioned at 25x25.
5868 LayerImpl* test_layer = root->children()[0];
5869 ASSERT_EQ(1u, render_surface_layer_list.size());
5870 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5871
5872 // Check whether the child layer fits into the root after scaled.
5873 EXPECT_RECT_EQ(gfx::Rect(test_layer->content_bounds()),
5874 test_layer->visible_content_rect());
5875
5876 // Hit checking for a point outside the layer should return a null pointer
5877 // (the root layer does not draw content, so it will not be tested either).
5878 gfx::PointF test_point(76.f, 76.f);
5879 test_point =
5880 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5881 LayerImpl* result_layer =
5882 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5883 test_point, render_surface_layer_list);
5884 EXPECT_FALSE(result_layer);
5885
5886 // Hit checking for a point inside the layer, but outside the touch handler
5887 // region should return a null pointer.
5888 test_point = gfx::Point(26, 26);
5889 test_point =
5890 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5891 result_layer =
5892 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5893 test_point, render_surface_layer_list);
5894 EXPECT_FALSE(result_layer);
5895
5896 test_point = gfx::Point(34, 34);
5897 test_point =
5898 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5899 result_layer =
5900 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5901 test_point, render_surface_layer_list);
5902 EXPECT_FALSE(result_layer);
5903
5904 test_point = gfx::Point(65, 65);
5905 test_point =
5906 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5907 result_layer =
5908 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5909 test_point, render_surface_layer_list);
5910 EXPECT_FALSE(result_layer);
5911
5912 test_point = gfx::Point(74, 74);
5913 test_point =
5914 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5915 result_layer =
5916 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5917 test_point, render_surface_layer_list);
5918 EXPECT_FALSE(result_layer);
5919
5920 // Hit checking for a point inside the touch event handler region should
5921 // return the root layer.
5922 test_point = gfx::Point(35, 35);
5923 test_point =
5924 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5925 result_layer =
5926 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5927 test_point, render_surface_layer_list);
5928 ASSERT_TRUE(result_layer);
5929 EXPECT_EQ(12345, result_layer->id());
5930
5931 test_point = gfx::Point(64, 64);
5932 test_point =
5933 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5934 result_layer =
5935 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5936 test_point, render_surface_layer_list);
5937 ASSERT_TRUE(result_layer);
5938 EXPECT_EQ(12345, result_layer->id());
5939 }
5940
5941 TEST_F(LayerTreeHostCommonTest,
5942 HitCheckingTouchHandlerRegionsForSimpleClippedLayer) {
5943 // Test that hit-checking will only work for the visible portion of a layer,
5944 // and not the entire layer bounds. Here we just test the simple axis-aligned
5945 // case.
5946 gfx::Transform identity_matrix;
5947 gfx::PointF anchor;
5948
5949 FakeImplProxy proxy;
5950 TestSharedBitmapManager shared_bitmap_manager;
5951 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
5952 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5953 SetLayerPropertiesForTesting(root.get(),
5954 identity_matrix,
5955 anchor,
5956 gfx::PointF(),
5957 gfx::Size(100, 100),
5958 true,
5959 false);
5960 {
5961 scoped_ptr<LayerImpl> clipping_layer =
5962 LayerImpl::Create(host_impl.active_tree(), 123);
5963 // this layer is positioned, and hit testing should correctly know where the
5964 // layer is located.
5965 gfx::PointF position(25.f, 25.f);
5966 gfx::Size bounds(50, 50);
5967 SetLayerPropertiesForTesting(clipping_layer.get(),
5968 identity_matrix,
5969 anchor,
5970 position,
5971 bounds,
5972 true,
5973 false);
5974 clipping_layer->SetMasksToBounds(true);
5975
5976 scoped_ptr<LayerImpl> child =
5977 LayerImpl::Create(host_impl.active_tree(), 456);
5978 Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
5979 position = gfx::PointF(-50.f, -50.f);
5980 bounds = gfx::Size(300, 300);
5981 SetLayerPropertiesForTesting(child.get(),
5982 identity_matrix,
5983 anchor,
5984 position,
5985 bounds,
5986 true,
5987 false);
5988 child->SetDrawsContent(true);
5989 child->SetTouchEventHandlerRegion(touch_handler_region);
5990 clipping_layer->AddChild(child.Pass());
5991 root->AddChild(clipping_layer.Pass());
5992 }
5993
5994 LayerImplList render_surface_layer_list;
5995 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5996 root.get(), root->bounds(), &render_surface_layer_list);
5997 inputs.can_adjust_raster_scales = true;
5998 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5999
6000 // Sanity check the scenario we just created.
6001 ASSERT_EQ(1u, render_surface_layer_list.size());
6002 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
6003 ASSERT_EQ(456, root->render_surface()->layer_list().at(0)->id());
6004
6005 // Hit checking for a point outside the layer should return a null pointer.
6006 // Despite the child layer being very large, it should be clipped to the root
6007 // layer's bounds.
6008 gfx::Point test_point(24, 24);
6009 LayerImpl* result_layer =
6010 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6011 test_point, render_surface_layer_list);
6012 EXPECT_FALSE(result_layer);
6013
6014 // Hit checking for a point inside the layer, but outside the touch handler
6015 // region should return a null pointer.
6016 test_point = gfx::Point(35, 35);
6017 result_layer =
6018 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6019 test_point, render_surface_layer_list);
6020 EXPECT_FALSE(result_layer);
6021
6022 test_point = gfx::Point(74, 74);
6023 result_layer =
6024 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6025 test_point, render_surface_layer_list);
6026 EXPECT_FALSE(result_layer);
6027
6028 // Hit checking for a point inside the touch event handler region should
6029 // return the root layer.
6030 test_point = gfx::Point(25, 25);
6031 result_layer =
6032 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6033 test_point, render_surface_layer_list);
6034 ASSERT_TRUE(result_layer);
6035 EXPECT_EQ(456, result_layer->id());
6036
6037 test_point = gfx::Point(34, 34);
6038 result_layer =
6039 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6040 test_point, render_surface_layer_list);
6041 ASSERT_TRUE(result_layer);
6042 EXPECT_EQ(456, result_layer->id());
6043 }
6044
6045 TEST_F(LayerTreeHostCommonTest,
6046 HitCheckingTouchHandlerOverlappingRegions) {
6047 gfx::Transform identity_matrix;
6048 gfx::PointF anchor;
6049
6050 FakeImplProxy proxy;
6051 TestSharedBitmapManager shared_bitmap_manager;
6052 FakeLayerTreeHostImpl host_impl(&proxy, &shared_bitmap_manager);
6053 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
6054 SetLayerPropertiesForTesting(root.get(),
6055 identity_matrix,
6056 anchor,
6057 gfx::PointF(),
6058 gfx::Size(100, 100),
6059 true,
6060 false);
6061 {
6062 scoped_ptr<LayerImpl> touch_layer =
6063 LayerImpl::Create(host_impl.active_tree(), 123);
6064 // this layer is positioned, and hit testing should correctly know where the
6065 // layer is located.
6066 gfx::PointF position;
6067 gfx::Size bounds(50, 50);
6068 SetLayerPropertiesForTesting(touch_layer.get(),
6069 identity_matrix,
6070 anchor,
6071 position,
6072 bounds,
6073 true,
6074 false);
6075 touch_layer->SetDrawsContent(true);
6076 touch_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50));
6077 root->AddChild(touch_layer.Pass());
6078 }
6079
6080 {
6081 scoped_ptr<LayerImpl> notouch_layer =
6082 LayerImpl::Create(host_impl.active_tree(), 1234);
6083 // this layer is positioned, and hit testing should correctly know where the
6084 // layer is located.
6085 gfx::PointF position(0, 25);
6086 gfx::Size bounds(50, 50);
6087 SetLayerPropertiesForTesting(notouch_layer.get(),
6088 identity_matrix,
6089 anchor,
6090 position,
6091 bounds,
6092 true,
6093 false);
6094 notouch_layer->SetDrawsContent(true);
6095 root->AddChild(notouch_layer.Pass());
6096 }
6097
6098 LayerImplList render_surface_layer_list;
6099 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
6100 root.get(), root->bounds(), &render_surface_layer_list);
6101 inputs.can_adjust_raster_scales = true;
6102 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6103
6104 // Sanity check the scenario we just created.
6105 ASSERT_EQ(1u, render_surface_layer_list.size());
6106 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
6107 ASSERT_EQ(123, root->render_surface()->layer_list().at(0)->id());
6108 ASSERT_EQ(1234, root->render_surface()->layer_list().at(1)->id());
6109
6110 gfx::Point test_point(35, 35);
6111 LayerImpl* result_layer =
6112 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6113 test_point, render_surface_layer_list);
6114
6115 // We should have passed through the no-touch layer and found the layer
6116 // behind it.
6117 EXPECT_TRUE(result_layer);
6118
6119 host_impl.active_tree()->LayerById(1234)->SetContentsOpaque(true);
6120 result_layer =
6121 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6122 test_point, render_surface_layer_list);
6123
6124 // Even with an opaque layer in the middle, we should still find the layer
6125 // with
6126 // the touch handler behind it (since we can't assume that opaque layers are
6127 // opaque to hit testing).
6128 EXPECT_TRUE(result_layer);
6129
6130 test_point = gfx::Point(35, 15);
6131 result_layer =
6132 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6133 test_point, render_surface_layer_list);
6134 ASSERT_TRUE(result_layer);
6135 EXPECT_EQ(123, result_layer->id());
6136
6137 test_point = gfx::Point(35, 65);
6138 result_layer =
6139 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6140 test_point, render_surface_layer_list);
6141 EXPECT_FALSE(result_layer);
6142 }
6143
6144 class NoScaleContentLayer : public ContentLayer { 3998 class NoScaleContentLayer : public ContentLayer {
6145 public: 3999 public:
6146 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) { 4000 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
6147 return make_scoped_refptr(new NoScaleContentLayer(client)); 4001 return make_scoped_refptr(new NoScaleContentLayer(client));
6148 } 4002 }
6149 4003
6150 virtual void CalculateContentsScale(float ideal_contents_scale, 4004 virtual void CalculateContentsScale(float ideal_contents_scale,
6151 float device_scale_factor, 4005 float device_scale_factor,
6152 float page_scale_factor, 4006 float page_scale_factor,
6153 float maximum_animation_contents_scale, 4007 float maximum_animation_contents_scale,
(...skipping 4298 matching lines...) Expand 10 before | Expand all | Expand 10 after
10452 expected.insert(child_raw); 8306 expected.insert(child_raw);
10453 expected.insert(grand_child1_raw); 8307 expected.insert(grand_child1_raw);
10454 expected.insert(grand_child2_raw); 8308 expected.insert(grand_child2_raw);
10455 8309
10456 actual.clear(); 8310 actual.clear();
10457 GatherDrawnLayers(render_surface_layer_list_impl(), &actual); 8311 GatherDrawnLayers(render_surface_layer_list_impl(), &actual);
10458 EXPECT_EQ(expected, actual); 8312 EXPECT_EQ(expected, actual);
10459 } 8313 }
10460 } // namespace 8314 } // namespace
10461 } // namespace cc 8315 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698