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

Side by Side Diff: cc/layer_tree_host_impl_unittest.cc

Issue 12280014: cc: Don't consider HUD layer for touches (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moved funcs around Created 7 years, 10 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/layer_tree_host_impl.h" 5 #include "cc/layer_tree_host_impl.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/hash_tables.h" 11 #include "base/hash_tables.h"
12 #include "cc/compositor_frame_metadata.h" 12 #include "cc/compositor_frame_metadata.h"
13 #include "cc/delegated_renderer_layer_impl.h" 13 #include "cc/delegated_renderer_layer_impl.h"
14 #include "cc/gl_renderer.h" 14 #include "cc/gl_renderer.h"
15 #include "cc/heads_up_display_layer_impl.h" 15 #include "cc/heads_up_display_layer_impl.h"
16 #include "cc/io_surface_layer_impl.h" 16 #include "cc/io_surface_layer_impl.h"
17 #include "cc/layer.h"
17 #include "cc/layer_impl.h" 18 #include "cc/layer_impl.h"
18 #include "cc/layer_tiling_data.h" 19 #include "cc/layer_tiling_data.h"
19 #include "cc/layer_tree_impl.h" 20 #include "cc/layer_tree_impl.h"
20 #include "cc/math_util.h" 21 #include "cc/math_util.h"
21 #include "cc/quad_sink.h" 22 #include "cc/quad_sink.h"
22 #include "cc/render_pass_draw_quad.h" 23 #include "cc/render_pass_draw_quad.h"
23 #include "cc/scrollbar_geometry_fixed_thumb.h" 24 #include "cc/scrollbar_geometry_fixed_thumb.h"
24 #include "cc/scrollbar_layer_impl.h" 25 #include "cc/scrollbar_layer_impl.h"
25 #include "cc/single_thread_proxy.h" 26 #include "cc/single_thread_proxy.h"
26 #include "cc/solid_color_draw_quad.h" 27 #include "cc/solid_color_draw_quad.h"
27 #include "cc/test/animation_test_common.h" 28 #include "cc/test/animation_test_common.h"
29 #include "cc/test/fake_impl_proxy.h"
30 #include "cc/test/fake_layer_tree_host_impl.h"
28 #include "cc/test/fake_output_surface.h" 31 #include "cc/test/fake_output_surface.h"
29 #include "cc/test/fake_proxy.h" 32 #include "cc/test/fake_proxy.h"
30 #include "cc/test/fake_video_frame_provider.h" 33 #include "cc/test/fake_video_frame_provider.h"
31 #include "cc/test/fake_web_scrollbar_theme_geometry.h" 34 #include "cc/test/fake_web_scrollbar_theme_geometry.h"
32 #include "cc/test/geometry_test_utils.h" 35 #include "cc/test/geometry_test_utils.h"
33 #include "cc/test/layer_test_common.h" 36 #include "cc/test/layer_test_common.h"
34 #include "cc/test/render_pass_test_common.h" 37 #include "cc/test/render_pass_test_common.h"
35 #include "cc/test/test_web_graphics_context_3d.h" 38 #include "cc/test/test_web_graphics_context_3d.h"
36 #include "cc/texture_draw_quad.h" 39 #include "cc/texture_draw_quad.h"
37 #include "cc/texture_layer_impl.h" 40 #include "cc/texture_layer_impl.h"
38 #include "cc/tile_draw_quad.h" 41 #include "cc/tile_draw_quad.h"
39 #include "cc/tiled_layer_impl.h" 42 #include "cc/tiled_layer_impl.h"
40 #include "cc/video_layer_impl.h" 43 #include "cc/video_layer_impl.h"
41 #include "media/base/media.h" 44 #include "media/base/media.h"
42 #include "testing/gmock/include/gmock/gmock.h" 45 #include "testing/gmock/include/gmock/gmock.h"
43 #include "testing/gtest/include/gtest/gtest.h" 46 #include "testing/gtest/include/gtest/gtest.h"
44 #include "ui/gfx/size_conversions.h" 47 #include "ui/gfx/size_conversions.h"
45 #include "ui/gfx/vector2d_conversions.h" 48 #include "ui/gfx/vector2d_conversions.h"
46 49
47 using ::testing::Mock; 50 using ::testing::Mock;
48 using ::testing::Return; 51 using ::testing::Return;
49 using ::testing::AnyNumber; 52 using ::testing::AnyNumber;
50 using ::testing::AtLeast; 53 using ::testing::AtLeast;
51 using ::testing::_; 54 using ::testing::_;
52 using media::VideoFrame; 55 using media::VideoFrame;
53 56
54 namespace cc { 57 namespace cc {
55 namespace { 58 namespace {
56 59
60 template<typename LayerType>
61 void setLayerPropertiesForTestingInternal(LayerType* layer, const gfx::Transform & transform, const gfx::Transform& sublayerTransform, const gfx::PointF& anchor, const gfx::PointF& position, const gfx::Size& bounds, bool preserves3D)
62 {
63 layer->setTransform(transform);
64 layer->setSublayerTransform(sublayerTransform);
65 layer->setAnchorPoint(anchor);
66 layer->setPosition(position);
67 layer->setBounds(bounds);
68 layer->setPreserves3D(preserves3D);
69 }
70
71 void setLayerPropertiesForTesting(Layer* layer, const gfx::Transform& transform, const gfx::Transform& sublayerTransform, const gfx::PointF& anchor, const gfx:: PointF& position, const gfx::Size& bounds, bool preserves3D)
72 {
73 setLayerPropertiesForTestingInternal<Layer>(layer, transform, sublayerTransf orm, anchor, position, bounds, preserves3D);
74 layer->setAutomaticallyComputeRasterScale(true);
75 }
76
77 void setLayerPropertiesForTesting(LayerImpl* layer, const gfx::Transform& transf orm, const gfx::Transform& sublayerTransform, const gfx::PointF& anchor, const g fx::PointF& position, const gfx::Size& bounds, bool preserves3D)
78 {
79 setLayerPropertiesForTestingInternal<LayerImpl>(layer, transform, sublayerTr ansform, anchor, position, bounds, preserves3D);
80 layer->setContentBounds(bounds);
81 }
82
57 // This test is parametrized to run all tests with the 83 // This test is parametrized to run all tests with the
58 // m_settings.pageScalePinchZoomEnabled field enabled and disabled. 84 // m_settings.pageScalePinchZoomEnabled field enabled and disabled.
59 class LayerTreeHostImplTest : public testing::TestWithParam<bool>, 85 class LayerTreeHostImplTest : public testing::TestWithParam<bool>,
60 public LayerTreeHostImplClient { 86 public LayerTreeHostImplClient {
61 public: 87 public:
62 LayerTreeHostImplTest() 88 LayerTreeHostImplTest()
63 : m_proxy(scoped_ptr<Thread>(NULL)) 89 : m_proxy(scoped_ptr<Thread>(NULL))
64 , m_alwaysImplThread(&m_proxy) 90 , m_alwaysImplThread(&m_proxy)
65 , m_alwaysMainThreadBlocked(&m_proxy) 91 , m_alwaysMainThreadBlocked(&m_proxy)
66 , m_onCanDrawStateChangedCalled(false) 92 , m_onCanDrawStateChangedCalled(false)
(...skipping 4269 matching lines...) Expand 10 before | Expand all | Expand 10 after
4336 ASSERT_EQ(DrawQuad::RENDER_PASS, frame.renderPasses[0]->quad_list[0]->ma terial); 4362 ASSERT_EQ(DrawQuad::RENDER_PASS, frame.renderPasses[0]->quad_list[0]->ma terial);
4337 const RenderPassDrawQuad* renderPassQuad = RenderPassDrawQuad::MaterialC ast(frame.renderPasses[0]->quad_list[0]); 4363 const RenderPassDrawQuad* renderPassQuad = RenderPassDrawQuad::MaterialC ast(frame.renderPasses[0]->quad_list[0]);
4338 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), renderPassQuad->rect.ToS tring()); 4364 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), renderPassQuad->rect.ToS tring());
4339 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), renderPassQuad->mas k_uv_rect.ToString()); 4365 EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), renderPassQuad->mas k_uv_rect.ToString());
4340 4366
4341 m_hostImpl->drawLayers(frame); 4367 m_hostImpl->drawLayers(frame);
4342 m_hostImpl->didDrawAllLayers(frame); 4368 m_hostImpl->didDrawAllLayers(frame);
4343 } 4369 }
4344 } 4370 }
4345 4371
4372 TEST(LayerTreeHostImplTest, verifyHitTestingForEmptyLayerList)
4373 {
4374 FakeImplProxy proxy;
4375 FakeLayerTreeHostImpl hostImpl(&proxy);
4376
4377 // Hit testing on an empty renderSurfaceLayerList should return a null point er.
4378 std::vector<LayerImpl*> renderSurfaceLayerList;
4379
4380 gfx::Point testPoint(0, 0);
4381 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4382 EXPECT_FALSE(resultLayer);
4383
4384 testPoint = gfx::Point(10, 20);
4385 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4386 EXPECT_FALSE(resultLayer);
4387 }
4388
4389 TEST(LayerTreeHostImplTest, verifyHitTestingForSingleLayer)
4390 {
4391 FakeImplProxy proxy;
4392 FakeLayerTreeHostImpl hostImpl(&proxy);
4393 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 12345) ;
4394
4395 gfx::Transform identityMatrix;
4396 gfx::PointF anchor(0, 0);
4397 gfx::PointF position(0, 0);
4398 gfx::Size bounds(100, 100);
4399 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc hor, position, bounds, false);
4400 root->setDrawsContent(true);
4401
4402 std::vector<LayerImpl*> renderSurfaceLayerList;
4403 int dummyMaxTextureSize = 512;
4404 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4405
4406 // Sanity check the scenario we just created.
4407 ASSERT_EQ(1u, renderSurfaceLayerList.size());
4408 ASSERT_EQ(1u, root->renderSurface()->layerList().size());
4409
4410 // Hit testing for a point outside the layer should return a null pointer.
4411 gfx::Point testPoint(101, 101);
4412 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4413 EXPECT_FALSE(resultLayer);
4414
4415 testPoint = gfx::Point(-1, -1);
4416 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4417 EXPECT_FALSE(resultLayer);
4418
4419 // Hit testing for a point inside should return the root layer.
4420 testPoint = gfx::Point(1, 1);
4421 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4422 ASSERT_TRUE(resultLayer);
4423 EXPECT_EQ(12345, resultLayer->id());
4424
4425 testPoint = gfx::Point(99, 99);
4426 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4427 ASSERT_TRUE(resultLayer);
4428 EXPECT_EQ(12345, resultLayer->id());
4429 }
4430
4431 TEST(LayerTreeHostImplTest, verifyHitTestingForUninvertibleTransform)
4432 {
4433 FakeImplProxy proxy;
4434 FakeLayerTreeHostImpl hostImpl(&proxy);
4435 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 12345) ;
4436
4437 gfx::Transform uninvertibleTransform;
4438 uninvertibleTransform.matrix().setDouble(0, 0, 0);
4439 uninvertibleTransform.matrix().setDouble(1, 1, 0);
4440 uninvertibleTransform.matrix().setDouble(2, 2, 0);
4441 uninvertibleTransform.matrix().setDouble(3, 3, 0);
4442 ASSERT_FALSE(uninvertibleTransform.IsInvertible());
4443
4444 gfx::Transform identityMatrix;
4445 gfx::PointF anchor(0, 0);
4446 gfx::PointF position(0, 0);
4447 gfx::Size bounds(100, 100);
4448 setLayerPropertiesForTesting(root.get(), uninvertibleTransform, identityMatr ix, anchor, position, bounds, false);
4449 root->setDrawsContent(true);
4450
4451 std::vector<LayerImpl*> renderSurfaceLayerList;
4452 int dummyMaxTextureSize = 512;
4453 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4454
4455 // Sanity check the scenario we just created.
4456 ASSERT_EQ(1u, renderSurfaceLayerList.size());
4457 ASSERT_EQ(1u, root->renderSurface()->layerList().size());
4458 ASSERT_FALSE(root->screenSpaceTransform().IsInvertible());
4459
4460 // Hit testing any point should not hit the layer. If the invertible matrix is
4461 // accidentally ignored and treated like an identity, then the hit testing w ill
4462 // incorrectly hit the layer when it shouldn't.
4463 gfx::Point testPoint(1, 1);
4464 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4465 EXPECT_FALSE(resultLayer);
4466
4467 testPoint = gfx::Point(10, 10);
4468 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4469 EXPECT_FALSE(resultLayer);
4470
4471 testPoint = gfx::Point(10, 30);
4472 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4473 EXPECT_FALSE(resultLayer);
4474
4475 testPoint = gfx::Point(50, 50);
4476 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4477 EXPECT_FALSE(resultLayer);
4478
4479 testPoint = gfx::Point(67, 48);
4480 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4481 EXPECT_FALSE(resultLayer);
4482
4483 testPoint = gfx::Point(99, 99);
4484 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4485 EXPECT_FALSE(resultLayer);
4486
4487 testPoint = gfx::Point(-1, -1);
4488 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4489 EXPECT_FALSE(resultLayer);
4490 }
4491
4492 TEST(LayerTreeHostImplTest, verifyHitTestingForSinglePositionedLayer)
4493 {
4494 FakeImplProxy proxy;
4495 FakeLayerTreeHostImpl hostImpl(&proxy);
4496 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 12345) ;
4497
4498 gfx::Transform identityMatrix;
4499 gfx::PointF anchor(0, 0);
4500 gfx::PointF position(50, 50); // this layer is positioned, and hit testing s hould correctly know where the layer is located.
4501 gfx::Size bounds(100, 100);
4502 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc hor, position, bounds, false);
4503 root->setDrawsContent(true);
4504
4505 std::vector<LayerImpl*> renderSurfaceLayerList;
4506 int dummyMaxTextureSize = 512;
4507 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4508
4509 // Sanity check the scenario we just created.
4510 ASSERT_EQ(1u, renderSurfaceLayerList.size());
4511 ASSERT_EQ(1u, root->renderSurface()->layerList().size());
4512
4513 // Hit testing for a point outside the layer should return a null pointer.
4514 gfx::Point testPoint(49, 49);
4515 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4516 EXPECT_FALSE(resultLayer);
4517
4518 // Even though the layer exists at (101, 101), it should not be visible ther e since the root renderSurface would clamp it.
4519 testPoint = gfx::Point(101, 101);
4520 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4521 EXPECT_FALSE(resultLayer);
4522
4523 // Hit testing for a point inside should return the root layer.
4524 testPoint = gfx::Point(51, 51);
4525 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4526 ASSERT_TRUE(resultLayer);
4527 EXPECT_EQ(12345, resultLayer->id());
4528
4529 testPoint = gfx::Point(99, 99);
4530 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4531 ASSERT_TRUE(resultLayer);
4532 EXPECT_EQ(12345, resultLayer->id());
4533 }
4534
4535 TEST(LayerTreeHostImplTest, verifyHitTestingForSingleRotatedLayer)
4536 {
4537 FakeImplProxy proxy;
4538 FakeLayerTreeHostImpl hostImpl(&proxy);
4539 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 12345) ;
4540
4541 gfx::Transform identityMatrix;
4542 gfx::Transform rotation45DegreesAboutCenter;
4543 rotation45DegreesAboutCenter.Translate(50, 50);
4544 rotation45DegreesAboutCenter.RotateAboutZAxis(45);
4545 rotation45DegreesAboutCenter.Translate(-50, -50);
4546 gfx::PointF anchor(0, 0);
4547 gfx::PointF position(0, 0);
4548 gfx::Size bounds(100, 100);
4549 setLayerPropertiesForTesting(root.get(), rotation45DegreesAboutCenter, ident ityMatrix, anchor, position, bounds, false);
4550 root->setDrawsContent(true);
4551
4552 std::vector<LayerImpl*> renderSurfaceLayerList;
4553 int dummyMaxTextureSize = 512;
4554 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4555
4556 // Sanity check the scenario we just created.
4557 ASSERT_EQ(1u, renderSurfaceLayerList.size());
4558 ASSERT_EQ(1u, root->renderSurface()->layerList().size());
4559
4560 // Hit testing for points outside the layer.
4561 // These corners would have been inside the un-transformed layer, but they s hould not hit the correctly transformed layer.
4562 gfx::Point testPoint(99, 99);
4563 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4564 EXPECT_FALSE(resultLayer);
4565
4566 testPoint = gfx::Point(1, 1);
4567 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4568 EXPECT_FALSE(resultLayer);
4569
4570 // Hit testing for a point inside should return the root layer.
4571 testPoint = gfx::Point(1, 50);
4572 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4573 ASSERT_TRUE(resultLayer);
4574 EXPECT_EQ(12345, resultLayer->id());
4575
4576 // Hit testing the corners that would overlap the unclipped layer, but are o utside the clipped region.
4577 testPoint = gfx::Point(50, -1);
4578 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4579 ASSERT_FALSE(resultLayer);
4580
4581 testPoint = gfx::Point(-1, 50);
4582 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4583 ASSERT_FALSE(resultLayer);
4584 }
4585
4586 TEST(LayerTreeHostImplTest, verifyHitTestingForSinglePerspectiveLayer)
4587 {
4588 FakeImplProxy proxy;
4589 FakeLayerTreeHostImpl hostImpl(&proxy);
4590 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 12345) ;
4591
4592 gfx::Transform identityMatrix;
4593
4594 // perspectiveProjectionAboutCenter * translationByZ is designed so that the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50).
4595 gfx::Transform perspectiveProjectionAboutCenter;
4596 perspectiveProjectionAboutCenter.Translate(50, 50);
4597 perspectiveProjectionAboutCenter.ApplyPerspectiveDepth(1);
4598 perspectiveProjectionAboutCenter.Translate(-50, -50);
4599 gfx::Transform translationByZ;
4600 translationByZ.Translate3d(0, 0, -1);
4601
4602 gfx::PointF anchor(0, 0);
4603 gfx::PointF position(0, 0);
4604 gfx::Size bounds(100, 100);
4605 setLayerPropertiesForTesting(root.get(), perspectiveProjectionAboutCenter * translationByZ, identityMatrix, anchor, position, bounds, false);
4606 root->setDrawsContent(true);
4607
4608 std::vector<LayerImpl*> renderSurfaceLayerList;
4609 int dummyMaxTextureSize = 512;
4610 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4611
4612 // Sanity check the scenario we just created.
4613 ASSERT_EQ(1u, renderSurfaceLayerList.size());
4614 ASSERT_EQ(1u, root->renderSurface()->layerList().size());
4615
4616 // Hit testing for points outside the layer.
4617 // These corners would have been inside the un-transformed layer, but they s hould not hit the correctly transformed layer.
4618 gfx::Point testPoint(24, 24);
4619 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4620 EXPECT_FALSE(resultLayer);
4621
4622 testPoint = gfx::Point(76, 76);
4623 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4624 EXPECT_FALSE(resultLayer);
4625
4626 // Hit testing for a point inside should return the root layer.
4627 testPoint = gfx::Point(26, 26);
4628 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4629 ASSERT_TRUE(resultLayer);
4630 EXPECT_EQ(12345, resultLayer->id());
4631
4632 testPoint = gfx::Point(74, 74);
4633 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4634 ASSERT_TRUE(resultLayer);
4635 EXPECT_EQ(12345, resultLayer->id());
4636 }
4637
4638 TEST(LayerTreeHostImplTest, verifyHitTestingForSingleLayerWithScaledContents)
4639 {
4640 // A layer's visibleContentRect is actually in the layer's content space. Th e
4641 // screenSpaceTransform converts from the layer's origin space to screen spa ce. This
4642 // test makes sure that hit testing works correctly accounts for the content s scale.
4643 // A contentsScale that is not 1 effectively forces a non-identity transform between
4644 // layer's content space and layer's origin space. The hit testing code must take this into account.
4645 //
4646 // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
4647 // contentsScale is ignored, then hit testing will mis-interpret the visible ContentRect
4648 // as being larger than the actual bounds of the layer.
4649 //
4650 FakeImplProxy proxy;
4651 FakeLayerTreeHostImpl hostImpl(&proxy);
4652 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 1);
4653
4654 gfx::Transform identityMatrix;
4655 gfx::PointF anchor(0, 0);
4656
4657 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc hor, gfx::PointF(0, 0), gfx::Size(100, 100), false);
4658
4659 {
4660 gfx::PointF position(25, 25);
4661 gfx::Size bounds(50, 50);
4662 scoped_ptr<LayerImpl> testLayer = LayerImpl::create(hostImpl.activeTree( ), 12345);
4663 setLayerPropertiesForTesting(testLayer.get(), identityMatrix, identityMa trix, anchor, position, bounds, false);
4664
4665 // override contentBounds and contentsScale
4666 testLayer->setContentBounds(gfx::Size(100, 100));
4667 testLayer->setContentsScale(2, 2);
4668
4669 testLayer->setDrawsContent(true);
4670 root->addChild(testLayer.Pass());
4671 }
4672
4673 std::vector<LayerImpl*> renderSurfaceLayerList;
4674 int dummyMaxTextureSize = 512;
4675 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4676
4677 // Sanity check the scenario we just created.
4678 // The visibleContentRect for testLayer is actually 100x100, even though its layout size is 50x50, positioned at 25x25.
4679 LayerImpl* testLayer = root->children()[0];
4680 EXPECT_RECT_EQ(gfx::Rect(gfx::Point(), gfx::Size(100, 100)), testLayer->visi bleContentRect());
4681 ASSERT_EQ(1u, renderSurfaceLayerList.size());
4682 ASSERT_EQ(1u, root->renderSurface()->layerList().size());
4683
4684 // Hit testing for a point outside the layer should return a null pointer (t he root layer does not draw content, so it will not be hit tested either).
4685 gfx::Point testPoint(101, 101);
4686 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4687 EXPECT_FALSE(resultLayer);
4688
4689 testPoint = gfx::Point(24, 24);
4690 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4691 EXPECT_FALSE(resultLayer);
4692
4693 testPoint = gfx::Point(76, 76);
4694 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4695 EXPECT_FALSE(resultLayer);
4696
4697 // Hit testing for a point inside should return the test layer.
4698 testPoint = gfx::Point(26, 26);
4699 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4700 ASSERT_TRUE(resultLayer);
4701 EXPECT_EQ(12345, resultLayer->id());
4702
4703 testPoint = gfx::Point(74, 74);
4704 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4705 ASSERT_TRUE(resultLayer);
4706 EXPECT_EQ(12345, resultLayer->id());
4707 }
4708
4709 TEST(LayerTreeHostImplTest, verifyHitTestingForSimpleClippedLayer)
4710 {
4711 // Test that hit-testing will only work for the visible portion of a layer, and not
4712 // the entire layer bounds. Here we just test the simple axis-aligned case.
4713 gfx::Transform identityMatrix;
4714 gfx::PointF anchor(0, 0);
4715
4716 FakeImplProxy proxy;
4717 FakeLayerTreeHostImpl hostImpl(&proxy);
4718 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 1);
4719 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc hor, gfx::PointF(0, 0), gfx::Size(100, 100), false);
4720
4721 {
4722 scoped_ptr<LayerImpl> clippingLayer = LayerImpl::create(hostImpl.activeT ree(), 123);
4723 gfx::PointF position(25, 25); // this layer is positioned, and hit testi ng should correctly know where the layer is located.
4724 gfx::Size bounds(50, 50);
4725 setLayerPropertiesForTesting(clippingLayer.get(), identityMatrix, identi tyMatrix, anchor, position, bounds, false);
4726 clippingLayer->setMasksToBounds(true);
4727
4728 scoped_ptr<LayerImpl> child = LayerImpl::create(hostImpl.activeTree(), 4 56);
4729 position = gfx::PointF(-50, -50);
4730 bounds = gfx::Size(300, 300);
4731 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix , anchor, position, bounds, false);
4732 child->setDrawsContent(true);
4733 clippingLayer->addChild(child.Pass());
4734 root->addChild(clippingLayer.Pass());
4735 }
4736
4737 std::vector<LayerImpl*> renderSurfaceLayerList;
4738 int dummyMaxTextureSize = 512;
4739 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4740
4741 // Sanity check the scenario we just created.
4742 ASSERT_EQ(1u, renderSurfaceLayerList.size());
4743 ASSERT_EQ(1u, root->renderSurface()->layerList().size());
4744 ASSERT_EQ(456, root->renderSurface()->layerList()[0]->id());
4745
4746 // Hit testing for a point outside the layer should return a null pointer.
4747 // Despite the child layer being very large, it should be clipped to the roo t layer's bounds.
4748 gfx::Point testPoint(24, 24);
4749 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4750 EXPECT_FALSE(resultLayer);
4751
4752 // Even though the layer exists at (101, 101), it should not be visible ther e since the clippingLayer would clamp it.
4753 testPoint = gfx::Point(76, 76);
4754 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4755 EXPECT_FALSE(resultLayer);
4756
4757 // Hit testing for a point inside should return the child layer.
4758 testPoint = gfx::Point(26, 26);
4759 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4760 ASSERT_TRUE(resultLayer);
4761 EXPECT_EQ(456, resultLayer->id());
4762
4763 testPoint = gfx::Point(74, 74);
4764 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4765 ASSERT_TRUE(resultLayer);
4766 EXPECT_EQ(456, resultLayer->id());
4767 }
4768
4769 TEST(LayerTreeHostImplTest, verifyHitTestingForMultiClippedRotatedLayer)
4770 {
4771 // This test checks whether hit testing correctly avoids hit testing with mu ltiple
4772 // ancestors that clip in non axis-aligned ways. To pass this test, the hit testing
4773 // algorithm needs to recognize that multiple parent layers may clip the lay er, and
4774 // should not actually hit those clipped areas.
4775 //
4776 // The child and grandChild layers are both initialized to clip the rotatedL eaf. The
4777 // child layer is rotated about the top-left corner, so that the root + chil d clips
4778 // combined create a triangle. The rotatedLeaf will only be visible where it overlaps
4779 // this triangle.
4780 //
4781 FakeImplProxy proxy;
4782 FakeLayerTreeHostImpl hostImpl(&proxy);
4783 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 123);
4784
4785 gfx::Transform identityMatrix;
4786 gfx::PointF anchor(0, 0);
4787 gfx::PointF position(0, 0);
4788 gfx::Size bounds(100, 100);
4789 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc hor, position, bounds, false);
4790 root->setMasksToBounds(true);
4791
4792 {
4793 scoped_ptr<LayerImpl> child = LayerImpl::create(hostImpl.activeTree(), 4 56);
4794 scoped_ptr<LayerImpl> grandChild = LayerImpl::create(hostImpl.activeTree (), 789);
4795 scoped_ptr<LayerImpl> rotatedLeaf = LayerImpl::create(hostImpl.activeTre e(), 2468);
4796
4797 position = gfx::PointF(10, 10);
4798 bounds = gfx::Size(80, 80);
4799 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix , anchor, position, bounds, false);
4800 child->setMasksToBounds(true);
4801
4802 gfx::Transform rotation45DegreesAboutCorner;
4803 rotation45DegreesAboutCorner.RotateAboutZAxis(45);
4804
4805 position = gfx::PointF(0, 0); // remember, positioned with respect to it s parent which is already at 10, 10
4806 bounds = gfx::Size(200, 200); // to ensure it covers at least sqrt(2) * 100.
4807 setLayerPropertiesForTesting(grandChild.get(), rotation45DegreesAboutCor ner, identityMatrix, anchor, position, bounds, false);
4808 grandChild->setMasksToBounds(true);
4809
4810 // Rotates about the center of the layer
4811 gfx::Transform rotatedLeafTransform;
4812 rotatedLeafTransform.Translate(-10, -10); // cancel out the grandParent' s position
4813 rotatedLeafTransform.RotateAboutZAxis(-45); // cancel out the corner 45- degree rotation of the parent.
4814 rotatedLeafTransform.Translate(50, 50);
4815 rotatedLeafTransform.RotateAboutZAxis(45);
4816 rotatedLeafTransform.Translate(-50, -50);
4817 position = gfx::PointF(0, 0);
4818 bounds = gfx::Size(100, 100);
4819 setLayerPropertiesForTesting(rotatedLeaf.get(), rotatedLeafTransform, id entityMatrix, anchor, position, bounds, false);
4820 rotatedLeaf->setDrawsContent(true);
4821
4822 grandChild->addChild(rotatedLeaf.Pass());
4823 child->addChild(grandChild.Pass());
4824 root->addChild(child.Pass());
4825 }
4826
4827 std::vector<LayerImpl*> renderSurfaceLayerList;
4828 int dummyMaxTextureSize = 512;
4829 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4830
4831 // Sanity check the scenario we just created.
4832 // The grandChild is expected to create a renderSurface because it masksToBo unds and is not axis aligned.
4833 ASSERT_EQ(2u, renderSurfaceLayerList.size());
4834 ASSERT_EQ(1u, renderSurfaceLayerList[0]->renderSurface()->layerList().size() );
4835 ASSERT_EQ(789, renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->i d()); // grandChild's surface.
4836 ASSERT_EQ(1u, renderSurfaceLayerList[1]->renderSurface()->layerList().size() );
4837 ASSERT_EQ(2468, renderSurfaceLayerList[1]->renderSurface()->layerList()[0]-> id());
4838
4839 // (11, 89) is close to the the bottom left corner within the clip, but it i s not inside the layer.
4840 gfx::Point testPoint(11, 89);
4841 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4842 EXPECT_FALSE(resultLayer);
4843
4844 // Closer inwards from the bottom left will overlap the layer.
4845 testPoint = gfx::Point(25, 75);
4846 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4847 ASSERT_TRUE(resultLayer);
4848 EXPECT_EQ(2468, resultLayer->id());
4849
4850 // (4, 50) is inside the unclipped layer, but that corner of the layer shoul d be
4851 // clipped away by the grandParent and should not get hit. If hit testing bl indly uses
4852 // visibleContentRect without considering how parent may clip the layer, the n hit
4853 // testing would accidentally think that the point successfully hits the lay er.
4854 testPoint = gfx::Point(4, 50);
4855 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4856 EXPECT_FALSE(resultLayer);
4857
4858 // (11, 50) is inside the layer and within the clipped area.
4859 testPoint = gfx::Point(11, 50);
4860 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4861 ASSERT_TRUE(resultLayer);
4862 EXPECT_EQ(2468, resultLayer->id());
4863
4864 // Around the middle, just to the right and up, would have hit the layer exc ept that
4865 // that area should be clipped away by the parent.
4866 testPoint = gfx::Point(51, 51);
4867 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4868 EXPECT_FALSE(resultLayer);
4869
4870 // Around the middle, just to the left and down, should successfully hit the layer.
4871 testPoint = gfx::Point(49, 51);
4872 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4873 ASSERT_TRUE(resultLayer);
4874 EXPECT_EQ(2468, resultLayer->id());
4875 }
4876
4877 TEST(LayerTreeHostImplTest, verifyHitTestingForNonClippingIntermediateLayer)
4878 {
4879 // This test checks that hit testing code does not accidentally clip to laye r
4880 // bounds for a layer that actually does not clip.
4881 gfx::Transform identityMatrix;
4882 gfx::PointF anchor(0, 0);
4883
4884 FakeImplProxy proxy;
4885 FakeLayerTreeHostImpl hostImpl(&proxy);
4886 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 1);
4887 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc hor, gfx::PointF(0, 0), gfx::Size(100, 100), false);
4888
4889 {
4890 scoped_ptr<LayerImpl> intermediateLayer = LayerImpl::create(hostImpl.act iveTree(), 123);
4891 gfx::PointF position(10, 10); // this layer is positioned, and hit testi ng should correctly know where the layer is located.
4892 gfx::Size bounds(50, 50);
4893 setLayerPropertiesForTesting(intermediateLayer.get(), identityMatrix, id entityMatrix, anchor, position, bounds, false);
4894 // Sanity check the intermediate layer should not clip.
4895 ASSERT_FALSE(intermediateLayer->masksToBounds());
4896 ASSERT_FALSE(intermediateLayer->maskLayer());
4897
4898 // The child of the intermediateLayer is translated so that it does not overlap intermediateLayer at all.
4899 // If child is incorrectly clipped, we would not be able to hit it succe ssfully.
4900 scoped_ptr<LayerImpl> child = LayerImpl::create(hostImpl.activeTree(), 4 56);
4901 position = gfx::PointF(60, 60); // 70, 70 in screen space
4902 bounds = gfx::Size(20, 20);
4903 setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix , anchor, position, bounds, false);
4904 child->setDrawsContent(true);
4905 intermediateLayer->addChild(child.Pass());
4906 root->addChild(intermediateLayer.Pass());
4907 }
4908
4909 std::vector<LayerImpl*> renderSurfaceLayerList;
4910 int dummyMaxTextureSize = 512;
4911 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4912
4913 // Sanity check the scenario we just created.
4914 ASSERT_EQ(1u, renderSurfaceLayerList.size());
4915 ASSERT_EQ(1u, root->renderSurface()->layerList().size());
4916 ASSERT_EQ(456, root->renderSurface()->layerList()[0]->id());
4917
4918 // Hit testing for a point outside the layer should return a null pointer.
4919 gfx::Point testPoint(69, 69);
4920 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
4921 EXPECT_FALSE(resultLayer);
4922
4923 testPoint = gfx::Point(91, 91);
4924 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4925 EXPECT_FALSE(resultLayer);
4926
4927 // Hit testing for a point inside should return the child layer.
4928 testPoint = gfx::Point(71, 71);
4929 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4930 ASSERT_TRUE(resultLayer);
4931 EXPECT_EQ(456, resultLayer->id());
4932
4933 testPoint = gfx::Point(89, 89);
4934 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
4935 ASSERT_TRUE(resultLayer);
4936 EXPECT_EQ(456, resultLayer->id());
4937 }
4938
4939
4940 TEST(LayerTreeHostImplTest, verifyHitTestingForMultipleLayers)
4941 {
4942 FakeImplProxy proxy;
4943 FakeLayerTreeHostImpl hostImpl(&proxy);
4944 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 1);
4945
4946 gfx::Transform identityMatrix;
4947 gfx::PointF anchor(0, 0);
4948 gfx::PointF position(0, 0);
4949 gfx::Size bounds(100, 100);
4950 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc hor, position, bounds, false);
4951 root->setDrawsContent(true);
4952
4953 {
4954 // child 1 and child2 are initialized to overlap between x=50 and x=60.
4955 // grandChild is set to overlap both child1 and child2 between y=50 and y=60.
4956 // The expected stacking order is:
4957 // (front) child2, (second) grandChild, (third) child1, and (back) the root layer behind all other layers.
4958
4959 scoped_ptr<LayerImpl> child1 = LayerImpl::create(hostImpl.activeTree(), 2);
4960 scoped_ptr<LayerImpl> child2 = LayerImpl::create(hostImpl.activeTree(), 3);
4961 scoped_ptr<LayerImpl> grandChild1 = LayerImpl::create(hostImpl.activeTre e(), 4);
4962
4963 position = gfx::PointF(10, 10);
4964 bounds = gfx::Size(50, 50);
4965 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatri x, anchor, position, bounds, false);
4966 child1->setDrawsContent(true);
4967
4968 position = gfx::PointF(50, 10);
4969 bounds = gfx::Size(50, 50);
4970 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatri x, anchor, position, bounds, false);
4971 child2->setDrawsContent(true);
4972
4973 // Remember that grandChild is positioned with respect to its parent (i. e. child1).
4974 // In screen space, the intended position is (10, 50), with size 100 x 5 0.
4975 position = gfx::PointF(0, 40);
4976 bounds = gfx::Size(100, 50);
4977 setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identity Matrix, anchor, position, bounds, false);
4978 grandChild1->setDrawsContent(true);
4979
4980 child1->addChild(grandChild1.Pass());
4981 root->addChild(child1.Pass());
4982 root->addChild(child2.Pass());
4983 }
4984
4985 LayerImpl* child1 = root->children()[0];
4986 LayerImpl* child2 = root->children()[1];
4987 LayerImpl* grandChild1 = child1->children()[0];
4988
4989 std::vector<LayerImpl*> renderSurfaceLayerList;
4990 int dummyMaxTextureSize = 512;
4991 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
4992
4993 // Sanity check the scenario we just created.
4994 ASSERT_TRUE(child1);
4995 ASSERT_TRUE(child2);
4996 ASSERT_TRUE(grandChild1);
4997 ASSERT_EQ(1u, renderSurfaceLayerList.size());
4998 ASSERT_EQ(4u, root->renderSurface()->layerList().size());
4999 ASSERT_EQ(1, root->renderSurface()->layerList()[0]->id()); // root layer
5000 ASSERT_EQ(2, root->renderSurface()->layerList()[1]->id()); // child1
5001 ASSERT_EQ(4, root->renderSurface()->layerList()[2]->id()); // grandChild1
5002 ASSERT_EQ(3, root->renderSurface()->layerList()[3]->id()); // child2
5003
5004 // Nothing overlaps the rootLayer at (1, 1), so hit testing there should fin d the root layer.
5005 gfx::Point testPoint = gfx::Point(1, 1);
5006 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
5007 ASSERT_TRUE(resultLayer);
5008 EXPECT_EQ(1, resultLayer->id());
5009
5010 // At (15, 15), child1 and root are the only layers. child1 is expected to b e on top.
5011 testPoint = gfx::Point(15, 15);
5012 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5013 ASSERT_TRUE(resultLayer);
5014 EXPECT_EQ(2, resultLayer->id());
5015
5016 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
5017 testPoint = gfx::Point(51, 20);
5018 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5019 ASSERT_TRUE(resultLayer);
5020 EXPECT_EQ(3, resultLayer->id());
5021
5022 // At (80, 51), child2 and grandChild1 overlap. child2 is expected to be on top.
5023 testPoint = gfx::Point(80, 51);
5024 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5025 ASSERT_TRUE(resultLayer);
5026 EXPECT_EQ(3, resultLayer->id());
5027
5028 // At (51, 51), all layers overlap each other. child2 is expected to be on t op of all other layers.
5029 testPoint = gfx::Point(51, 51);
5030 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5031 ASSERT_TRUE(resultLayer);
5032 EXPECT_EQ(3, resultLayer->id());
5033
5034 // At (20, 51), child1 and grandChild1 overlap. grandChild1 is expected to b e on top.
5035 testPoint = gfx::Point(20, 51);
5036 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5037 ASSERT_TRUE(resultLayer);
5038 EXPECT_EQ(4, resultLayer->id());
5039 }
5040
5041 TEST(LayerTreeHostImplTest, verifyHitTestingForMultipleLayerLists)
5042 {
5043 //
5044 // The geometry is set up similarly to the previous case, but
5045 // all layers are forced to be renderSurfaces now.
5046 //
5047 FakeImplProxy proxy;
5048 FakeLayerTreeHostImpl hostImpl(&proxy);
5049 scoped_ptr<LayerImpl> root = LayerImpl::create(hostImpl.activeTree(), 1);
5050
5051 gfx::Transform identityMatrix;
5052 gfx::PointF anchor(0, 0);
5053 gfx::PointF position(0, 0);
5054 gfx::Size bounds(100, 100);
5055 setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, anc hor, position, bounds, false);
5056 root->setDrawsContent(true);
5057
5058 {
5059 // child 1 and child2 are initialized to overlap between x=50 and x=60.
5060 // grandChild is set to overlap both child1 and child2 between y=50 and y=60.
5061 // The expected stacking order is:
5062 // (front) child2, (second) grandChild, (third) child1, and (back) the root layer behind all other layers.
5063
5064 scoped_ptr<LayerImpl> child1 = LayerImpl::create(hostImpl.activeTree(), 2);
5065 scoped_ptr<LayerImpl> child2 = LayerImpl::create(hostImpl.activeTree(), 3);
5066 scoped_ptr<LayerImpl> grandChild1 = LayerImpl::create(hostImpl.activeTre e(), 4);
5067
5068 position = gfx::PointF(10, 10);
5069 bounds = gfx::Size(50, 50);
5070 setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatri x, anchor, position, bounds, false);
5071 child1->setDrawsContent(true);
5072 child1->setForceRenderSurface(true);
5073
5074 position = gfx::PointF(50, 10);
5075 bounds = gfx::Size(50, 50);
5076 setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatri x, anchor, position, bounds, false);
5077 child2->setDrawsContent(true);
5078 child2->setForceRenderSurface(true);
5079
5080 // Remember that grandChild is positioned with respect to its parent (i. e. child1).
5081 // In screen space, the intended position is (10, 50), with size 100 x 5 0.
5082 position = gfx::PointF(0, 40);
5083 bounds = gfx::Size(100, 50);
5084 setLayerPropertiesForTesting(grandChild1.get(), identityMatrix, identity Matrix, anchor, position, bounds, false);
5085 grandChild1->setDrawsContent(true);
5086 grandChild1->setForceRenderSurface(true);
5087
5088 child1->addChild(grandChild1.Pass());
5089 root->addChild(child1.Pass());
5090 root->addChild(child2.Pass());
5091 }
5092
5093 LayerImpl* child1 = root->children()[0];
5094 LayerImpl* child2 = root->children()[1];
5095 LayerImpl* grandChild1 = child1->children()[0];
5096
5097 std::vector<LayerImpl*> renderSurfaceLayerList;
5098 int dummyMaxTextureSize = 512;
5099 LayerTreeHostCommon::calculateDrawProperties(root.get(), root->bounds(), 1, 1, dummyMaxTextureSize, false, renderSurfaceLayerList, false);
5100
5101 // Sanity check the scenario we just created.
5102 ASSERT_TRUE(child1);
5103 ASSERT_TRUE(child2);
5104 ASSERT_TRUE(grandChild1);
5105 ASSERT_TRUE(child1->renderSurface());
5106 ASSERT_TRUE(child2->renderSurface());
5107 ASSERT_TRUE(grandChild1->renderSurface());
5108 ASSERT_EQ(4u, renderSurfaceLayerList.size());
5109 ASSERT_EQ(3u, root->renderSurface()->layerList().size()); // The root surfac e has the root layer, and child1's and child2's renderSurfaces.
5110 ASSERT_EQ(2u, child1->renderSurface()->layerList().size()); // The child1 su rface has the child1 layer and grandChild1's renderSurface.
5111 ASSERT_EQ(1u, child2->renderSurface()->layerList().size());
5112 ASSERT_EQ(1u, grandChild1->renderSurface()->layerList().size());
5113 ASSERT_EQ(1, renderSurfaceLayerList[0]->id()); // root layer
5114 ASSERT_EQ(2, renderSurfaceLayerList[1]->id()); // child1
5115 ASSERT_EQ(4, renderSurfaceLayerList[2]->id()); // grandChild1
5116 ASSERT_EQ(3, renderSurfaceLayerList[3]->id()); // child2
5117
5118 // Nothing overlaps the rootLayer at (1, 1), so hit testing there should fin d the root layer.
5119 gfx::Point testPoint = gfx::Point(1, 1);
5120 LayerImpl* resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, rende rSurfaceLayerList);
5121 ASSERT_TRUE(resultLayer);
5122 EXPECT_EQ(1, resultLayer->id());
5123
5124 // At (15, 15), child1 and root are the only layers. child1 is expected to b e on top.
5125 testPoint = gfx::Point(15, 15);
5126 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5127 ASSERT_TRUE(resultLayer);
5128 EXPECT_EQ(2, resultLayer->id());
5129
5130 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
5131 testPoint = gfx::Point(51, 20);
5132 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5133 ASSERT_TRUE(resultLayer);
5134 EXPECT_EQ(3, resultLayer->id());
5135
5136 // At (80, 51), child2 and grandChild1 overlap. child2 is expected to be on top.
5137 testPoint = gfx::Point(80, 51);
5138 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5139 ASSERT_TRUE(resultLayer);
5140 EXPECT_EQ(3, resultLayer->id());
5141
5142 // At (51, 51), all layers overlap each other. child2 is expected to be on t op of all other layers.
5143 testPoint = gfx::Point(51, 51);
5144 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5145 ASSERT_TRUE(resultLayer);
5146 EXPECT_EQ(3, resultLayer->id());
5147
5148 // At (20, 51), child1 and grandChild1 overlap. grandChild1 is expected to b e on top.
5149 testPoint = gfx::Point(20, 51);
5150 resultLayer = hostImpl.findLayerThatIsHitByPoint(testPoint, renderSurfaceLay erList);
5151 ASSERT_TRUE(resultLayer);
5152 EXPECT_EQ(4, resultLayer->id());
5153 }
5154
4346 INSTANTIATE_TEST_CASE_P(LayerTreeHostImplTests, 5155 INSTANTIATE_TEST_CASE_P(LayerTreeHostImplTests,
4347 LayerTreeHostImplTest, 5156 LayerTreeHostImplTest,
4348 ::testing::Values(false, true)); 5157 ::testing::Values(false, true));
4349 5158
4350 } // namespace 5159 } // namespace
4351 } // namespace cc 5160 } // namespace cc
OLDNEW
« cc/layer_tree_host_impl.cc ('K') | « cc/layer_tree_host_impl.cc ('k') | cc/math_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698