Home | History | Annotate | Download | only in trees
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "cc/trees/layer_tree_impl.h"
      6 
      7 #include "cc/layers/heads_up_display_layer_impl.h"
      8 #include "cc/layers/layer.h"
      9 #include "cc/test/fake_impl_proxy.h"
     10 #include "cc/test/fake_layer_tree_host_impl.h"
     11 #include "cc/test/fake_output_surface.h"
     12 #include "cc/test/geometry_test_utils.h"
     13 #include "cc/test/layer_tree_host_common_test.h"
     14 #include "cc/test/test_shared_bitmap_manager.h"
     15 #include "cc/trees/layer_tree_host_impl.h"
     16 #include "ui/gfx/size_conversions.h"
     17 
     18 namespace cc {
     19 namespace {
     20 
     21 class LayerTreeImplTest : public LayerTreeHostCommonTest {
     22  public:
     23   LayerTreeImplTest() {
     24     LayerTreeSettings settings;
     25     settings.layer_transforms_should_scale_layer_contents = true;
     26     host_impl_.reset(
     27         new FakeLayerTreeHostImpl(settings, &proxy_, &shared_bitmap_manager_));
     28     EXPECT_TRUE(host_impl_->InitializeRenderer(
     29         FakeOutputSurface::Create3d().PassAs<OutputSurface>()));
     30   }
     31 
     32   FakeLayerTreeHostImpl& host_impl() { return *host_impl_; }
     33 
     34   LayerImpl* root_layer() { return host_impl_->active_tree()->root_layer(); }
     35 
     36   const LayerImplList& RenderSurfaceLayerList() const {
     37     return host_impl_->active_tree()->RenderSurfaceLayerList();
     38   }
     39 
     40  private:
     41   TestSharedBitmapManager shared_bitmap_manager_;
     42   FakeImplProxy proxy_;
     43   scoped_ptr<FakeLayerTreeHostImpl> host_impl_;
     44 };
     45 
     46 TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) {
     47   scoped_ptr<LayerImpl> root =
     48       LayerImpl::Create(host_impl().active_tree(), 12345);
     49 
     50   gfx::Transform identity_matrix;
     51   gfx::Point3F transform_origin;
     52   gfx::PointF position;
     53   gfx::Size bounds(100, 100);
     54   SetLayerPropertiesForTesting(root.get(),
     55                                identity_matrix,
     56                                transform_origin,
     57                                position,
     58                                bounds,
     59                                true,
     60                                false);
     61   root->SetDrawsContent(true);
     62 
     63   host_impl().SetViewportSize(root->bounds());
     64   host_impl().active_tree()->SetRootLayer(root.Pass());
     65   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
     66 
     67   // Sanity check the scenario we just created.
     68   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
     69   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
     70 
     71   // Hit testing for a point outside the layer should return a null pointer.
     72   gfx::Point test_point(101, 101);
     73   LayerImpl* result_layer =
     74       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
     75   EXPECT_FALSE(result_layer);
     76 
     77   test_point = gfx::Point(-1, -1);
     78   result_layer =
     79       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
     80   EXPECT_FALSE(result_layer);
     81 
     82   // Hit testing for a point inside should return the root layer.
     83   test_point = gfx::Point(1, 1);
     84   result_layer =
     85       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
     86   ASSERT_TRUE(result_layer);
     87   EXPECT_EQ(12345, result_layer->id());
     88 
     89   test_point = gfx::Point(99, 99);
     90   result_layer =
     91       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
     92   ASSERT_TRUE(result_layer);
     93   EXPECT_EQ(12345, result_layer->id());
     94 }
     95 
     96 TEST_F(LayerTreeImplTest, HitTestingForSingleLayerAndHud) {
     97   scoped_ptr<LayerImpl> root =
     98       LayerImpl::Create(host_impl().active_tree(), 12345);
     99   scoped_ptr<HeadsUpDisplayLayerImpl> hud =
    100       HeadsUpDisplayLayerImpl::Create(host_impl().active_tree(), 11111);
    101 
    102   gfx::Transform identity_matrix;
    103   gfx::Point3F transform_origin;
    104   gfx::PointF position;
    105   gfx::Size bounds(100, 100);
    106   SetLayerPropertiesForTesting(root.get(),
    107                                identity_matrix,
    108                                transform_origin,
    109                                position,
    110                                bounds,
    111                                true,
    112                                false);
    113   root->SetDrawsContent(true);
    114 
    115   // Create hud and add it as a child of root.
    116   gfx::Size hud_bounds(200, 200);
    117   SetLayerPropertiesForTesting(hud.get(),
    118                                identity_matrix,
    119                                transform_origin,
    120                                position,
    121                                hud_bounds,
    122                                true,
    123                                false);
    124   hud->SetDrawsContent(true);
    125 
    126   host_impl().active_tree()->set_hud_layer(hud.get());
    127   root->AddChild(hud.PassAs<LayerImpl>());
    128 
    129   host_impl().SetViewportSize(hud_bounds);
    130   host_impl().active_tree()->SetRootLayer(root.Pass());
    131   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    132 
    133   // Sanity check the scenario we just created.
    134   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
    135   ASSERT_EQ(2u, root_layer()->render_surface()->layer_list().size());
    136 
    137   // Hit testing for a point inside HUD, but outside root should return null
    138   gfx::Point test_point(101, 101);
    139   LayerImpl* result_layer =
    140       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    141   EXPECT_FALSE(result_layer);
    142 
    143   test_point = gfx::Point(-1, -1);
    144   result_layer =
    145       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    146   EXPECT_FALSE(result_layer);
    147 
    148   // Hit testing for a point inside should return the root layer, never the HUD
    149   // layer.
    150   test_point = gfx::Point(1, 1);
    151   result_layer =
    152       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    153   ASSERT_TRUE(result_layer);
    154   EXPECT_EQ(12345, result_layer->id());
    155 
    156   test_point = gfx::Point(99, 99);
    157   result_layer =
    158       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    159   ASSERT_TRUE(result_layer);
    160   EXPECT_EQ(12345, result_layer->id());
    161 }
    162 
    163 TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) {
    164   scoped_ptr<LayerImpl> root =
    165       LayerImpl::Create(host_impl().active_tree(), 12345);
    166 
    167   gfx::Transform uninvertible_transform;
    168   uninvertible_transform.matrix().set(0, 0, 0.0);
    169   uninvertible_transform.matrix().set(1, 1, 0.0);
    170   uninvertible_transform.matrix().set(2, 2, 0.0);
    171   uninvertible_transform.matrix().set(3, 3, 0.0);
    172   ASSERT_FALSE(uninvertible_transform.IsInvertible());
    173 
    174   gfx::Transform identity_matrix;
    175   gfx::Point3F transform_origin;
    176   gfx::PointF position;
    177   gfx::Size bounds(100, 100);
    178   SetLayerPropertiesForTesting(root.get(),
    179                                uninvertible_transform,
    180                                transform_origin,
    181                                position,
    182                                bounds,
    183                                true,
    184                                false);
    185   root->SetDrawsContent(true);
    186 
    187   host_impl().SetViewportSize(root->bounds());
    188   host_impl().active_tree()->SetRootLayer(root.Pass());
    189   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    190   // Sanity check the scenario we just created.
    191   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
    192   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
    193   ASSERT_FALSE(root_layer()->screen_space_transform().IsInvertible());
    194 
    195   // Hit testing any point should not hit the layer. If the invertible matrix is
    196   // accidentally ignored and treated like an identity, then the hit testing
    197   // will incorrectly hit the layer when it shouldn't.
    198   gfx::Point test_point(1, 1);
    199   LayerImpl* result_layer =
    200       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    201   EXPECT_FALSE(result_layer);
    202 
    203   test_point = gfx::Point(10, 10);
    204   result_layer =
    205       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    206   EXPECT_FALSE(result_layer);
    207 
    208   test_point = gfx::Point(10, 30);
    209   result_layer =
    210       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    211   EXPECT_FALSE(result_layer);
    212 
    213   test_point = gfx::Point(50, 50);
    214   result_layer =
    215       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    216   EXPECT_FALSE(result_layer);
    217 
    218   test_point = gfx::Point(67, 48);
    219   result_layer =
    220       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    221   EXPECT_FALSE(result_layer);
    222 
    223   test_point = gfx::Point(99, 99);
    224   result_layer =
    225       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    226   EXPECT_FALSE(result_layer);
    227 
    228   test_point = gfx::Point(-1, -1);
    229   result_layer =
    230       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    231   EXPECT_FALSE(result_layer);
    232 }
    233 
    234 TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) {
    235   scoped_ptr<LayerImpl> root =
    236       LayerImpl::Create(host_impl().active_tree(), 12345);
    237 
    238   gfx::Transform identity_matrix;
    239   gfx::Point3F transform_origin;
    240   // this layer is positioned, and hit testing should correctly know where the
    241   // layer is located.
    242   gfx::PointF position(50.f, 50.f);
    243   gfx::Size bounds(100, 100);
    244   SetLayerPropertiesForTesting(root.get(),
    245                                identity_matrix,
    246                                transform_origin,
    247                                position,
    248                                bounds,
    249                                true,
    250                                false);
    251   root->SetDrawsContent(true);
    252 
    253   host_impl().SetViewportSize(root->bounds());
    254   host_impl().active_tree()->SetRootLayer(root.Pass());
    255   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    256 
    257   // Sanity check the scenario we just created.
    258   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
    259   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
    260 
    261   // Hit testing for a point outside the layer should return a null pointer.
    262   gfx::Point test_point(49, 49);
    263   LayerImpl* result_layer =
    264       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    265   EXPECT_FALSE(result_layer);
    266 
    267   // Even though the layer exists at (101, 101), it should not be visible there
    268   // since the root render surface would clamp it.
    269   test_point = gfx::Point(101, 101);
    270   result_layer =
    271       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    272   EXPECT_FALSE(result_layer);
    273 
    274   // Hit testing for a point inside should return the root layer.
    275   test_point = gfx::Point(51, 51);
    276   result_layer =
    277       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    278   ASSERT_TRUE(result_layer);
    279   EXPECT_EQ(12345, result_layer->id());
    280 
    281   test_point = gfx::Point(99, 99);
    282   result_layer =
    283       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    284   ASSERT_TRUE(result_layer);
    285   EXPECT_EQ(12345, result_layer->id());
    286 }
    287 
    288 TEST_F(LayerTreeImplTest, HitTestingForSingleRotatedLayer) {
    289   scoped_ptr<LayerImpl> root =
    290       LayerImpl::Create(host_impl().active_tree(), 12345);
    291 
    292   gfx::Transform identity_matrix;
    293   gfx::Transform rotation45_degrees_about_center;
    294   rotation45_degrees_about_center.Translate(50.0, 50.0);
    295   rotation45_degrees_about_center.RotateAboutZAxis(45.0);
    296   rotation45_degrees_about_center.Translate(-50.0, -50.0);
    297   gfx::Point3F transform_origin;
    298   gfx::PointF position;
    299   gfx::Size bounds(100, 100);
    300   SetLayerPropertiesForTesting(root.get(),
    301                                rotation45_degrees_about_center,
    302                                transform_origin,
    303                                position,
    304                                bounds,
    305                                true,
    306                                false);
    307   root->SetDrawsContent(true);
    308 
    309   host_impl().SetViewportSize(root->bounds());
    310   host_impl().active_tree()->SetRootLayer(root.Pass());
    311   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    312 
    313   // Sanity check the scenario we just created.
    314   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
    315   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
    316 
    317   // Hit testing for points outside the layer.
    318   // These corners would have been inside the un-transformed layer, but they
    319   // should not hit the correctly transformed layer.
    320   gfx::Point test_point(99, 99);
    321   LayerImpl* result_layer =
    322       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    323   EXPECT_FALSE(result_layer);
    324 
    325   test_point = gfx::Point(1, 1);
    326   result_layer =
    327       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    328   EXPECT_FALSE(result_layer);
    329 
    330   // Hit testing for a point inside should return the root layer.
    331   test_point = gfx::Point(1, 50);
    332   result_layer =
    333       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    334   ASSERT_TRUE(result_layer);
    335   EXPECT_EQ(12345, result_layer->id());
    336 
    337   // Hit testing the corners that would overlap the unclipped layer, but are
    338   // outside the clipped region.
    339   test_point = gfx::Point(50, -1);
    340   result_layer =
    341       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    342   ASSERT_FALSE(result_layer);
    343 
    344   test_point = gfx::Point(-1, 50);
    345   result_layer =
    346       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    347   ASSERT_FALSE(result_layer);
    348 }
    349 
    350 TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) {
    351   scoped_ptr<LayerImpl> root =
    352       LayerImpl::Create(host_impl().active_tree(), 12345);
    353 
    354   gfx::Transform identity_matrix;
    355 
    356   // perspective_projection_about_center * translation_by_z is designed so that
    357   // the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50).
    358   gfx::Transform perspective_projection_about_center;
    359   perspective_projection_about_center.Translate(50.0, 50.0);
    360   perspective_projection_about_center.ApplyPerspectiveDepth(1.0);
    361   perspective_projection_about_center.Translate(-50.0, -50.0);
    362   gfx::Transform translation_by_z;
    363   translation_by_z.Translate3d(0.0, 0.0, -1.0);
    364 
    365   gfx::Point3F transform_origin;
    366   gfx::PointF position;
    367   gfx::Size bounds(100, 100);
    368   SetLayerPropertiesForTesting(
    369       root.get(),
    370       perspective_projection_about_center * translation_by_z,
    371       transform_origin,
    372       position,
    373       bounds,
    374       true,
    375       false);
    376   root->SetDrawsContent(true);
    377 
    378   host_impl().SetViewportSize(root->bounds());
    379   host_impl().active_tree()->SetRootLayer(root.Pass());
    380   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    381 
    382   // Sanity check the scenario we just created.
    383   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
    384   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
    385 
    386   // Hit testing for points outside the layer.
    387   // These corners would have been inside the un-transformed layer, but they
    388   // should not hit the correctly transformed layer.
    389   gfx::Point test_point(24, 24);
    390   LayerImpl* result_layer =
    391       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    392   EXPECT_FALSE(result_layer);
    393 
    394   test_point = gfx::Point(76, 76);
    395   result_layer =
    396       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    397   EXPECT_FALSE(result_layer);
    398 
    399   // Hit testing for a point inside should return the root layer.
    400   test_point = gfx::Point(26, 26);
    401   result_layer =
    402       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    403   ASSERT_TRUE(result_layer);
    404   EXPECT_EQ(12345, result_layer->id());
    405 
    406   test_point = gfx::Point(74, 74);
    407   result_layer =
    408       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    409   ASSERT_TRUE(result_layer);
    410   EXPECT_EQ(12345, result_layer->id());
    411 }
    412 
    413 TEST_F(LayerTreeImplTest, HitTestingForSingleLayerWithScaledContents) {
    414   // A layer's visible content rect is actually in the layer's content space.
    415   // The screen space transform converts from the layer's origin space to screen
    416   // space. This test makes sure that hit testing works correctly accounts for
    417   // the contents scale.  A contents scale that is not 1 effectively forces a
    418   // non-identity transform between layer's content space and layer's origin
    419   // space. The hit testing code must take this into account.
    420   //
    421   // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
    422   // contents scale is ignored, then hit testing will mis-interpret the visible
    423   // content rect as being larger than the actual bounds of the layer.
    424   //
    425   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
    426 
    427   gfx::Transform identity_matrix;
    428   gfx::Point3F transform_origin;
    429 
    430   SetLayerPropertiesForTesting(root.get(),
    431                                identity_matrix,
    432                                transform_origin,
    433                                gfx::PointF(),
    434                                gfx::Size(100, 100),
    435                                true,
    436                                false);
    437   {
    438     gfx::PointF position(25.f, 25.f);
    439     gfx::Size bounds(50, 50);
    440     scoped_ptr<LayerImpl> test_layer =
    441         LayerImpl::Create(host_impl().active_tree(), 12345);
    442     SetLayerPropertiesForTesting(test_layer.get(),
    443                                  identity_matrix,
    444                                  transform_origin,
    445                                  position,
    446                                  bounds,
    447                                  true,
    448                                  false);
    449 
    450     // override content bounds and contents scale
    451     test_layer->SetContentBounds(gfx::Size(100, 100));
    452     test_layer->SetContentsScale(2, 2);
    453 
    454     test_layer->SetDrawsContent(true);
    455     root->AddChild(test_layer.Pass());
    456   }
    457 
    458   host_impl().SetViewportSize(root->bounds());
    459   host_impl().active_tree()->SetRootLayer(root.Pass());
    460   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    461 
    462   // Sanity check the scenario we just created.
    463   // The visible content rect for test_layer is actually 100x100, even though
    464   // its layout size is 50x50, positioned at 25x25.
    465   LayerImpl* test_layer =
    466       host_impl().active_tree()->root_layer()->children()[0];
    467   EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), test_layer->visible_content_rect());
    468   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
    469   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
    470 
    471   // Hit testing for a point outside the layer should return a null pointer (the
    472   // root layer does not draw content, so it will not be hit tested either).
    473   gfx::Point test_point(101, 101);
    474   LayerImpl* result_layer =
    475       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    476   EXPECT_FALSE(result_layer);
    477 
    478   test_point = gfx::Point(24, 24);
    479   result_layer =
    480       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    481   EXPECT_FALSE(result_layer);
    482 
    483   test_point = gfx::Point(76, 76);
    484   result_layer =
    485       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    486   EXPECT_FALSE(result_layer);
    487 
    488   // Hit testing for a point inside should return the test layer.
    489   test_point = gfx::Point(26, 26);
    490   result_layer =
    491       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    492   ASSERT_TRUE(result_layer);
    493   EXPECT_EQ(12345, result_layer->id());
    494 
    495   test_point = gfx::Point(74, 74);
    496   result_layer =
    497       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    498   ASSERT_TRUE(result_layer);
    499   EXPECT_EQ(12345, result_layer->id());
    500 }
    501 
    502 TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) {
    503   // Test that hit-testing will only work for the visible portion of a layer,
    504   // and not the entire layer bounds. Here we just test the simple axis-aligned
    505   // case.
    506   gfx::Transform identity_matrix;
    507   gfx::Point3F transform_origin;
    508 
    509   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
    510   SetLayerPropertiesForTesting(root.get(),
    511                                identity_matrix,
    512                                transform_origin,
    513                                gfx::PointF(),
    514                                gfx::Size(100, 100),
    515                                true,
    516                                false);
    517   {
    518     scoped_ptr<LayerImpl> clipping_layer =
    519         LayerImpl::Create(host_impl().active_tree(), 123);
    520     // this layer is positioned, and hit testing should correctly know where the
    521     // layer is located.
    522     gfx::PointF position(25.f, 25.f);
    523     gfx::Size bounds(50, 50);
    524     SetLayerPropertiesForTesting(clipping_layer.get(),
    525                                  identity_matrix,
    526                                  transform_origin,
    527                                  position,
    528                                  bounds,
    529                                  true,
    530                                  false);
    531     clipping_layer->SetMasksToBounds(true);
    532 
    533     scoped_ptr<LayerImpl> child =
    534         LayerImpl::Create(host_impl().active_tree(), 456);
    535     position = gfx::PointF(-50.f, -50.f);
    536     bounds = gfx::Size(300, 300);
    537     SetLayerPropertiesForTesting(child.get(),
    538                                  identity_matrix,
    539                                  transform_origin,
    540                                  position,
    541                                  bounds,
    542                                  true,
    543                                  false);
    544     child->SetDrawsContent(true);
    545     clipping_layer->AddChild(child.Pass());
    546     root->AddChild(clipping_layer.Pass());
    547   }
    548 
    549   host_impl().SetViewportSize(root->bounds());
    550   host_impl().active_tree()->SetRootLayer(root.Pass());
    551   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    552 
    553   // Sanity check the scenario we just created.
    554   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
    555   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
    556   ASSERT_EQ(456, root_layer()->render_surface()->layer_list().at(0)->id());
    557 
    558   // Hit testing for a point outside the layer should return a null pointer.
    559   // Despite the child layer being very large, it should be clipped to the root
    560   // layer's bounds.
    561   gfx::Point test_point(24, 24);
    562   LayerImpl* result_layer =
    563       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    564   EXPECT_FALSE(result_layer);
    565 
    566   // Even though the layer exists at (101, 101), it should not be visible there
    567   // since the clipping_layer would clamp it.
    568   test_point = gfx::Point(76, 76);
    569   result_layer =
    570       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    571   EXPECT_FALSE(result_layer);
    572 
    573   // Hit testing for a point inside should return the child layer.
    574   test_point = gfx::Point(26, 26);
    575   result_layer =
    576       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    577   ASSERT_TRUE(result_layer);
    578   EXPECT_EQ(456, result_layer->id());
    579 
    580   test_point = gfx::Point(74, 74);
    581   result_layer =
    582       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    583   ASSERT_TRUE(result_layer);
    584   EXPECT_EQ(456, result_layer->id());
    585 }
    586 
    587 TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) {
    588   // This test checks whether hit testing correctly avoids hit testing with
    589   // multiple ancestors that clip in non axis-aligned ways. To pass this test,
    590   // the hit testing algorithm needs to recognize that multiple parent layers
    591   // may clip the layer, and should not actually hit those clipped areas.
    592   //
    593   // The child and grand_child layers are both initialized to clip the
    594   // rotated_leaf. The child layer is rotated about the top-left corner, so that
    595   // the root + child clips combined create a triangle. The rotated_leaf will
    596   // only be visible where it overlaps this triangle.
    597   //
    598   scoped_ptr<LayerImpl> root =
    599       LayerImpl::Create(host_impl().active_tree(), 123);
    600 
    601   gfx::Transform identity_matrix;
    602   gfx::Point3F transform_origin;
    603   gfx::PointF position;
    604   gfx::Size bounds(100, 100);
    605   SetLayerPropertiesForTesting(root.get(),
    606                                identity_matrix,
    607                                transform_origin,
    608                                position,
    609                                bounds,
    610                                true,
    611                                false);
    612   root->SetMasksToBounds(true);
    613   {
    614     scoped_ptr<LayerImpl> child =
    615         LayerImpl::Create(host_impl().active_tree(), 456);
    616     scoped_ptr<LayerImpl> grand_child =
    617         LayerImpl::Create(host_impl().active_tree(), 789);
    618     scoped_ptr<LayerImpl> rotated_leaf =
    619         LayerImpl::Create(host_impl().active_tree(), 2468);
    620 
    621     position = gfx::PointF(10.f, 10.f);
    622     bounds = gfx::Size(80, 80);
    623     SetLayerPropertiesForTesting(child.get(),
    624                                  identity_matrix,
    625                                  transform_origin,
    626                                  position,
    627                                  bounds,
    628                                  true,
    629                                  false);
    630     child->SetMasksToBounds(true);
    631 
    632     gfx::Transform rotation45_degrees_about_corner;
    633     rotation45_degrees_about_corner.RotateAboutZAxis(45.0);
    634 
    635     // remember, positioned with respect to its parent which is already at 10,
    636     // 10
    637     position = gfx::PointF();
    638     bounds =
    639         gfx::Size(200, 200);  // to ensure it covers at least sqrt(2) * 100.
    640     SetLayerPropertiesForTesting(grand_child.get(),
    641                                  rotation45_degrees_about_corner,
    642                                  transform_origin,
    643                                  position,
    644                                  bounds,
    645                                  true,
    646                                  false);
    647     grand_child->SetMasksToBounds(true);
    648 
    649     // Rotates about the center of the layer
    650     gfx::Transform rotated_leaf_transform;
    651     rotated_leaf_transform.Translate(
    652         -10.0, -10.0);  // cancel out the grand_parent's position
    653     rotated_leaf_transform.RotateAboutZAxis(
    654         -45.0);  // cancel out the corner 45-degree rotation of the parent.
    655     rotated_leaf_transform.Translate(50.0, 50.0);
    656     rotated_leaf_transform.RotateAboutZAxis(45.0);
    657     rotated_leaf_transform.Translate(-50.0, -50.0);
    658     position = gfx::PointF();
    659     bounds = gfx::Size(100, 100);
    660     SetLayerPropertiesForTesting(rotated_leaf.get(),
    661                                  rotated_leaf_transform,
    662                                  transform_origin,
    663                                  position,
    664                                  bounds,
    665                                  true,
    666                                  false);
    667     rotated_leaf->SetDrawsContent(true);
    668 
    669     grand_child->AddChild(rotated_leaf.Pass());
    670     child->AddChild(grand_child.Pass());
    671     root->AddChild(child.Pass());
    672   }
    673 
    674   host_impl().SetViewportSize(root->bounds());
    675   host_impl().active_tree()->SetRootLayer(root.Pass());
    676   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    677 
    678   // Sanity check the scenario we just created.
    679   // The grand_child is expected to create a render surface because it
    680   // MasksToBounds and is not axis aligned.
    681   ASSERT_EQ(2u, RenderSurfaceLayerList().size());
    682   ASSERT_EQ(
    683       1u,
    684       RenderSurfaceLayerList().at(0)->render_surface()->layer_list().size());
    685   ASSERT_EQ(789,
    686             RenderSurfaceLayerList()
    687                 .at(0)
    688                 ->render_surface()
    689                 ->layer_list()
    690                 .at(0)
    691                 ->id());  // grand_child's surface.
    692   ASSERT_EQ(
    693       1u,
    694       RenderSurfaceLayerList().at(1)->render_surface()->layer_list().size());
    695   ASSERT_EQ(
    696       2468,
    697       RenderSurfaceLayerList()[1]->render_surface()->layer_list().at(0)->id());
    698 
    699   // (11, 89) is close to the the bottom left corner within the clip, but it is
    700   // not inside the layer.
    701   gfx::Point test_point(11, 89);
    702   LayerImpl* result_layer =
    703       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    704   EXPECT_FALSE(result_layer);
    705 
    706   // Closer inwards from the bottom left will overlap the layer.
    707   test_point = gfx::Point(25, 75);
    708   result_layer =
    709       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    710   ASSERT_TRUE(result_layer);
    711   EXPECT_EQ(2468, result_layer->id());
    712 
    713   // (4, 50) is inside the unclipped layer, but that corner of the layer should
    714   // be clipped away by the grandparent and should not get hit. If hit testing
    715   // blindly uses visible content rect without considering how parent may clip
    716   // the layer, then hit testing would accidentally think that the point
    717   // successfully hits the layer.
    718   test_point = gfx::Point(4, 50);
    719   result_layer =
    720       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    721   EXPECT_FALSE(result_layer);
    722 
    723   // (11, 50) is inside the layer and within the clipped area.
    724   test_point = gfx::Point(11, 50);
    725   result_layer =
    726       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    727   ASSERT_TRUE(result_layer);
    728   EXPECT_EQ(2468, result_layer->id());
    729 
    730   // Around the middle, just to the right and up, would have hit the layer
    731   // except that that area should be clipped away by the parent.
    732   test_point = gfx::Point(51, 49);
    733   result_layer =
    734       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    735   EXPECT_FALSE(result_layer);
    736 
    737   // Around the middle, just to the left and down, should successfully hit the
    738   // layer.
    739   test_point = gfx::Point(49, 51);
    740   result_layer =
    741       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    742   ASSERT_TRUE(result_layer);
    743   EXPECT_EQ(2468, result_layer->id());
    744 }
    745 
    746 TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) {
    747   // This test checks that hit testing code does not accidentally clip to layer
    748   // bounds for a layer that actually does not clip.
    749   gfx::Transform identity_matrix;
    750   gfx::Point3F transform_origin;
    751 
    752   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
    753   SetLayerPropertiesForTesting(root.get(),
    754                                identity_matrix,
    755                                transform_origin,
    756                                gfx::PointF(),
    757                                gfx::Size(100, 100),
    758                                true,
    759                                false);
    760   {
    761     scoped_ptr<LayerImpl> intermediate_layer =
    762         LayerImpl::Create(host_impl().active_tree(), 123);
    763     // this layer is positioned, and hit testing should correctly know where the
    764     // layer is located.
    765     gfx::PointF position(10.f, 10.f);
    766     gfx::Size bounds(50, 50);
    767     SetLayerPropertiesForTesting(intermediate_layer.get(),
    768                                  identity_matrix,
    769                                  transform_origin,
    770                                  position,
    771                                  bounds,
    772                                  true,
    773                                  false);
    774     // Sanity check the intermediate layer should not clip.
    775     ASSERT_FALSE(intermediate_layer->masks_to_bounds());
    776     ASSERT_FALSE(intermediate_layer->mask_layer());
    777 
    778     // The child of the intermediate_layer is translated so that it does not
    779     // overlap intermediate_layer at all.  If child is incorrectly clipped, we
    780     // would not be able to hit it successfully.
    781     scoped_ptr<LayerImpl> child =
    782         LayerImpl::Create(host_impl().active_tree(), 456);
    783     position = gfx::PointF(60.f, 60.f);  // 70, 70 in screen space
    784     bounds = gfx::Size(20, 20);
    785     SetLayerPropertiesForTesting(child.get(),
    786                                  identity_matrix,
    787                                  transform_origin,
    788                                  position,
    789                                  bounds,
    790                                  true,
    791                                  false);
    792     child->SetDrawsContent(true);
    793     intermediate_layer->AddChild(child.Pass());
    794     root->AddChild(intermediate_layer.Pass());
    795   }
    796 
    797   host_impl().SetViewportSize(root->bounds());
    798   host_impl().active_tree()->SetRootLayer(root.Pass());
    799   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    800 
    801   // Sanity check the scenario we just created.
    802   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
    803   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
    804   ASSERT_EQ(456, root_layer()->render_surface()->layer_list().at(0)->id());
    805 
    806   // Hit testing for a point outside the layer should return a null pointer.
    807   gfx::Point test_point(69, 69);
    808   LayerImpl* result_layer =
    809       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    810   EXPECT_FALSE(result_layer);
    811 
    812   test_point = gfx::Point(91, 91);
    813   result_layer =
    814       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    815   EXPECT_FALSE(result_layer);
    816 
    817   // Hit testing for a point inside should return the child layer.
    818   test_point = gfx::Point(71, 71);
    819   result_layer =
    820       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    821   ASSERT_TRUE(result_layer);
    822   EXPECT_EQ(456, result_layer->id());
    823 
    824   test_point = gfx::Point(89, 89);
    825   result_layer =
    826       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    827   ASSERT_TRUE(result_layer);
    828   EXPECT_EQ(456, result_layer->id());
    829 }
    830 
    831 TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) {
    832   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
    833 
    834   gfx::Transform identity_matrix;
    835   gfx::Point3F transform_origin;
    836   gfx::PointF position;
    837   gfx::Size bounds(100, 100);
    838   SetLayerPropertiesForTesting(root.get(),
    839                                identity_matrix,
    840                                transform_origin,
    841                                position,
    842                                bounds,
    843                                true,
    844                                false);
    845   root->SetDrawsContent(true);
    846   {
    847     // child 1 and child2 are initialized to overlap between x=50 and x=60.
    848     // grand_child is set to overlap both child1 and child2 between y=50 and
    849     // y=60.  The expected stacking order is: (front) child2, (second)
    850     // grand_child, (third) child1, and (back) the root layer behind all other
    851     // layers.
    852 
    853     scoped_ptr<LayerImpl> child1 =
    854         LayerImpl::Create(host_impl().active_tree(), 2);
    855     scoped_ptr<LayerImpl> child2 =
    856         LayerImpl::Create(host_impl().active_tree(), 3);
    857     scoped_ptr<LayerImpl> grand_child1 =
    858         LayerImpl::Create(host_impl().active_tree(), 4);
    859 
    860     position = gfx::PointF(10.f, 10.f);
    861     bounds = gfx::Size(50, 50);
    862     SetLayerPropertiesForTesting(child1.get(),
    863                                  identity_matrix,
    864                                  transform_origin,
    865                                  position,
    866                                  bounds,
    867                                  true,
    868                                  false);
    869     child1->SetDrawsContent(true);
    870 
    871     position = gfx::PointF(50.f, 10.f);
    872     bounds = gfx::Size(50, 50);
    873     SetLayerPropertiesForTesting(child2.get(),
    874                                  identity_matrix,
    875                                  transform_origin,
    876                                  position,
    877                                  bounds,
    878                                  true,
    879                                  false);
    880     child2->SetDrawsContent(true);
    881 
    882     // Remember that grand_child is positioned with respect to its parent (i.e.
    883     // child1).  In screen space, the intended position is (10, 50), with size
    884     // 100 x 50.
    885     position = gfx::PointF(0.f, 40.f);
    886     bounds = gfx::Size(100, 50);
    887     SetLayerPropertiesForTesting(grand_child1.get(),
    888                                  identity_matrix,
    889                                  transform_origin,
    890                                  position,
    891                                  bounds,
    892                                  true,
    893                                  false);
    894     grand_child1->SetDrawsContent(true);
    895 
    896     child1->AddChild(grand_child1.Pass());
    897     root->AddChild(child1.Pass());
    898     root->AddChild(child2.Pass());
    899   }
    900 
    901   LayerImpl* child1 = root->children()[0];
    902   LayerImpl* child2 = root->children()[1];
    903   LayerImpl* grand_child1 = child1->children()[0];
    904 
    905   host_impl().SetViewportSize(root->bounds());
    906   host_impl().active_tree()->SetRootLayer(root.Pass());
    907   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
    908 
    909   // Sanity check the scenario we just created.
    910   ASSERT_TRUE(child1);
    911   ASSERT_TRUE(child2);
    912   ASSERT_TRUE(grand_child1);
    913   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
    914 
    915   RenderSurfaceImpl* root_render_surface = root_layer()->render_surface();
    916   ASSERT_EQ(4u, root_render_surface->layer_list().size());
    917   ASSERT_EQ(1, root_render_surface->layer_list().at(0)->id());  // root layer
    918   ASSERT_EQ(2, root_render_surface->layer_list().at(1)->id());  // child1
    919   ASSERT_EQ(4, root_render_surface->layer_list().at(2)->id());  // grand_child1
    920   ASSERT_EQ(3, root_render_surface->layer_list().at(3)->id());  // child2
    921 
    922   // Nothing overlaps the root_layer at (1, 1), so hit testing there should find
    923   // the root layer.
    924   gfx::Point test_point = gfx::Point(1, 1);
    925   LayerImpl* result_layer =
    926       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    927   ASSERT_TRUE(result_layer);
    928   EXPECT_EQ(1, result_layer->id());
    929 
    930   // At (15, 15), child1 and root are the only layers. child1 is expected to be
    931   // on top.
    932   test_point = gfx::Point(15, 15);
    933   result_layer =
    934       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    935   ASSERT_TRUE(result_layer);
    936   EXPECT_EQ(2, result_layer->id());
    937 
    938   // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
    939   test_point = gfx::Point(51, 20);
    940   result_layer =
    941       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    942   ASSERT_TRUE(result_layer);
    943   EXPECT_EQ(3, result_layer->id());
    944 
    945   // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
    946   // top.
    947   test_point = gfx::Point(80, 51);
    948   result_layer =
    949       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    950   ASSERT_TRUE(result_layer);
    951   EXPECT_EQ(3, result_layer->id());
    952 
    953   // At (51, 51), all layers overlap each other. child2 is expected to be on top
    954   // of all other layers.
    955   test_point = gfx::Point(51, 51);
    956   result_layer =
    957       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    958   ASSERT_TRUE(result_layer);
    959   EXPECT_EQ(3, result_layer->id());
    960 
    961   // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
    962   // be on top.
    963   test_point = gfx::Point(20, 51);
    964   result_layer =
    965       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
    966   ASSERT_TRUE(result_layer);
    967   EXPECT_EQ(4, result_layer->id());
    968 }
    969 
    970 TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) {
    971   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
    972 
    973   gfx::Transform identity_matrix;
    974   gfx::Point3F transform_origin;
    975   gfx::PointF position;
    976   gfx::Size bounds(100, 100);
    977   SetLayerPropertiesForTesting(root.get(),
    978                                identity_matrix,
    979                                transform_origin,
    980                                position,
    981                                bounds,
    982                                true,
    983                                false);
    984   root->SetDrawsContent(true);
    985   root->SetShouldFlattenTransform(false);
    986   root->Set3dSortingContextId(1);
    987   {
    988     // child 1 and child2 are initialized to overlap between x=50 and x=60.
    989     // grand_child is set to overlap both child1 and child2 between y=50 and
    990     // y=60.  The expected stacking order is: (front) child2, (second)
    991     // grand_child, (third) child1, and (back) the root layer behind all other
    992     // layers.
    993 
    994     scoped_ptr<LayerImpl> child1 =
    995         LayerImpl::Create(host_impl().active_tree(), 2);
    996     scoped_ptr<LayerImpl> child2 =
    997         LayerImpl::Create(host_impl().active_tree(), 3);
    998     scoped_ptr<LayerImpl> grand_child1 =
    999         LayerImpl::Create(host_impl().active_tree(), 4);
   1000 
   1001     position = gfx::PointF(10.f, 10.f);
   1002     bounds = gfx::Size(50, 50);
   1003     SetLayerPropertiesForTesting(child1.get(),
   1004                                  identity_matrix,
   1005                                  transform_origin,
   1006                                  position,
   1007                                  bounds,
   1008                                  true,
   1009                                  false);
   1010     child1->SetDrawsContent(true);
   1011     child1->SetShouldFlattenTransform(false);
   1012     child1->Set3dSortingContextId(1);
   1013 
   1014     position = gfx::PointF(50.f, 10.f);
   1015     bounds = gfx::Size(50, 50);
   1016     gfx::Transform translate_z;
   1017     translate_z.Translate3d(0, 0, -10.f);
   1018     SetLayerPropertiesForTesting(child2.get(),
   1019                                  translate_z,
   1020                                  transform_origin,
   1021                                  position,
   1022                                  bounds,
   1023                                  true,
   1024                                  false);
   1025     child2->SetDrawsContent(true);
   1026     child2->SetShouldFlattenTransform(false);
   1027     child2->Set3dSortingContextId(1);
   1028 
   1029     // Remember that grand_child is positioned with respect to its parent (i.e.
   1030     // child1).  In screen space, the intended position is (10, 50), with size
   1031     // 100 x 50.
   1032     position = gfx::PointF(0.f, 40.f);
   1033     bounds = gfx::Size(100, 50);
   1034     SetLayerPropertiesForTesting(grand_child1.get(),
   1035                                  identity_matrix,
   1036                                  transform_origin,
   1037                                  position,
   1038                                  bounds,
   1039                                  true,
   1040                                  false);
   1041     grand_child1->SetDrawsContent(true);
   1042     grand_child1->SetShouldFlattenTransform(false);
   1043 
   1044     child1->AddChild(grand_child1.Pass());
   1045     root->AddChild(child1.Pass());
   1046     root->AddChild(child2.Pass());
   1047   }
   1048 
   1049   LayerImpl* child1 = root->children()[0];
   1050   LayerImpl* child2 = root->children()[1];
   1051   LayerImpl* grand_child1 = child1->children()[0];
   1052 
   1053   host_impl().SetViewportSize(root->bounds());
   1054   host_impl().active_tree()->SetRootLayer(root.Pass());
   1055   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1056 
   1057   // Sanity check the scenario we just created.
   1058   ASSERT_TRUE(child1);
   1059   ASSERT_TRUE(child2);
   1060   ASSERT_TRUE(grand_child1);
   1061   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   1062 
   1063   RenderSurfaceImpl* root_render_surface =
   1064       host_impl().active_tree()->root_layer()->render_surface();
   1065   ASSERT_EQ(4u, root_render_surface->layer_list().size());
   1066   ASSERT_EQ(3, root_render_surface->layer_list().at(0)->id());
   1067   ASSERT_EQ(1, root_render_surface->layer_list().at(1)->id());
   1068   ASSERT_EQ(2, root_render_surface->layer_list().at(2)->id());
   1069   ASSERT_EQ(4, root_render_surface->layer_list().at(3)->id());
   1070 
   1071   // Nothing overlaps the root_layer at (1, 1), so hit testing there should find
   1072   // the root layer.
   1073   gfx::Point test_point = gfx::Point(1, 1);
   1074   LayerImpl* result_layer =
   1075       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1076   ASSERT_TRUE(result_layer);
   1077   EXPECT_EQ(1, result_layer->id());
   1078 
   1079   // At (15, 15), child1 and root are the only layers. child1 is expected to be
   1080   // on top.
   1081   test_point = gfx::Point(15, 15);
   1082   result_layer =
   1083       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1084   ASSERT_TRUE(result_layer);
   1085   EXPECT_EQ(2, result_layer->id());
   1086 
   1087   // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
   1088   // (because 3 is transformed to the back).
   1089   test_point = gfx::Point(51, 20);
   1090   result_layer =
   1091       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1092   ASSERT_TRUE(result_layer);
   1093   EXPECT_EQ(2, result_layer->id());
   1094 
   1095   // 3 Would have been on top if it hadn't been transformed to the background.
   1096   // Make sure that it isn't hit.
   1097   test_point = gfx::Point(80, 51);
   1098   result_layer =
   1099       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1100   ASSERT_TRUE(result_layer);
   1101   EXPECT_EQ(4, result_layer->id());
   1102 
   1103   // 3 Would have been on top if it hadn't been transformed to the background.
   1104   // Make sure that it isn't hit.
   1105   test_point = gfx::Point(51, 51);
   1106   result_layer =
   1107       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1108   ASSERT_TRUE(result_layer);
   1109   EXPECT_EQ(4, result_layer->id());
   1110 
   1111   // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
   1112   // be on top.
   1113   test_point = gfx::Point(20, 51);
   1114   result_layer =
   1115       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1116   ASSERT_TRUE(result_layer);
   1117   EXPECT_EQ(4, result_layer->id());
   1118 }
   1119 
   1120 TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) {
   1121   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
   1122   gfx::Transform identity_matrix;
   1123   gfx::Point3F transform_origin;
   1124   gfx::PointF position;
   1125   gfx::Size bounds(100, 100);
   1126   SetLayerPropertiesForTesting(root.get(),
   1127                                identity_matrix,
   1128                                transform_origin,
   1129                                position,
   1130                                bounds,
   1131                                true,
   1132                                false);
   1133   root->SetDrawsContent(true);
   1134   {
   1135     scoped_ptr<LayerImpl> child =
   1136         LayerImpl::Create(host_impl().active_tree(), 2);
   1137     scoped_ptr<LayerImpl> grand_child =
   1138         LayerImpl::Create(host_impl().active_tree(), 4);
   1139 
   1140     position = gfx::PointF(10.f, 10.f);
   1141     bounds = gfx::Size(1, 1);
   1142     SetLayerPropertiesForTesting(child.get(),
   1143                                  identity_matrix,
   1144                                  transform_origin,
   1145                                  position,
   1146                                  bounds,
   1147                                  true,
   1148                                  false);
   1149     child->SetDrawsContent(true);
   1150     child->SetMasksToBounds(true);
   1151 
   1152     position = gfx::PointF(0.f, 40.f);
   1153     bounds = gfx::Size(100, 50);
   1154     SetLayerPropertiesForTesting(grand_child.get(),
   1155                                  identity_matrix,
   1156                                  transform_origin,
   1157                                  position,
   1158                                  bounds,
   1159                                  true,
   1160                                  false);
   1161     grand_child->SetDrawsContent(true);
   1162     grand_child->SetForceRenderSurface(true);
   1163 
   1164     // This should let |grand_child| "escape" |child|'s clip.
   1165     grand_child->SetClipParent(root.get());
   1166 
   1167     child->AddChild(grand_child.Pass());
   1168     root->AddChild(child.Pass());
   1169   }
   1170 
   1171   host_impl().SetViewportSize(root->bounds());
   1172   host_impl().active_tree()->SetRootLayer(root.Pass());
   1173   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1174 
   1175   gfx::Point test_point = gfx::Point(12, 52);
   1176   LayerImpl* result_layer =
   1177       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1178   ASSERT_TRUE(result_layer);
   1179   EXPECT_EQ(4, result_layer->id());
   1180 }
   1181 
   1182 TEST_F(LayerTreeImplTest, HitTestingRespectsScrollParents) {
   1183   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
   1184   gfx::Transform identity_matrix;
   1185   gfx::Point3F transform_origin;
   1186   gfx::PointF position;
   1187   gfx::Size bounds(100, 100);
   1188   SetLayerPropertiesForTesting(root.get(),
   1189                                identity_matrix,
   1190                                transform_origin,
   1191                                position,
   1192                                bounds,
   1193                                true,
   1194                                false);
   1195   root->SetDrawsContent(true);
   1196   {
   1197     scoped_ptr<LayerImpl> child =
   1198         LayerImpl::Create(host_impl().active_tree(), 2);
   1199     scoped_ptr<LayerImpl> scroll_child =
   1200         LayerImpl::Create(host_impl().active_tree(), 3);
   1201     scoped_ptr<LayerImpl> grand_child =
   1202         LayerImpl::Create(host_impl().active_tree(), 4);
   1203 
   1204     position = gfx::PointF(10.f, 10.f);
   1205     bounds = gfx::Size(1, 1);
   1206     SetLayerPropertiesForTesting(child.get(),
   1207                                  identity_matrix,
   1208                                  transform_origin,
   1209                                  position,
   1210                                  bounds,
   1211                                  true,
   1212                                  false);
   1213     child->SetDrawsContent(true);
   1214     child->SetMasksToBounds(true);
   1215 
   1216     position = gfx::PointF();
   1217     bounds = gfx::Size(200, 200);
   1218     SetLayerPropertiesForTesting(scroll_child.get(),
   1219                                  identity_matrix,
   1220                                  transform_origin,
   1221                                  position,
   1222                                  bounds,
   1223                                  true,
   1224                                  false);
   1225     scroll_child->SetDrawsContent(true);
   1226 
   1227     // This should cause scroll child and its descendants to be affected by
   1228     // |child|'s clip.
   1229     scroll_child->SetScrollParent(child.get());
   1230 
   1231     SetLayerPropertiesForTesting(grand_child.get(),
   1232                                  identity_matrix,
   1233                                  transform_origin,
   1234                                  position,
   1235                                  bounds,
   1236                                  true,
   1237                                  false);
   1238     grand_child->SetDrawsContent(true);
   1239     grand_child->SetForceRenderSurface(true);
   1240 
   1241     scroll_child->AddChild(grand_child.Pass());
   1242     root->AddChild(scroll_child.Pass());
   1243     root->AddChild(child.Pass());
   1244   }
   1245 
   1246   host_impl().SetViewportSize(root->bounds());
   1247   host_impl().active_tree()->SetRootLayer(root.Pass());
   1248   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1249 
   1250   gfx::Point test_point = gfx::Point(12, 52);
   1251   LayerImpl* result_layer =
   1252       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1253   // The |test_point| should have been clipped away by |child|, the scroll
   1254   // parent, so the only thing that should be hit is |root|.
   1255   ASSERT_TRUE(result_layer);
   1256   ASSERT_EQ(1, result_layer->id());
   1257 }
   1258 TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) {
   1259   //
   1260   // The geometry is set up similarly to the previous case, but
   1261   // all layers are forced to be render surfaces now.
   1262   //
   1263   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
   1264 
   1265   gfx::Transform identity_matrix;
   1266   gfx::Point3F transform_origin;
   1267   gfx::PointF position;
   1268   gfx::Size bounds(100, 100);
   1269   SetLayerPropertiesForTesting(root.get(),
   1270                                identity_matrix,
   1271                                transform_origin,
   1272                                position,
   1273                                bounds,
   1274                                true,
   1275                                false);
   1276   root->SetDrawsContent(true);
   1277   {
   1278     // child 1 and child2 are initialized to overlap between x=50 and x=60.
   1279     // grand_child is set to overlap both child1 and child2 between y=50 and
   1280     // y=60.  The expected stacking order is: (front) child2, (second)
   1281     // grand_child, (third) child1, and (back) the root layer behind all other
   1282     // layers.
   1283 
   1284     scoped_ptr<LayerImpl> child1 =
   1285         LayerImpl::Create(host_impl().active_tree(), 2);
   1286     scoped_ptr<LayerImpl> child2 =
   1287         LayerImpl::Create(host_impl().active_tree(), 3);
   1288     scoped_ptr<LayerImpl> grand_child1 =
   1289         LayerImpl::Create(host_impl().active_tree(), 4);
   1290 
   1291     position = gfx::PointF(10.f, 10.f);
   1292     bounds = gfx::Size(50, 50);
   1293     SetLayerPropertiesForTesting(child1.get(),
   1294                                  identity_matrix,
   1295                                  transform_origin,
   1296                                  position,
   1297                                  bounds,
   1298                                  true,
   1299                                  false);
   1300     child1->SetDrawsContent(true);
   1301     child1->SetForceRenderSurface(true);
   1302 
   1303     position = gfx::PointF(50.f, 10.f);
   1304     bounds = gfx::Size(50, 50);
   1305     SetLayerPropertiesForTesting(child2.get(),
   1306                                  identity_matrix,
   1307                                  transform_origin,
   1308                                  position,
   1309                                  bounds,
   1310                                  true,
   1311                                  false);
   1312     child2->SetDrawsContent(true);
   1313     child2->SetForceRenderSurface(true);
   1314 
   1315     // Remember that grand_child is positioned with respect to its parent (i.e.
   1316     // child1).  In screen space, the intended position is (10, 50), with size
   1317     // 100 x 50.
   1318     position = gfx::PointF(0.f, 40.f);
   1319     bounds = gfx::Size(100, 50);
   1320     SetLayerPropertiesForTesting(grand_child1.get(),
   1321                                  identity_matrix,
   1322                                  transform_origin,
   1323                                  position,
   1324                                  bounds,
   1325                                  true,
   1326                                  false);
   1327     grand_child1->SetDrawsContent(true);
   1328     grand_child1->SetForceRenderSurface(true);
   1329 
   1330     child1->AddChild(grand_child1.Pass());
   1331     root->AddChild(child1.Pass());
   1332     root->AddChild(child2.Pass());
   1333   }
   1334 
   1335   LayerImpl* child1 = root->children()[0];
   1336   LayerImpl* child2 = root->children()[1];
   1337   LayerImpl* grand_child1 = child1->children()[0];
   1338 
   1339   host_impl().SetViewportSize(root->bounds());
   1340   host_impl().active_tree()->SetRootLayer(root.Pass());
   1341   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1342 
   1343   // Sanity check the scenario we just created.
   1344   ASSERT_TRUE(child1);
   1345   ASSERT_TRUE(child2);
   1346   ASSERT_TRUE(grand_child1);
   1347   ASSERT_TRUE(child1->render_surface());
   1348   ASSERT_TRUE(child2->render_surface());
   1349   ASSERT_TRUE(grand_child1->render_surface());
   1350   ASSERT_EQ(4u, RenderSurfaceLayerList().size());
   1351   // The root surface has the root layer, and child1's and child2's render
   1352   // surfaces.
   1353   ASSERT_EQ(3u, root_layer()->render_surface()->layer_list().size());
   1354   // The child1 surface has the child1 layer and grand_child1's render surface.
   1355   ASSERT_EQ(2u, child1->render_surface()->layer_list().size());
   1356   ASSERT_EQ(1u, child2->render_surface()->layer_list().size());
   1357   ASSERT_EQ(1u, grand_child1->render_surface()->layer_list().size());
   1358   ASSERT_EQ(1, RenderSurfaceLayerList().at(0)->id());  // root layer
   1359   ASSERT_EQ(2, RenderSurfaceLayerList()[1]->id());     // child1
   1360   ASSERT_EQ(4, RenderSurfaceLayerList().at(2)->id());  // grand_child1
   1361   ASSERT_EQ(3, RenderSurfaceLayerList()[3]->id());     // child2
   1362 
   1363   // Nothing overlaps the root_layer at (1, 1), so hit testing there should find
   1364   // the root layer.
   1365   gfx::Point test_point = gfx::Point(1, 1);
   1366   LayerImpl* result_layer =
   1367       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1368   ASSERT_TRUE(result_layer);
   1369   EXPECT_EQ(1, result_layer->id());
   1370 
   1371   // At (15, 15), child1 and root are the only layers. child1 is expected to be
   1372   // on top.
   1373   test_point = gfx::Point(15, 15);
   1374   result_layer =
   1375       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1376   ASSERT_TRUE(result_layer);
   1377   EXPECT_EQ(2, result_layer->id());
   1378 
   1379   // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
   1380   test_point = gfx::Point(51, 20);
   1381   result_layer =
   1382       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1383   ASSERT_TRUE(result_layer);
   1384   EXPECT_EQ(3, result_layer->id());
   1385 
   1386   // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
   1387   // top.
   1388   test_point = gfx::Point(80, 51);
   1389   result_layer =
   1390       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1391   ASSERT_TRUE(result_layer);
   1392   EXPECT_EQ(3, result_layer->id());
   1393 
   1394   // At (51, 51), all layers overlap each other. child2 is expected to be on top
   1395   // of all other layers.
   1396   test_point = gfx::Point(51, 51);
   1397   result_layer =
   1398       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1399   ASSERT_TRUE(result_layer);
   1400   EXPECT_EQ(3, result_layer->id());
   1401 
   1402   // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
   1403   // be on top.
   1404   test_point = gfx::Point(20, 51);
   1405   result_layer =
   1406       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
   1407   ASSERT_TRUE(result_layer);
   1408   EXPECT_EQ(4, result_layer->id());
   1409 }
   1410 
   1411 TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) {
   1412   scoped_ptr<LayerImpl> root =
   1413       LayerImpl::Create(host_impl().active_tree(), 12345);
   1414 
   1415   gfx::Transform identity_matrix;
   1416   Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
   1417   gfx::Point3F transform_origin;
   1418   gfx::PointF position;
   1419   gfx::Size bounds(100, 100);
   1420   SetLayerPropertiesForTesting(root.get(),
   1421                                identity_matrix,
   1422                                transform_origin,
   1423                                position,
   1424                                bounds,
   1425                                true,
   1426                                false);
   1427   root->SetDrawsContent(true);
   1428 
   1429   host_impl().SetViewportSize(root->bounds());
   1430   host_impl().active_tree()->SetRootLayer(root.Pass());
   1431   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1432 
   1433   // Sanity check the scenario we just created.
   1434   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   1435   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
   1436 
   1437   // Hit checking for any point should return a null pointer for a layer without
   1438   // any touch event handler regions.
   1439   gfx::Point test_point(11, 11);
   1440   LayerImpl* result_layer =
   1441       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1442           test_point);
   1443   EXPECT_FALSE(result_layer);
   1444 
   1445   host_impl().active_tree()->root_layer()->SetTouchEventHandlerRegion(
   1446       touch_handler_region);
   1447   // Hit checking for a point outside the layer should return a null pointer.
   1448   test_point = gfx::Point(101, 101);
   1449   result_layer =
   1450       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1451           test_point);
   1452   EXPECT_FALSE(result_layer);
   1453 
   1454   test_point = gfx::Point(-1, -1);
   1455   result_layer =
   1456       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1457           test_point);
   1458   EXPECT_FALSE(result_layer);
   1459 
   1460   // Hit checking for a point inside the layer, but outside the touch handler
   1461   // region should return a null pointer.
   1462   test_point = gfx::Point(1, 1);
   1463   result_layer =
   1464       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1465           test_point);
   1466   EXPECT_FALSE(result_layer);
   1467 
   1468   test_point = gfx::Point(99, 99);
   1469   result_layer =
   1470       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1471           test_point);
   1472   EXPECT_FALSE(result_layer);
   1473 
   1474   // Hit checking for a point inside the touch event handler region should
   1475   // return the root layer.
   1476   test_point = gfx::Point(11, 11);
   1477   result_layer =
   1478       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1479           test_point);
   1480   ASSERT_TRUE(result_layer);
   1481   EXPECT_EQ(12345, result_layer->id());
   1482 
   1483   test_point = gfx::Point(59, 59);
   1484   result_layer =
   1485       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1486           test_point);
   1487   ASSERT_TRUE(result_layer);
   1488   EXPECT_EQ(12345, result_layer->id());
   1489 }
   1490 
   1491 TEST_F(LayerTreeImplTest,
   1492        HitCheckingTouchHandlerRegionsForUninvertibleTransform) {
   1493   scoped_ptr<LayerImpl> root =
   1494       LayerImpl::Create(host_impl().active_tree(), 12345);
   1495 
   1496   gfx::Transform uninvertible_transform;
   1497   uninvertible_transform.matrix().set(0, 0, 0.0);
   1498   uninvertible_transform.matrix().set(1, 1, 0.0);
   1499   uninvertible_transform.matrix().set(2, 2, 0.0);
   1500   uninvertible_transform.matrix().set(3, 3, 0.0);
   1501   ASSERT_FALSE(uninvertible_transform.IsInvertible());
   1502 
   1503   gfx::Transform identity_matrix;
   1504   Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
   1505   gfx::Point3F transform_origin;
   1506   gfx::PointF position;
   1507   gfx::Size bounds(100, 100);
   1508   SetLayerPropertiesForTesting(root.get(),
   1509                                uninvertible_transform,
   1510                                transform_origin,
   1511                                position,
   1512                                bounds,
   1513                                true,
   1514                                false);
   1515   root->SetDrawsContent(true);
   1516   root->SetTouchEventHandlerRegion(touch_handler_region);
   1517 
   1518   host_impl().SetViewportSize(root->bounds());
   1519   host_impl().active_tree()->SetRootLayer(root.Pass());
   1520   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1521 
   1522   // Sanity check the scenario we just created.
   1523   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   1524   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
   1525   ASSERT_FALSE(root_layer()->screen_space_transform().IsInvertible());
   1526 
   1527   // Hit checking any point should not hit the touch handler region on the
   1528   // layer. If the invertible matrix is accidentally ignored and treated like an
   1529   // identity, then the hit testing will incorrectly hit the layer when it
   1530   // shouldn't.
   1531   gfx::Point test_point(1, 1);
   1532   LayerImpl* result_layer =
   1533       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1534           test_point);
   1535   EXPECT_FALSE(result_layer);
   1536 
   1537   test_point = gfx::Point(10, 10);
   1538   result_layer =
   1539       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1540           test_point);
   1541   EXPECT_FALSE(result_layer);
   1542 
   1543   test_point = gfx::Point(10, 30);
   1544   result_layer =
   1545       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1546           test_point);
   1547   EXPECT_FALSE(result_layer);
   1548 
   1549   test_point = gfx::Point(50, 50);
   1550   result_layer =
   1551       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1552           test_point);
   1553   EXPECT_FALSE(result_layer);
   1554 
   1555   test_point = gfx::Point(67, 48);
   1556   result_layer =
   1557       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1558           test_point);
   1559   EXPECT_FALSE(result_layer);
   1560 
   1561   test_point = gfx::Point(99, 99);
   1562   result_layer =
   1563       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1564           test_point);
   1565   EXPECT_FALSE(result_layer);
   1566 
   1567   test_point = gfx::Point(-1, -1);
   1568   result_layer =
   1569       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1570           test_point);
   1571   EXPECT_FALSE(result_layer);
   1572 }
   1573 
   1574 TEST_F(LayerTreeImplTest,
   1575        HitCheckingTouchHandlerRegionsForSinglePositionedLayer) {
   1576   scoped_ptr<LayerImpl> root =
   1577       LayerImpl::Create(host_impl().active_tree(), 12345);
   1578 
   1579   gfx::Transform identity_matrix;
   1580   Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
   1581   gfx::Point3F transform_origin;
   1582   // this layer is positioned, and hit testing should correctly know where the
   1583   // layer is located.
   1584   gfx::PointF position(50.f, 50.f);
   1585   gfx::Size bounds(100, 100);
   1586   SetLayerPropertiesForTesting(root.get(),
   1587                                identity_matrix,
   1588                                transform_origin,
   1589                                position,
   1590                                bounds,
   1591                                true,
   1592                                false);
   1593   root->SetDrawsContent(true);
   1594   root->SetTouchEventHandlerRegion(touch_handler_region);
   1595 
   1596   host_impl().SetViewportSize(root->bounds());
   1597   host_impl().active_tree()->SetRootLayer(root.Pass());
   1598   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1599 
   1600   // Sanity check the scenario we just created.
   1601   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   1602   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
   1603 
   1604   // Hit checking for a point outside the layer should return a null pointer.
   1605   gfx::Point test_point(49, 49);
   1606   LayerImpl* result_layer =
   1607       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1608           test_point);
   1609   EXPECT_FALSE(result_layer);
   1610 
   1611   // Even though the layer has a touch handler region containing (101, 101), it
   1612   // should not be visible there since the root render surface would clamp it.
   1613   test_point = gfx::Point(101, 101);
   1614   result_layer =
   1615       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1616           test_point);
   1617   EXPECT_FALSE(result_layer);
   1618 
   1619   // Hit checking for a point inside the layer, but outside the touch handler
   1620   // region should return a null pointer.
   1621   test_point = gfx::Point(51, 51);
   1622   result_layer =
   1623       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1624           test_point);
   1625   EXPECT_FALSE(result_layer);
   1626 
   1627   // Hit checking for a point inside the touch event handler region should
   1628   // return the root layer.
   1629   test_point = gfx::Point(61, 61);
   1630   result_layer =
   1631       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1632           test_point);
   1633   ASSERT_TRUE(result_layer);
   1634   EXPECT_EQ(12345, result_layer->id());
   1635 
   1636   test_point = gfx::Point(99, 99);
   1637   result_layer =
   1638       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1639           test_point);
   1640   ASSERT_TRUE(result_layer);
   1641   EXPECT_EQ(12345, result_layer->id());
   1642 }
   1643 
   1644 TEST_F(LayerTreeImplTest,
   1645        HitCheckingTouchHandlerRegionsForSingleLayerWithScaledContents) {
   1646   // A layer's visible content rect is actually in the layer's content space.
   1647   // The screen space transform converts from the layer's origin space to screen
   1648   // space. This test makes sure that hit testing works correctly accounts for
   1649   // the contents scale.  A contents scale that is not 1 effectively forces a
   1650   // non-identity transform between layer's content space and layer's origin
   1651   // space. The hit testing code must take this into account.
   1652   //
   1653   // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
   1654   // contents scale is ignored, then hit checking will mis-interpret the visible
   1655   // content rect as being larger than the actual bounds of the layer.
   1656   //
   1657   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
   1658 
   1659   gfx::Transform identity_matrix;
   1660   gfx::Point3F transform_origin;
   1661 
   1662   SetLayerPropertiesForTesting(root.get(),
   1663                                identity_matrix,
   1664                                transform_origin,
   1665                                gfx::PointF(),
   1666                                gfx::Size(100, 100),
   1667                                true,
   1668                                false);
   1669   {
   1670     Region touch_handler_region(gfx::Rect(10, 10, 30, 30));
   1671     gfx::PointF position(25.f, 25.f);
   1672     gfx::Size bounds(50, 50);
   1673     scoped_ptr<LayerImpl> test_layer =
   1674         LayerImpl::Create(host_impl().active_tree(), 12345);
   1675     SetLayerPropertiesForTesting(test_layer.get(),
   1676                                  identity_matrix,
   1677                                  transform_origin,
   1678                                  position,
   1679                                  bounds,
   1680                                  true,
   1681                                  false);
   1682 
   1683     // override content bounds and contents scale
   1684     test_layer->SetContentBounds(gfx::Size(100, 100));
   1685     test_layer->SetContentsScale(2, 2);
   1686 
   1687     test_layer->SetDrawsContent(true);
   1688     test_layer->SetTouchEventHandlerRegion(touch_handler_region);
   1689     root->AddChild(test_layer.Pass());
   1690   }
   1691 
   1692   host_impl().SetViewportSize(root->bounds());
   1693   host_impl().active_tree()->SetRootLayer(root.Pass());
   1694   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1695 
   1696   // Sanity check the scenario we just created.
   1697   // The visible content rect for test_layer is actually 100x100, even though
   1698   // its layout size is 50x50, positioned at 25x25.
   1699   LayerImpl* test_layer =
   1700       host_impl().active_tree()->root_layer()->children()[0];
   1701   EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), test_layer->visible_content_rect());
   1702   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   1703   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
   1704 
   1705   // Hit checking for a point outside the layer should return a null pointer
   1706   // (the root layer does not draw content, so it will not be tested either).
   1707   gfx::Point test_point(76, 76);
   1708   LayerImpl* result_layer =
   1709       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1710           test_point);
   1711   EXPECT_FALSE(result_layer);
   1712 
   1713   // Hit checking for a point inside the layer, but outside the touch handler
   1714   // region should return a null pointer.
   1715   test_point = gfx::Point(26, 26);
   1716   result_layer =
   1717       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1718           test_point);
   1719   EXPECT_FALSE(result_layer);
   1720 
   1721   test_point = gfx::Point(34, 34);
   1722   result_layer =
   1723       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1724           test_point);
   1725   EXPECT_FALSE(result_layer);
   1726 
   1727   test_point = gfx::Point(65, 65);
   1728   result_layer =
   1729       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1730           test_point);
   1731   EXPECT_FALSE(result_layer);
   1732 
   1733   test_point = gfx::Point(74, 74);
   1734   result_layer =
   1735       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1736           test_point);
   1737   EXPECT_FALSE(result_layer);
   1738 
   1739   // Hit checking for a point inside the touch event handler region should
   1740   // return the root layer.
   1741   test_point = gfx::Point(35, 35);
   1742   result_layer =
   1743       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1744           test_point);
   1745   ASSERT_TRUE(result_layer);
   1746   EXPECT_EQ(12345, result_layer->id());
   1747 
   1748   test_point = gfx::Point(64, 64);
   1749   result_layer =
   1750       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1751           test_point);
   1752   ASSERT_TRUE(result_layer);
   1753   EXPECT_EQ(12345, result_layer->id());
   1754 }
   1755 
   1756 TEST_F(LayerTreeImplTest,
   1757        HitCheckingTouchHandlerRegionsForSingleLayerWithDeviceScale) {
   1758   // The layer's device_scale_factor and page_scale_factor should scale the
   1759   // content rect and we should be able to hit the touch handler region by
   1760   // scaling the points accordingly.
   1761   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
   1762 
   1763   gfx::Transform identity_matrix;
   1764   gfx::Point3F transform_origin;
   1765   // Set the bounds of the root layer big enough to fit the child when scaled.
   1766   SetLayerPropertiesForTesting(root.get(),
   1767                                identity_matrix,
   1768                                transform_origin,
   1769                                gfx::PointF(),
   1770                                gfx::Size(100, 100),
   1771                                true,
   1772                                false);
   1773   {
   1774     Region touch_handler_region(gfx::Rect(10, 10, 30, 30));
   1775     gfx::PointF position(25.f, 25.f);
   1776     gfx::Size bounds(50, 50);
   1777     scoped_ptr<LayerImpl> test_layer =
   1778         LayerImpl::Create(host_impl().active_tree(), 12345);
   1779     SetLayerPropertiesForTesting(test_layer.get(),
   1780                                  identity_matrix,
   1781                                  transform_origin,
   1782                                  position,
   1783                                  bounds,
   1784                                  true,
   1785                                  false);
   1786 
   1787     test_layer->SetDrawsContent(true);
   1788     test_layer->SetTouchEventHandlerRegion(touch_handler_region);
   1789     root->AddChild(test_layer.Pass());
   1790   }
   1791 
   1792   float device_scale_factor = 3.f;
   1793   float page_scale_factor = 5.f;
   1794   gfx::Size scaled_bounds_for_root = gfx::ToCeiledSize(
   1795       gfx::ScaleSize(root->bounds(), device_scale_factor * page_scale_factor));
   1796   host_impl().SetViewportSize(scaled_bounds_for_root);
   1797 
   1798   host_impl().SetDeviceScaleFactor(device_scale_factor);
   1799   host_impl().active_tree()->SetPageScaleFactorAndLimits(
   1800       page_scale_factor, page_scale_factor, page_scale_factor);
   1801   host_impl().active_tree()->SetRootLayer(root.Pass());
   1802   host_impl().active_tree()->SetViewportLayersFromIds(1, 1, Layer::INVALID_ID);
   1803   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1804 
   1805   // Sanity check the scenario we just created.
   1806   // The visible content rect for test_layer is actually 100x100, even though
   1807   // its layout size is 50x50, positioned at 25x25.
   1808   LayerImpl* test_layer =
   1809       host_impl().active_tree()->root_layer()->children()[0];
   1810   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   1811   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
   1812 
   1813   // Check whether the child layer fits into the root after scaled.
   1814   EXPECT_RECT_EQ(gfx::Rect(test_layer->content_bounds()),
   1815                  test_layer->visible_content_rect());
   1816 
   1817   // Hit checking for a point outside the layer should return a null pointer
   1818   // (the root layer does not draw content, so it will not be tested either).
   1819   gfx::PointF test_point(76.f, 76.f);
   1820   test_point =
   1821       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
   1822   LayerImpl* result_layer =
   1823       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1824           test_point);
   1825   EXPECT_FALSE(result_layer);
   1826 
   1827   // Hit checking for a point inside the layer, but outside the touch handler
   1828   // region should return a null pointer.
   1829   test_point = gfx::Point(26, 26);
   1830   test_point =
   1831       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
   1832   result_layer =
   1833       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1834           test_point);
   1835   EXPECT_FALSE(result_layer);
   1836 
   1837   test_point = gfx::Point(34, 34);
   1838   test_point =
   1839       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
   1840   result_layer =
   1841       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1842           test_point);
   1843   EXPECT_FALSE(result_layer);
   1844 
   1845   test_point = gfx::Point(65, 65);
   1846   test_point =
   1847       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
   1848   result_layer =
   1849       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1850           test_point);
   1851   EXPECT_FALSE(result_layer);
   1852 
   1853   test_point = gfx::Point(74, 74);
   1854   test_point =
   1855       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
   1856   result_layer =
   1857       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1858           test_point);
   1859   EXPECT_FALSE(result_layer);
   1860 
   1861   // Hit checking for a point inside the touch event handler region should
   1862   // return the root layer.
   1863   test_point = gfx::Point(35, 35);
   1864   test_point =
   1865       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
   1866   result_layer =
   1867       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1868           test_point);
   1869   ASSERT_TRUE(result_layer);
   1870   EXPECT_EQ(12345, result_layer->id());
   1871 
   1872   test_point = gfx::Point(64, 64);
   1873   test_point =
   1874       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
   1875   result_layer =
   1876       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1877           test_point);
   1878   ASSERT_TRUE(result_layer);
   1879   EXPECT_EQ(12345, result_layer->id());
   1880 }
   1881 
   1882 TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) {
   1883   // Test that hit-checking will only work for the visible portion of a layer,
   1884   // and not the entire layer bounds. Here we just test the simple axis-aligned
   1885   // case.
   1886   gfx::Transform identity_matrix;
   1887   gfx::Point3F transform_origin;
   1888 
   1889   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
   1890   SetLayerPropertiesForTesting(root.get(),
   1891                                identity_matrix,
   1892                                transform_origin,
   1893                                gfx::PointF(),
   1894                                gfx::Size(100, 100),
   1895                                true,
   1896                                false);
   1897   {
   1898     scoped_ptr<LayerImpl> clipping_layer =
   1899         LayerImpl::Create(host_impl().active_tree(), 123);
   1900     // this layer is positioned, and hit testing should correctly know where the
   1901     // layer is located.
   1902     gfx::PointF position(25.f, 25.f);
   1903     gfx::Size bounds(50, 50);
   1904     SetLayerPropertiesForTesting(clipping_layer.get(),
   1905                                  identity_matrix,
   1906                                  transform_origin,
   1907                                  position,
   1908                                  bounds,
   1909                                  true,
   1910                                  false);
   1911     clipping_layer->SetMasksToBounds(true);
   1912 
   1913     scoped_ptr<LayerImpl> child =
   1914         LayerImpl::Create(host_impl().active_tree(), 456);
   1915     Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
   1916     position = gfx::PointF(-50.f, -50.f);
   1917     bounds = gfx::Size(300, 300);
   1918     SetLayerPropertiesForTesting(child.get(),
   1919                                  identity_matrix,
   1920                                  transform_origin,
   1921                                  position,
   1922                                  bounds,
   1923                                  true,
   1924                                  false);
   1925     child->SetDrawsContent(true);
   1926     child->SetTouchEventHandlerRegion(touch_handler_region);
   1927     clipping_layer->AddChild(child.Pass());
   1928     root->AddChild(clipping_layer.Pass());
   1929   }
   1930 
   1931   host_impl().SetViewportSize(root->bounds());
   1932   host_impl().active_tree()->SetRootLayer(root.Pass());
   1933   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   1934 
   1935   // Sanity check the scenario we just created.
   1936   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   1937   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
   1938   ASSERT_EQ(456, root_layer()->render_surface()->layer_list().at(0)->id());
   1939 
   1940   // Hit checking for a point outside the layer should return a null pointer.
   1941   // Despite the child layer being very large, it should be clipped to the root
   1942   // layer's bounds.
   1943   gfx::Point test_point(24, 24);
   1944   LayerImpl* result_layer =
   1945       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1946           test_point);
   1947   EXPECT_FALSE(result_layer);
   1948 
   1949   // Hit checking for a point inside the layer, but outside the touch handler
   1950   // region should return a null pointer.
   1951   test_point = gfx::Point(35, 35);
   1952   result_layer =
   1953       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1954           test_point);
   1955   EXPECT_FALSE(result_layer);
   1956 
   1957   test_point = gfx::Point(74, 74);
   1958   result_layer =
   1959       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1960           test_point);
   1961   EXPECT_FALSE(result_layer);
   1962 
   1963   // Hit checking for a point inside the touch event handler region should
   1964   // return the root layer.
   1965   test_point = gfx::Point(25, 25);
   1966   result_layer =
   1967       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1968           test_point);
   1969   ASSERT_TRUE(result_layer);
   1970   EXPECT_EQ(456, result_layer->id());
   1971 
   1972   test_point = gfx::Point(34, 34);
   1973   result_layer =
   1974       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   1975           test_point);
   1976   ASSERT_TRUE(result_layer);
   1977   EXPECT_EQ(456, result_layer->id());
   1978 }
   1979 
   1980 TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) {
   1981   gfx::Transform identity_matrix;
   1982   gfx::Point3F transform_origin;
   1983 
   1984   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
   1985   SetLayerPropertiesForTesting(root.get(),
   1986                                identity_matrix,
   1987                                transform_origin,
   1988                                gfx::PointF(),
   1989                                gfx::Size(100, 100),
   1990                                true,
   1991                                false);
   1992   {
   1993     scoped_ptr<LayerImpl> touch_layer =
   1994         LayerImpl::Create(host_impl().active_tree(), 123);
   1995     // this layer is positioned, and hit testing should correctly know where the
   1996     // layer is located.
   1997     gfx::PointF position;
   1998     gfx::Size bounds(50, 50);
   1999     SetLayerPropertiesForTesting(touch_layer.get(),
   2000                                  identity_matrix,
   2001                                  transform_origin,
   2002                                  position,
   2003                                  bounds,
   2004                                  true,
   2005                                  false);
   2006     touch_layer->SetDrawsContent(true);
   2007     touch_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50));
   2008     root->AddChild(touch_layer.Pass());
   2009   }
   2010 
   2011   {
   2012     scoped_ptr<LayerImpl> notouch_layer =
   2013         LayerImpl::Create(host_impl().active_tree(), 1234);
   2014     // this layer is positioned, and hit testing should correctly know where the
   2015     // layer is located.
   2016     gfx::PointF position(0, 25);
   2017     gfx::Size bounds(50, 50);
   2018     SetLayerPropertiesForTesting(notouch_layer.get(),
   2019                                  identity_matrix,
   2020                                  transform_origin,
   2021                                  position,
   2022                                  bounds,
   2023                                  true,
   2024                                  false);
   2025     notouch_layer->SetDrawsContent(true);
   2026     root->AddChild(notouch_layer.Pass());
   2027   }
   2028 
   2029   host_impl().SetViewportSize(root->bounds());
   2030   host_impl().active_tree()->SetRootLayer(root.Pass());
   2031   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   2032 
   2033   // Sanity check the scenario we just created.
   2034   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   2035   ASSERT_EQ(2u, root_layer()->render_surface()->layer_list().size());
   2036   ASSERT_EQ(123, root_layer()->render_surface()->layer_list().at(0)->id());
   2037   ASSERT_EQ(1234, root_layer()->render_surface()->layer_list().at(1)->id());
   2038 
   2039   gfx::Point test_point(35, 35);
   2040   LayerImpl* result_layer =
   2041       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   2042           test_point);
   2043 
   2044   // We should have passed through the no-touch layer and found the layer
   2045   // behind it.
   2046   EXPECT_TRUE(result_layer);
   2047 
   2048   host_impl().active_tree()->LayerById(1234)->SetContentsOpaque(true);
   2049   result_layer =
   2050       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   2051           test_point);
   2052 
   2053   // Even with an opaque layer in the middle, we should still find the layer
   2054   // with
   2055   // the touch handler behind it (since we can't assume that opaque layers are
   2056   // opaque to hit testing).
   2057   EXPECT_TRUE(result_layer);
   2058 
   2059   test_point = gfx::Point(35, 15);
   2060   result_layer =
   2061       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   2062           test_point);
   2063   ASSERT_TRUE(result_layer);
   2064   EXPECT_EQ(123, result_layer->id());
   2065 
   2066   test_point = gfx::Point(35, 65);
   2067   result_layer =
   2068       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
   2069           test_point);
   2070   EXPECT_FALSE(result_layer);
   2071 }
   2072 
   2073 TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) {
   2074   int root_layer_id = 12345;
   2075   scoped_ptr<LayerImpl> root =
   2076       LayerImpl::Create(host_impl().active_tree(), root_layer_id);
   2077 
   2078   gfx::Transform identity_matrix;
   2079   gfx::Point3F transform_origin;
   2080   gfx::PointF position;
   2081   gfx::Size bounds(100, 100);
   2082   SetLayerPropertiesForTesting(root.get(),
   2083                                identity_matrix,
   2084                                transform_origin,
   2085                                position,
   2086                                bounds,
   2087                                true,
   2088                                false);
   2089   root->SetDrawsContent(true);
   2090 
   2091   host_impl().SetViewportSize(root->bounds());
   2092   host_impl().active_tree()->SetRootLayer(root.Pass());
   2093   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   2094 
   2095   // Sanity check the scenario we just created.
   2096   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   2097   ASSERT_EQ(1u, root_layer()->render_surface()->layer_list().size());
   2098 
   2099   LayerSelectionBound left_input;
   2100   left_input.type = SELECTION_BOUND_LEFT;
   2101   left_input.edge_top = gfx::PointF(10, 10);
   2102   left_input.edge_bottom = gfx::PointF(10, 20);
   2103   left_input.layer_id = root_layer_id;
   2104 
   2105   LayerSelectionBound right_input;
   2106   right_input.type = SELECTION_BOUND_RIGHT;
   2107   right_input.edge_top = gfx::PointF(50, 10);
   2108   right_input.edge_bottom = gfx::PointF(50, 30);
   2109   right_input.layer_id = root_layer_id;
   2110 
   2111   ViewportSelectionBound left_output, right_output;
   2112 
   2113   // Empty input bounds should produce empty output bounds.
   2114   host_impl().active_tree()->GetViewportSelection(&left_output, &right_output);
   2115   EXPECT_EQ(ViewportSelectionBound(), left_output);
   2116   EXPECT_EQ(ViewportSelectionBound(), right_output);
   2117 
   2118   // Selection bounds should produce distinct left and right bounds.
   2119   host_impl().active_tree()->RegisterSelection(left_input, right_input);
   2120   host_impl().active_tree()->GetViewportSelection(&left_output, &right_output);
   2121   EXPECT_EQ(left_input.type, left_output.type);
   2122   EXPECT_EQ(left_input.edge_bottom, left_output.edge_bottom);
   2123   EXPECT_EQ(left_input.edge_top, left_output.edge_top);
   2124   EXPECT_TRUE(left_output.visible);
   2125   EXPECT_EQ(right_input.type, right_output.type);
   2126   EXPECT_EQ(right_input.edge_bottom, right_output.edge_bottom);
   2127   EXPECT_EQ(right_input.edge_top, right_output.edge_top);
   2128   EXPECT_TRUE(right_output.visible);
   2129 
   2130   // Insertion bounds should produce identical left and right bounds.
   2131   LayerSelectionBound insertion_input;
   2132   insertion_input.type = SELECTION_BOUND_CENTER;
   2133   insertion_input.edge_top = gfx::PointF(15, 10);
   2134   insertion_input.edge_bottom = gfx::PointF(15, 30);
   2135   insertion_input.layer_id = root_layer_id;
   2136   host_impl().active_tree()->RegisterSelection(insertion_input,
   2137                                                LayerSelectionBound());
   2138   host_impl().active_tree()->GetViewportSelection(&left_output, &right_output);
   2139   EXPECT_EQ(insertion_input.type, left_output.type);
   2140   EXPECT_EQ(insertion_input.edge_bottom, left_output.edge_bottom);
   2141   EXPECT_EQ(insertion_input.edge_top, left_output.edge_top);
   2142   EXPECT_TRUE(left_output.visible);
   2143   EXPECT_EQ(left_output, right_output);
   2144 }
   2145 
   2146 TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) {
   2147   int root_layer_id = 12345;
   2148   int clip_layer_id = 1234;
   2149   int clipped_layer_id = 123;
   2150   scoped_ptr<LayerImpl> root =
   2151       LayerImpl::Create(host_impl().active_tree(), root_layer_id);
   2152   root->SetDrawsContent(true);
   2153 
   2154   gfx::Transform identity_matrix;
   2155   gfx::Point3F transform_origin;
   2156   gfx::PointF position;
   2157   gfx::Size bounds(100, 100);
   2158   SetLayerPropertiesForTesting(root.get(),
   2159                                identity_matrix,
   2160                                transform_origin,
   2161                                position,
   2162                                bounds,
   2163                                true,
   2164                                false);
   2165 
   2166   gfx::Vector2dF clipping_offset(10, 10);
   2167   {
   2168     scoped_ptr<LayerImpl> clipping_layer =
   2169         LayerImpl::Create(host_impl().active_tree(), clip_layer_id);
   2170     // The clipping layer should occlude the right selection bound.
   2171     gfx::PointF position = gfx::PointF() + clipping_offset;
   2172     gfx::Size bounds(50, 50);
   2173     SetLayerPropertiesForTesting(clipping_layer.get(),
   2174                                  identity_matrix,
   2175                                  transform_origin,
   2176                                  position,
   2177                                  bounds,
   2178                                  true,
   2179                                  false);
   2180     clipping_layer->SetMasksToBounds(true);
   2181 
   2182     scoped_ptr<LayerImpl> clipped_layer =
   2183         LayerImpl::Create(host_impl().active_tree(), clipped_layer_id);
   2184     position = gfx::PointF();
   2185     bounds = gfx::Size(100, 100);
   2186     SetLayerPropertiesForTesting(clipped_layer.get(),
   2187                                  identity_matrix,
   2188                                  transform_origin,
   2189                                  position,
   2190                                  bounds,
   2191                                  true,
   2192                                  false);
   2193     clipped_layer->SetDrawsContent(true);
   2194     clipping_layer->AddChild(clipped_layer.Pass());
   2195     root->AddChild(clipping_layer.Pass());
   2196   }
   2197 
   2198   host_impl().SetViewportSize(root->bounds());
   2199   host_impl().active_tree()->SetRootLayer(root.Pass());
   2200   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   2201 
   2202   // Sanity check the scenario we just created.
   2203   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   2204 
   2205   LayerSelectionBound left_input;
   2206   left_input.type = SELECTION_BOUND_LEFT;
   2207   left_input.edge_top = gfx::PointF(25, 10);
   2208   left_input.edge_bottom = gfx::PointF(25, 30);
   2209   left_input.layer_id = clipped_layer_id;
   2210 
   2211   LayerSelectionBound right_input;
   2212   right_input.type = SELECTION_BOUND_RIGHT;
   2213   right_input.edge_top = gfx::PointF(75, 10);
   2214   right_input.edge_bottom = gfx::PointF(75, 30);
   2215   right_input.layer_id = clipped_layer_id;
   2216   host_impl().active_tree()->RegisterSelection(left_input, right_input);
   2217 
   2218   // The left bound should be occluded by the clip layer.
   2219   ViewportSelectionBound left_output, right_output;
   2220   host_impl().active_tree()->GetViewportSelection(&left_output, &right_output);
   2221   EXPECT_EQ(left_input.type, left_output.type);
   2222   gfx::PointF expected_left_output_top = left_input.edge_top;
   2223   gfx::PointF expected_left_output_bottom = left_input.edge_bottom;
   2224   expected_left_output_top.Offset(clipping_offset.x(), clipping_offset.y());
   2225   expected_left_output_bottom.Offset(clipping_offset.x(), clipping_offset.y());
   2226   EXPECT_EQ(expected_left_output_top, left_output.edge_top);
   2227   EXPECT_EQ(expected_left_output_bottom, left_output.edge_bottom);
   2228   EXPECT_TRUE(left_output.visible);
   2229   EXPECT_EQ(right_input.type, right_output.type);
   2230   gfx::PointF expected_right_output_top = right_input.edge_top;
   2231   gfx::PointF expected_right_output_bottom = right_input.edge_bottom;
   2232   expected_right_output_bottom.Offset(clipping_offset.x(), clipping_offset.y());
   2233   expected_right_output_top.Offset(clipping_offset.x(), clipping_offset.y());
   2234   EXPECT_EQ(expected_right_output_top, right_output.edge_top);
   2235   EXPECT_EQ(expected_right_output_bottom, right_output.edge_bottom);
   2236   EXPECT_FALSE(right_output.visible);
   2237 
   2238   // Handles outside the viewport bounds should be marked invisible.
   2239   left_input.edge_top = gfx::PointF(-25, 0);
   2240   left_input.edge_bottom = gfx::PointF(-25, 20);
   2241   host_impl().active_tree()->RegisterSelection(left_input, right_input);
   2242   host_impl().active_tree()->GetViewportSelection(&left_output, &right_output);
   2243   EXPECT_FALSE(left_output.visible);
   2244 
   2245   left_input.edge_top = gfx::PointF(0, -25);
   2246   left_input.edge_bottom = gfx::PointF(0, -5);
   2247   host_impl().active_tree()->RegisterSelection(left_input, right_input);
   2248   host_impl().active_tree()->GetViewportSelection(&left_output, &right_output);
   2249   EXPECT_FALSE(left_output.visible);
   2250 
   2251   // If the handle bottom is partially visible, the handle is marked visible.
   2252   left_input.edge_top = gfx::PointF(0, -20);
   2253   left_input.edge_bottom = gfx::PointF(0, 1);
   2254   host_impl().active_tree()->RegisterSelection(left_input, right_input);
   2255   host_impl().active_tree()->GetViewportSelection(&left_output, &right_output);
   2256   EXPECT_TRUE(left_output.visible);
   2257 }
   2258 
   2259 TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) {
   2260   int root_layer_id = 1;
   2261   int sub_layer_id = 2;
   2262   scoped_ptr<LayerImpl> root =
   2263       LayerImpl::Create(host_impl().active_tree(), root_layer_id);
   2264   root->SetDrawsContent(true);
   2265 
   2266   gfx::Transform identity_matrix;
   2267   gfx::Point3F transform_origin;
   2268   gfx::PointF position;
   2269   gfx::Size bounds(100, 100);
   2270   SetLayerPropertiesForTesting(root.get(),
   2271                                identity_matrix,
   2272                                transform_origin,
   2273                                position,
   2274                                bounds,
   2275                                true,
   2276                                false);
   2277 
   2278   gfx::Vector2dF sub_layer_offset(10, 0);
   2279   {
   2280     scoped_ptr<LayerImpl> sub_layer =
   2281         LayerImpl::Create(host_impl().active_tree(), sub_layer_id);
   2282     gfx::PointF position = gfx::PointF() + sub_layer_offset;
   2283     gfx::Size bounds(50, 50);
   2284     SetLayerPropertiesForTesting(sub_layer.get(),
   2285                                  identity_matrix,
   2286                                  transform_origin,
   2287                                  position,
   2288                                  bounds,
   2289                                  true,
   2290                                  false);
   2291     sub_layer->SetDrawsContent(true);
   2292     root->AddChild(sub_layer.Pass());
   2293   }
   2294 
   2295   float device_scale_factor = 3.f;
   2296   float page_scale_factor = 5.f;
   2297   gfx::Size scaled_bounds_for_root = gfx::ToCeiledSize(
   2298       gfx::ScaleSize(root->bounds(), device_scale_factor * page_scale_factor));
   2299   host_impl().SetViewportSize(scaled_bounds_for_root);
   2300 
   2301   host_impl().SetDeviceScaleFactor(device_scale_factor);
   2302   host_impl().active_tree()->SetPageScaleFactorAndLimits(
   2303       page_scale_factor, page_scale_factor, page_scale_factor);
   2304   host_impl().active_tree()->SetRootLayer(root.Pass());
   2305   host_impl().active_tree()->SetViewportLayersFromIds(1, 1, Layer::INVALID_ID);
   2306   host_impl().UpdateNumChildrenAndDrawPropertiesForActiveTree();
   2307 
   2308   // Sanity check the scenario we just created.
   2309   ASSERT_EQ(1u, RenderSurfaceLayerList().size());
   2310 
   2311   LayerSelectionBound left_input;
   2312   left_input.type = SELECTION_BOUND_LEFT;
   2313   left_input.edge_top = gfx::PointF(10, 10);
   2314   left_input.edge_bottom = gfx::PointF(10, 30);
   2315   left_input.layer_id = root_layer_id;
   2316 
   2317   LayerSelectionBound right_input;
   2318   right_input.type = SELECTION_BOUND_RIGHT;
   2319   right_input.edge_top = gfx::PointF(0, 0);
   2320   right_input.edge_bottom = gfx::PointF(0, 20);
   2321   right_input.layer_id = sub_layer_id;
   2322   host_impl().active_tree()->RegisterSelection(left_input, right_input);
   2323 
   2324   // The viewport bounds should be properly scaled by the page scale, but should
   2325   // remain in DIP coordinates.
   2326   ViewportSelectionBound left_output, right_output;
   2327   host_impl().active_tree()->GetViewportSelection(&left_output, &right_output);
   2328   EXPECT_EQ(left_input.type, left_output.type);
   2329   gfx::PointF expected_left_output_top = left_input.edge_top;
   2330   gfx::PointF expected_left_output_bottom = left_input.edge_bottom;
   2331   expected_left_output_top.Scale(page_scale_factor);
   2332   expected_left_output_bottom.Scale(page_scale_factor);
   2333   EXPECT_EQ(left_input.edge_top, left_output.edge_top);
   2334   EXPECT_EQ(left_input.edge_bottom, left_output.edge_bottom);
   2335   EXPECT_TRUE(left_output.visible);
   2336   EXPECT_EQ(right_input.type, right_output.type);
   2337 
   2338   gfx::PointF expected_right_output_top = right_input.edge_top;
   2339   gfx::PointF expected_right_output_bottom = right_input.edge_bottom;
   2340   expected_right_output_top.Offset(sub_layer_offset.x(), sub_layer_offset.y());
   2341   expected_right_output_bottom.Offset(sub_layer_offset.x(),
   2342                                       sub_layer_offset.y());
   2343   expected_right_output_top.Scale(page_scale_factor);
   2344   expected_right_output_bottom.Scale(page_scale_factor);
   2345   EXPECT_EQ(expected_right_output_top, right_output.edge_top);
   2346   EXPECT_EQ(expected_right_output_bottom, right_output.edge_bottom);
   2347   EXPECT_TRUE(right_output.visible);
   2348 }
   2349 
   2350 TEST_F(LayerTreeImplTest, NumLayersTestOne) {
   2351   EXPECT_EQ(0u, host_impl().active_tree()->NumLayers());
   2352   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
   2353   EXPECT_EQ(1u, host_impl().active_tree()->NumLayers());
   2354 }
   2355 
   2356 TEST_F(LayerTreeImplTest, NumLayersSmallTree) {
   2357   EXPECT_EQ(0u, host_impl().active_tree()->NumLayers());
   2358   scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl().active_tree(), 1);
   2359   root->AddChild(LayerImpl::Create(host_impl().active_tree(), 2));
   2360   root->AddChild(LayerImpl::Create(host_impl().active_tree(), 3));
   2361   root->child_at(1)->AddChild(LayerImpl::Create(host_impl().active_tree(), 4));
   2362   EXPECT_EQ(4u, host_impl().active_tree()->NumLayers());
   2363 }
   2364 
   2365 }  // namespace
   2366 }  // namespace cc
   2367