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 "base/numerics/ranges.h"
8 #include "cc/layers/heads_up_display_layer_impl.h"
9 #include "cc/test/fake_layer_tree_host_impl.h"
10 #include "cc/test/fake_raster_source.h"
11 #include "cc/test/geometry_test_utils.h"
12 #include "cc/test/layer_tree_impl_test_base.h"
13 #include "cc/trees/clip_node.h"
14 #include "cc/trees/draw_property_utils.h"
15 #include "cc/trees/layer_tree_host_impl.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 namespace cc {
20 namespace {
21 
GetVisibleSelectionEndPoints(const gfx::RectF & rect,const gfx::PointF & top,const gfx::PointF & bottom)22 std::pair<gfx::PointF, gfx::PointF> GetVisibleSelectionEndPoints(
23     const gfx::RectF& rect,
24     const gfx::PointF& top,
25     const gfx::PointF& bottom) {
26   gfx::PointF start(base::ClampToRange(top.x(), rect.x(), rect.right()),
27                     base::ClampToRange(top.y(), rect.y(), rect.bottom()));
28   gfx::PointF end =
29       start + gfx::Vector2dF(bottom.x() - top.x(), bottom.y() - top.y());
30   return {start, end};
31 }
32 
33 class LayerTreeImplTest : public LayerTreeImplTestBase, public testing::Test {
34  public:
35   LayerTreeImplTest() = default;
LayerTreeImplTest(const LayerTreeSettings & settings)36   explicit LayerTreeImplTest(const LayerTreeSettings& settings)
37       : LayerTreeImplTestBase(settings) {}
38 
SetUp()39   void SetUp() override {
40     root_layer()->SetBounds(gfx::Size(100, 100));
41     UpdateDrawProperties(host_impl().active_tree());
42   }
43 
host_impl() const44   FakeLayerTreeHostImpl& host_impl() const {
45     return *LayerTreeImplTestBase::host_impl();
46   }
47 
GetRenderSurfaceList() const48   const RenderSurfaceList& GetRenderSurfaceList() const {
49     return host_impl().active_tree()->GetRenderSurfaceList();
50   }
51 
HitTestSimpleTree(int top_sorting_context,int left_child_sorting_context,int right_child_sorting_context,float top_depth,float left_child_depth,float right_child_depth)52   LayerImpl* HitTestSimpleTree(int top_sorting_context,
53                                int left_child_sorting_context,
54                                int right_child_sorting_context,
55                                float top_depth,
56                                float left_child_depth,
57                                float right_child_depth) {
58     top_ = AddLayer<LayerImpl>();
59     left_child_ = AddLayer<LayerImpl>();
60     right_child_ = AddLayer<LayerImpl>();
61 
62     gfx::Size bounds(100, 100);
63     {
64       gfx::Transform translate_z;
65       translate_z.Translate3d(0, 0, top_depth);
66       top_->SetBounds(bounds);
67       top_->SetDrawsContent(true);
68       top_->SetHitTestable(true);
69 
70       CopyProperties(root_layer(), top_);
71       auto& transform_node = CreateTransformNode(top_);
72       transform_node.local = translate_z;
73       transform_node.sorting_context_id = top_sorting_context;
74     }
75     {
76       gfx::Transform translate_z;
77       translate_z.Translate3d(0, 0, left_child_depth);
78       left_child_->SetBounds(bounds);
79       left_child_->SetDrawsContent(true);
80       left_child_->SetHitTestable(true);
81 
82       CopyProperties(top_, left_child_);
83       auto& transform_node = CreateTransformNode(left_child_);
84       transform_node.local = translate_z;
85       transform_node.sorting_context_id = left_child_sorting_context;
86       transform_node.flattens_inherited_transform = false;
87     }
88     {
89       gfx::Transform translate_z;
90       translate_z.Translate3d(0, 0, right_child_depth);
91       right_child_->SetBounds(bounds);
92       right_child_->SetDrawsContent(true);
93       right_child_->SetHitTestable(true);
94 
95       CopyProperties(top_, right_child_);
96       auto& transform_node = CreateTransformNode(right_child_);
97       transform_node.local = translate_z;
98       transform_node.sorting_context_id = right_child_sorting_context;
99     }
100 
101     root_layer()->SetBounds(top_->bounds());
102     host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(top_->bounds()));
103 
104     UpdateDrawProperties(host_impl().active_tree());
105     CHECK_EQ(1u, GetRenderSurfaceList().size());
106 
107     gfx::PointF test_point = gfx::PointF(1.f, 1.f);
108     LayerImpl* result_layer =
109         host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
110 
111     CHECK(result_layer);
112     return result_layer;
113   }
114 
115   // These layers are created by HitTestSimpleTree().
116   LayerImpl* top_ = nullptr;
117   LayerImpl* left_child_ = nullptr;
118   LayerImpl* right_child_ = nullptr;
119 };
120 
TEST_F(LayerTreeImplTest,HitTestingForSingleLayer)121 TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) {
122   gfx::Size bounds(100, 100);
123   LayerImpl* root = root_layer();
124   root->SetBounds(bounds);
125   root->SetDrawsContent(true);
126   root->SetHitTestable(true);
127 
128   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
129   UpdateDrawProperties(host_impl().active_tree());
130 
131   // Sanity check the scenario we just created.
132   ASSERT_EQ(1u, GetRenderSurfaceList().size());
133   ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());
134 
135   // Hit testing for a point outside the layer should return a null pointer.
136   gfx::PointF test_point(101.f, 101.f);
137   LayerImpl* result_layer =
138       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
139   EXPECT_FALSE(result_layer);
140 
141   test_point = gfx::PointF(-1.f, -1.f);
142   result_layer =
143       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
144   EXPECT_FALSE(result_layer);
145 
146   // Hit testing for a point inside should return the root layer.
147   test_point = gfx::PointF(1.f, 1.f);
148   result_layer =
149       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
150   ASSERT_TRUE(result_layer);
151   EXPECT_EQ(root, result_layer);
152 
153   test_point = gfx::PointF(99.f, 99.f);
154   result_layer =
155       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
156   ASSERT_TRUE(result_layer);
157   EXPECT_EQ(root, result_layer);
158 }
159 
TEST_F(LayerTreeImplTest,UpdateViewportAndHitTest)160 TEST_F(LayerTreeImplTest, UpdateViewportAndHitTest) {
161   // Ensures that the viewport rect is correctly updated by the clip tree.
162   gfx::Size bounds(100, 100);
163   LayerImpl* root = root_layer();
164   root->SetBounds(bounds);
165   root->SetDrawsContent(true);
166   root->SetHitTestable(true);
167 
168   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
169   UpdateDrawProperties(host_impl().active_tree());
170   EXPECT_EQ(
171       gfx::RectF(gfx::SizeF(bounds)),
172       host_impl().active_tree()->property_trees()->clip_tree.ViewportClip());
173   EXPECT_EQ(gfx::Rect(bounds), root->visible_layer_rect());
174 
175   gfx::Size new_bounds(50, 50);
176   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(new_bounds));
177   gfx::PointF test_point(51.f, 51.f);
178   host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
179   EXPECT_EQ(
180       gfx::RectF(gfx::SizeF(new_bounds)),
181       host_impl().active_tree()->property_trees()->clip_tree.ViewportClip());
182   EXPECT_EQ(gfx::Rect(new_bounds), root->visible_layer_rect());
183 }
184 
TEST_F(LayerTreeImplTest,HitTestingForSingleLayerAndHud)185 TEST_F(LayerTreeImplTest, HitTestingForSingleLayerAndHud) {
186   LayerImpl* root = root_layer();
187   root->SetBounds(gfx::Size(100, 100));
188   root->SetDrawsContent(true);
189   root->SetHitTestable(true);
190 
191   // Create hud and add it as a child of root.
192   auto* hud = AddLayer<HeadsUpDisplayLayerImpl>();
193   hud->SetBounds(gfx::Size(200, 200));
194   hud->SetDrawsContent(true);
195   hud->SetHitTestable(true);
196 
197   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(hud->bounds()));
198   host_impl().active_tree()->set_hud_layer(hud);
199   CopyProperties(root, hud);
200   UpdateDrawProperties(host_impl().active_tree());
201 
202   // Sanity check the scenario we just created.
203   ASSERT_EQ(1u, GetRenderSurfaceList().size());
204   ASSERT_EQ(2, GetRenderSurface(root_layer())->num_contributors());
205 
206   // Hit testing for a point inside HUD, but outside root should return null
207   gfx::PointF test_point(101.f, 101.f);
208   LayerImpl* result_layer =
209       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
210   EXPECT_FALSE(result_layer);
211 
212   test_point = gfx::PointF(-1.f, -1.f);
213   result_layer =
214       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
215   EXPECT_FALSE(result_layer);
216 
217   // Hit testing for a point inside should return the root layer, never the HUD
218   // layer.
219   test_point = gfx::PointF(1.f, 1.f);
220   result_layer =
221       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
222   ASSERT_TRUE(result_layer);
223   EXPECT_EQ(root, result_layer);
224 
225   test_point = gfx::PointF(99.f, 99.f);
226   result_layer =
227       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
228   ASSERT_TRUE(result_layer);
229   EXPECT_EQ(root, result_layer);
230 }
231 
TEST_F(LayerTreeImplTest,HitTestingForUninvertibleTransform)232 TEST_F(LayerTreeImplTest, HitTestingForUninvertibleTransform) {
233   gfx::Transform uninvertible_transform;
234   uninvertible_transform.matrix().set(0, 0, 0.0);
235   uninvertible_transform.matrix().set(1, 1, 0.0);
236   uninvertible_transform.matrix().set(2, 2, 0.0);
237   uninvertible_transform.matrix().set(3, 3, 0.0);
238   ASSERT_FALSE(uninvertible_transform.IsInvertible());
239 
240   LayerImpl* root = root_layer();
241 
242   LayerImpl* layer = AddLayer<LayerImpl>();
243   layer->SetBounds(gfx::Size(100, 100));
244   layer->SetDrawsContent(true);
245   layer->SetHitTestable(true);
246   root->SetBounds(layer->bounds());
247   CopyProperties(root, layer);
248   CreateTransformNode(layer).local = uninvertible_transform;
249 
250   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
251   UpdateDrawProperties(host_impl().active_tree());
252   // Sanity check the scenario we just created.
253   ASSERT_EQ(1u, GetRenderSurfaceList().size());
254   ASSERT_FALSE(layer->ScreenSpaceTransform().IsInvertible());
255 
256   // Hit testing any point should not hit the layer. If the invertible matrix is
257   // accidentally ignored and treated like an identity, then the hit testing
258   // will incorrectly hit the layer when it shouldn't.
259   gfx::PointF test_point(1.f, 1.f);
260   LayerImpl* result_layer =
261       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
262   EXPECT_FALSE(result_layer);
263 
264   test_point = gfx::PointF(10.f, 10.f);
265   result_layer =
266       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
267   EXPECT_FALSE(result_layer);
268 
269   test_point = gfx::PointF(10.f, 30.f);
270   result_layer =
271       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
272   EXPECT_FALSE(result_layer);
273 
274   test_point = gfx::PointF(50.f, 50.f);
275   result_layer =
276       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
277   EXPECT_FALSE(result_layer);
278 
279   test_point = gfx::PointF(67.f, 48.f);
280   result_layer =
281       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
282   EXPECT_FALSE(result_layer);
283 
284   test_point = gfx::PointF(99.f, 99.f);
285   result_layer =
286       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
287   EXPECT_FALSE(result_layer);
288 
289   test_point = gfx::PointF(-1.f, -1.f);
290   result_layer =
291       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
292   EXPECT_FALSE(result_layer);
293 }
294 
TEST_F(LayerTreeImplTest,HitTestingForSinglePositionedLayer)295 TEST_F(LayerTreeImplTest, HitTestingForSinglePositionedLayer) {
296   // This layer is positioned, and hit testing should correctly know where the
297   // layer is located.
298   LayerImpl* test_layer = AddLayer<LayerImpl>();
299   test_layer->SetBounds(gfx::Size(100, 100));
300   test_layer->SetDrawsContent(true);
301   test_layer->SetHitTestable(true);
302   CopyProperties(root_layer(), test_layer);
303   test_layer->SetOffsetToTransformParent(gfx::Vector2dF(50.f, 50.f));
304 
305   host_impl().active_tree()->SetDeviceViewportRect(
306       gfx::Rect(test_layer->bounds()));
307   UpdateDrawProperties(host_impl().active_tree());
308 
309   // Sanity check the scenario we just created.
310   ASSERT_EQ(1u, GetRenderSurfaceList().size());
311   ASSERT_EQ(1, GetRenderSurface(test_layer)->num_contributors());
312 
313   // Hit testing for a point outside the layer should return a null pointer.
314   gfx::PointF test_point(49.f, 49.f);
315   LayerImpl* result_layer =
316       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
317   EXPECT_FALSE(result_layer);
318 
319   // Even though the layer exists at (101, 101), it should not be visible there
320   // since the root render surface would clamp it.
321   test_point = gfx::PointF(101.f, 101.f);
322   result_layer =
323       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
324   EXPECT_FALSE(result_layer);
325 
326   // Hit testing for a point inside should return the root layer.
327   test_point = gfx::PointF(51.f, 51.f);
328   result_layer =
329       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
330   ASSERT_TRUE(result_layer);
331   EXPECT_EQ(test_layer, result_layer);
332 
333   test_point = gfx::PointF(99.f, 99.f);
334   result_layer =
335       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
336   ASSERT_TRUE(result_layer);
337   EXPECT_EQ(test_layer, result_layer);
338 }
339 
TEST_F(LayerTreeImplTest,HitTestingForSingleRotatedLayer)340 TEST_F(LayerTreeImplTest, HitTestingForSingleRotatedLayer) {
341   LayerImpl* root = root_layer();
342 
343   gfx::Transform rotation45_degrees_about_center;
344   rotation45_degrees_about_center.Translate(50.0, 50.0);
345   rotation45_degrees_about_center.RotateAboutZAxis(45.0);
346   rotation45_degrees_about_center.Translate(-50.0, -50.0);
347 
348   LayerImpl* layer = AddLayer<LayerImpl>();
349   layer->SetBounds(gfx::Size(100, 100));
350   layer->SetDrawsContent(true);
351   layer->SetHitTestable(true);
352   root->SetBounds(layer->bounds());
353   CopyProperties(root, layer);
354   CreateTransformNode(layer).local = rotation45_degrees_about_center;
355 
356   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
357   UpdateDrawProperties(host_impl().active_tree());
358 
359   // Sanity check the scenario we just created.
360   ASSERT_EQ(1u, GetRenderSurfaceList().size());
361   ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());
362 
363   // Hit testing for points outside the layer.
364   // These corners would have been inside the un-transformed layer, but they
365   // should not hit the correctly transformed layer.
366   gfx::PointF test_point(99.f, 99.f);
367   LayerImpl* result_layer =
368       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
369   EXPECT_FALSE(result_layer);
370 
371   test_point = gfx::PointF(1.f, 1.f);
372   result_layer =
373       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
374   EXPECT_FALSE(result_layer);
375 
376   // Hit testing for a point inside should return the root layer.
377   test_point = gfx::PointF(1.f, 50.f);
378   result_layer =
379       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
380   ASSERT_TRUE(result_layer);
381   EXPECT_EQ(layer, result_layer);
382 
383   // Hit testing the corners that would overlap the unclipped layer, but are
384   // outside the clipped region.
385   test_point = gfx::PointF(50.f, -1.f);
386   result_layer =
387       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
388   ASSERT_FALSE(result_layer);
389 
390   test_point = gfx::PointF(-1.f, 50.f);
391   result_layer =
392       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
393   ASSERT_FALSE(result_layer);
394 }
395 
TEST_F(LayerTreeImplTest,HitTestingClipNodeDifferentTransformAndTargetIds)396 TEST_F(LayerTreeImplTest, HitTestingClipNodeDifferentTransformAndTargetIds) {
397   // Tests hit testing on a layer whose clip node has different transform and
398   // target id.
399   LayerImpl* root = root_layer();
400   root->SetBounds(gfx::Size(500, 500));
401 
402   gfx::Transform translation;
403   translation.Translate(100, 100);
404   LayerImpl* render_surface = AddLayer<LayerImpl>();
405   render_surface->SetBounds(gfx::Size(100, 100));
406   CopyProperties(root, render_surface);
407   CreateTransformNode(render_surface).local = translation;
408   CreateEffectNode(render_surface).render_surface_reason =
409       RenderSurfaceReason::kTest;
410 
411   gfx::Transform scale_matrix;
412   scale_matrix.Scale(2, 2);
413   LayerImpl* scale = AddLayer<LayerImpl>();
414   scale->SetBounds(gfx::Size(50, 50));
415   CopyProperties(render_surface, scale);
416   CreateTransformNode(scale).local = scale_matrix;
417 
418   LayerImpl* clip = AddLayer<LayerImpl>();
419   clip->SetBounds(gfx::Size(25, 25));
420   CopyProperties(scale, clip);
421   CreateClipNode(clip);
422 
423   LayerImpl* test = AddLayer<LayerImpl>();
424   test->SetBounds(gfx::Size(100, 100));
425   test->SetDrawsContent(true);
426   test->SetHitTestable(true);
427   CopyProperties(clip, test);
428 
429   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
430   UpdateDrawProperties(host_impl().active_tree());
431 
432   gfx::PointF test_point(160.f, 160.f);
433   LayerImpl* result_layer =
434       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
435   EXPECT_FALSE(result_layer);
436 
437   test_point = gfx::PointF(140.f, 140.f);
438   result_layer =
439       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
440   ASSERT_TRUE(result_layer);
441   EXPECT_EQ(test, result_layer);
442 }
443 
TEST_F(LayerTreeImplTest,HitTestingSiblings)444 TEST_F(LayerTreeImplTest, HitTestingSiblings) {
445   // This tests hit testing when the test point hits only one of the siblings.
446   LayerImpl* root = root_layer();
447   root->SetBounds(gfx::Size(100, 100));
448 
449   LayerImpl* child1 = AddLayer<LayerImpl>();
450   child1->SetBounds(gfx::Size(25, 25));
451   child1->SetDrawsContent(true);
452   child1->SetHitTestable(true);
453   CopyProperties(root, child1);
454   CreateClipNode(child1);
455 
456   LayerImpl* child2 = AddLayer<LayerImpl>();
457   child2->SetBounds(gfx::Size(75, 75));
458   child2->SetDrawsContent(true);
459   child2->SetHitTestable(true);
460   CopyProperties(root, child2);
461   CreateClipNode(child2);
462 
463   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
464   UpdateDrawProperties(host_impl().active_tree());
465 
466   gfx::PointF test_point(50.f, 50.f);
467   LayerImpl* result_layer =
468       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
469   ASSERT_TRUE(result_layer);
470   EXPECT_EQ(child2, result_layer);
471 }
472 
TEST_F(LayerTreeImplTest,HitTestingForSinglePerspectiveLayer)473 TEST_F(LayerTreeImplTest, HitTestingForSinglePerspectiveLayer) {
474   LayerImpl* root = root_layer();
475 
476   // perspective_projection_about_center * translation_by_z is designed so
477   // that the 100 x 100 layer becomes 50 x 50, and remains centered at (50,
478   // 50).
479   gfx::Transform perspective_projection_about_center;
480   perspective_projection_about_center.Translate(50.0, 50.0);
481   perspective_projection_about_center.ApplyPerspectiveDepth(1.0);
482   perspective_projection_about_center.Translate(-50.0, -50.0);
483   gfx::Transform translation_by_z;
484   translation_by_z.Translate3d(0.0, 0.0, -1.0);
485 
486   LayerImpl* layer = AddLayer<LayerImpl>();
487   layer->SetBounds(gfx::Size(100, 100));
488   layer->SetDrawsContent(true);
489   layer->SetHitTestable(true);
490   root->SetBounds(layer->bounds());
491   CopyProperties(root, layer);
492   CreateTransformNode(layer).local =
493       (perspective_projection_about_center * translation_by_z);
494 
495   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
496   UpdateDrawProperties(host_impl().active_tree());
497 
498   // Sanity check the scenario we just created.
499   ASSERT_EQ(1u, GetRenderSurfaceList().size());
500   ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());
501 
502   // Hit testing for points outside the layer.
503   // These corners would have been inside the un-transformed layer, but they
504   // should not hit the correctly transformed layer.
505   gfx::PointF test_point(24.f, 24.f);
506   LayerImpl* result_layer =
507       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
508   EXPECT_FALSE(result_layer);
509 
510   test_point = gfx::PointF(76.f, 76.f);
511   result_layer =
512       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
513   EXPECT_FALSE(result_layer);
514 
515   // Hit testing for a point inside should return the root layer.
516   test_point = gfx::PointF(26.f, 26.f);
517   result_layer =
518       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
519   EXPECT_EQ(layer, result_layer);
520 
521   test_point = gfx::PointF(74.f, 74.f);
522   result_layer =
523       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
524   EXPECT_EQ(layer, result_layer);
525 }
526 
TEST_F(LayerTreeImplTest,HitTestingForSimpleClippedLayer)527 TEST_F(LayerTreeImplTest, HitTestingForSimpleClippedLayer) {
528   // Test that hit-testing will only work for the visible portion of a layer,
529   // and not the entire layer bounds. Here we just test the simple axis-aligned
530   // case.
531   LayerImpl* root = root_layer();
532   root->SetBounds(gfx::Size(100, 100));
533 
534   LayerImpl* clipping_layer = AddLayer<LayerImpl>();
535   // this layer is positioned, and hit testing should correctly know where the
536   // layer is located.
537   clipping_layer->SetBounds(gfx::Size(50, 50));
538   CopyProperties(root, clipping_layer);
539   clipping_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 25.f));
540   CreateClipNode(clipping_layer);
541 
542   LayerImpl* child = AddLayer<LayerImpl>();
543   child->SetBounds(gfx::Size(300, 300));
544   child->SetDrawsContent(true);
545   child->SetHitTestable(true);
546   CopyProperties(clipping_layer, child);
547   child->SetOffsetToTransformParent(gfx::Vector2dF(-50.f, -50.f));
548 
549   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
550   UpdateDrawProperties(host_impl().active_tree());
551 
552   // Sanity check the scenario we just created.
553   ASSERT_EQ(1u, GetRenderSurfaceList().size());
554   ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());
555   EXPECT_TRUE(child->contributes_to_drawn_render_surface());
556 
557   // Hit testing for a point outside the layer should return a null pointer.
558   // Despite the child layer being very large, it should be clipped to the root
559   // layer's bounds.
560   gfx::PointF test_point(24.f, 24.f);
561   LayerImpl* result_layer =
562       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
563   EXPECT_FALSE(result_layer);
564 
565   // Even though the layer exists at (101, 101), it should not be visible there
566   // since the clipping_layer would clamp it.
567   test_point = gfx::PointF(76.f, 76.f);
568   result_layer =
569       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
570   EXPECT_FALSE(result_layer);
571 
572   // Hit testing for a point inside should return the child layer.
573   test_point = gfx::PointF(26.f, 26.f);
574   result_layer =
575       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
576   EXPECT_EQ(child, result_layer);
577 
578   test_point = gfx::PointF(74.f, 74.f);
579   result_layer =
580       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
581   EXPECT_EQ(child, result_layer);
582 }
583 
TEST_F(LayerTreeImplTest,HitTestingForMultiClippedRotatedLayer)584 TEST_F(LayerTreeImplTest, HitTestingForMultiClippedRotatedLayer) {
585   // This test checks whether hit testing correctly avoids hit testing with
586   // multiple ancestors that clip in non axis-aligned ways. To pass this test,
587   // the hit testing algorithm needs to recognize that multiple parent layers
588   // may clip the layer, and should not actually hit those clipped areas.
589   //
590   // The child and grand_child layers are both initialized to clip the
591   // rotated_leaf. The child layer is rotated about the top-left corner, so that
592   // the root + child clips combined create a triangle. The rotated_leaf will
593   // only be visible where it overlaps this triangle.
594   //
595   LayerImpl* root = root_layer();
596 
597   root->SetBounds(gfx::Size(100, 100));
598   CreateClipNode(root);
599 
600   // Visible rects computed by combinig clips in target space and root space
601   // don't match because of rotation transforms. So, we skip
602   // verify_visible_rect_calculations.
603   LayerImpl* child = AddLayer<LayerImpl>();
604   LayerImpl* grand_child = AddLayer<LayerImpl>();
605   LayerImpl* rotated_leaf = AddLayer<LayerImpl>();
606 
607   child->SetBounds(gfx::Size(80, 80));
608   CopyProperties(root, child);
609   child->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f));
610   CreateClipNode(child);
611 
612   gfx::Transform rotation45_degrees_about_corner;
613   rotation45_degrees_about_corner.RotateAboutZAxis(45.0);
614 
615   // This is positioned with respect to its parent which is already at
616   // position (10, 10).
617   // The size is to ensure it covers at least sqrt(2) * 100.
618   grand_child->SetBounds(gfx::Size(200, 200));
619   CopyProperties(child, grand_child);
620   CreateTransformNode(grand_child).local = rotation45_degrees_about_corner;
621   CreateClipNode(grand_child);
622 
623   // Rotates about the center of the layer
624   gfx::Transform rotated_leaf_transform;
625   rotated_leaf_transform.Translate(
626       -10.0, -10.0);  // cancel out the grand_parent's position
627   rotated_leaf_transform.RotateAboutZAxis(
628       -45.0);  // cancel out the corner 45-degree rotation of the parent.
629   rotated_leaf_transform.Translate(50.0, 50.0);
630   rotated_leaf_transform.RotateAboutZAxis(45.0);
631   rotated_leaf_transform.Translate(-50.0, -50.0);
632   rotated_leaf->SetBounds(gfx::Size(100, 100));
633   rotated_leaf->SetDrawsContent(true);
634   rotated_leaf->SetHitTestable(true);
635   CopyProperties(grand_child, rotated_leaf);
636   CreateTransformNode(rotated_leaf).local = rotated_leaf_transform;
637 
638   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
639   UpdateDrawProperties(host_impl().active_tree());
640   // (11, 89) is close to the the bottom left corner within the clip, but it is
641   // not inside the layer.
642   gfx::PointF test_point(11.f, 89.f);
643   LayerImpl* result_layer =
644       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
645   EXPECT_FALSE(result_layer);
646 
647   // Closer inwards from the bottom left will overlap the layer.
648   test_point = gfx::PointF(25.f, 75.f);
649   result_layer =
650       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
651   EXPECT_EQ(rotated_leaf, result_layer);
652 
653   // (4, 50) is inside the unclipped layer, but that corner of the layer should
654   // be clipped away by the grandparent and should not get hit. If hit testing
655   // blindly uses visible content rect without considering how parent may clip
656   // the layer, then hit testing would accidentally think that the point
657   // successfully hits the layer.
658   test_point = gfx::PointF(4.f, 50.f);
659   result_layer =
660       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
661   EXPECT_FALSE(result_layer);
662 
663   // (11, 50) is inside the layer and within the clipped area.
664   test_point = gfx::PointF(11.f, 50.f);
665   result_layer =
666       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
667   EXPECT_EQ(rotated_leaf, result_layer);
668 
669   // Around the middle, just to the right and up, would have hit the layer
670   // except that that area should be clipped away by the parent.
671   test_point = gfx::PointF(51.f, 49.f);
672   result_layer =
673       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
674   EXPECT_FALSE(result_layer);
675 
676   // Around the middle, just to the left and down, should successfully hit the
677   // layer.
678   test_point = gfx::PointF(49.f, 51.f);
679   result_layer =
680       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
681   EXPECT_EQ(rotated_leaf, result_layer);
682 }
683 
TEST_F(LayerTreeImplTest,HitTestingForNonClippingIntermediateLayer)684 TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) {
685   // This test checks that hit testing code does not accidentally clip to layer
686   // bounds for a layer that actually does not clip.
687 
688   LayerImpl* root = root_layer();
689   root->SetBounds(gfx::Size(100, 100));
690 
691   LayerImpl* intermediate_layer = AddLayer<LayerImpl>();
692   intermediate_layer->SetBounds(gfx::Size(50, 50));
693   CopyProperties(root, intermediate_layer);
694   // this layer is positioned, and hit testing should correctly know where the
695   // layer is located.
696   intermediate_layer->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f));
697 
698   // The child of the intermediate_layer is translated so that it does not
699   // overlap intermediate_layer at all.  If child is incorrectly clipped, we
700   // would not be able to hit it successfully.
701   LayerImpl* child = AddLayer<LayerImpl>();
702   child->SetBounds(gfx::Size(20, 20));
703   child->SetDrawsContent(true);
704   child->SetHitTestable(true);
705   CopyProperties(intermediate_layer, child);
706   child->SetOffsetToTransformParent(gfx::Vector2dF(70.f, 70.f));
707 
708   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
709   UpdateDrawProperties(host_impl().active_tree());
710 
711   // Sanity check the scenario we just created.
712   ASSERT_EQ(1u, GetRenderSurfaceList().size());
713   ASSERT_EQ(1, GetRenderSurface(root_layer())->num_contributors());
714   EXPECT_TRUE(child->contributes_to_drawn_render_surface());
715 
716   // Hit testing for a point outside the layer should return a null pointer.
717   gfx::PointF test_point(69.f, 69.f);
718   LayerImpl* result_layer =
719       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
720   EXPECT_FALSE(result_layer);
721 
722   test_point = gfx::PointF(91.f, 91.f);
723   result_layer =
724       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
725   EXPECT_FALSE(result_layer);
726 
727   // Hit testing for a point inside should return the child layer.
728   test_point = gfx::PointF(71.f, 71.f);
729   result_layer =
730       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
731   EXPECT_EQ(child, result_layer);
732 
733   test_point = gfx::PointF(89.f, 89.f);
734   result_layer =
735       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
736   EXPECT_EQ(child, result_layer);
737 }
738 
TEST_F(LayerTreeImplTest,HitTestingForMultipleLayers)739 TEST_F(LayerTreeImplTest, HitTestingForMultipleLayers) {
740   LayerImpl* root = root_layer();
741   root->SetBounds(gfx::Size(100, 100));
742   root->SetDrawsContent(true);
743   root->SetHitTestable(true);
744 
745   // child1 and child2 are initialized to overlap between x=50 and x=60.
746   // grand_child is set to overlap both child1 and child2 between y=50 and
747   // y=60.  The expected stacking order is: (front) child2, (second)
748   // grand_child, (third) child1, and (back) the root layer behind all other
749   // layers.
750 
751   LayerImpl* child1 = AddLayer<LayerImpl>();
752   child1->SetBounds(gfx::Size(50, 50));
753   child1->SetDrawsContent(true);
754   child1->SetHitTestable(true);
755   CopyProperties(root, child1);
756   child1->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f));
757 
758   // Remember that grand_child is positioned with respect to its parent (i.e.
759   // child1).  In screen space, the intended position is (10, 50), with size
760   // 100 x 50.
761   LayerImpl* grand_child1 = AddLayer<LayerImpl>();
762   grand_child1->SetBounds(gfx::Size(100, 50));
763   grand_child1->SetDrawsContent(true);
764   grand_child1->SetHitTestable(true);
765   CopyProperties(child1, grand_child1);
766   grand_child1->SetOffsetToTransformParent(
767       gfx::Vector2dF(0.f, 40.f) + child1->offset_to_transform_parent());
768 
769   LayerImpl* child2 = AddLayer<LayerImpl>();
770   child2->SetBounds(gfx::Size(50, 50));
771   child2->SetDrawsContent(true);
772   child2->SetHitTestable(true);
773   CopyProperties(root, child2);
774   child2->SetOffsetToTransformParent(gfx::Vector2dF(50.f, 10.f));
775 
776   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
777   UpdateDrawProperties(host_impl().active_tree());
778 
779   // Sanity check the scenario we just created.
780   ASSERT_TRUE(child1);
781   ASSERT_TRUE(child2);
782   ASSERT_TRUE(grand_child1);
783   ASSERT_EQ(1u, GetRenderSurfaceList().size());
784 
785   RenderSurfaceImpl* root_render_surface = GetRenderSurface(root);
786   ASSERT_EQ(4, root_render_surface->num_contributors());
787   EXPECT_TRUE(root_layer()->contributes_to_drawn_render_surface());
788   EXPECT_TRUE(child1->contributes_to_drawn_render_surface());
789   EXPECT_TRUE(child2->contributes_to_drawn_render_surface());
790   EXPECT_TRUE(grand_child1->contributes_to_drawn_render_surface());
791 
792   // Nothing overlaps the root at (1, 1), so hit testing there should find
793   // the root layer.
794   gfx::PointF test_point = gfx::PointF(1.f, 1.f);
795   LayerImpl* result_layer =
796       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
797   EXPECT_EQ(root, result_layer);
798 
799   // At (15, 15), child1 and root are the only layers. child1 is expected to be
800   // on top.
801   test_point = gfx::PointF(15.f, 15.f);
802   result_layer =
803       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
804   EXPECT_EQ(child1, result_layer);
805 
806   // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
807   test_point = gfx::PointF(51.f, 20.f);
808   result_layer =
809       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
810   EXPECT_EQ(child2, result_layer);
811 
812   // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
813   // top.
814   test_point = gfx::PointF(80.f, 51.f);
815   result_layer =
816       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
817   EXPECT_EQ(child2, result_layer);
818 
819   // At (51, 51), all layers overlap each other. child2 is expected to be on top
820   // of all other layers.
821   test_point = gfx::PointF(51.f, 51.f);
822   result_layer =
823       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
824   EXPECT_EQ(child2, result_layer);
825 
826   // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
827   // be on top.
828   test_point = gfx::PointF(20.f, 51.f);
829   result_layer =
830       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
831   EXPECT_EQ(grand_child1, result_layer);
832 }
833 
TEST_F(LayerTreeImplTest,HitTestingSameSortingContextTied)834 TEST_F(LayerTreeImplTest, HitTestingSameSortingContextTied) {
835   LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 10, 10, 10,
836                                            /* depths */ 0, 0, 0);
837   // 3 is the last in tree order, and so should be on top.
838   EXPECT_EQ(right_child_, hit_layer);
839 }
840 
TEST_F(LayerTreeImplTest,HitTestingSameSortingContextChildWins)841 TEST_F(LayerTreeImplTest, HitTestingSameSortingContextChildWins) {
842   LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 10, 10, 10,
843                                            /* depths */ 0, 1, 0);
844   EXPECT_EQ(left_child_, hit_layer);
845 }
846 
TEST_F(LayerTreeImplTest,HitTestingWithoutSortingContext)847 TEST_F(LayerTreeImplTest, HitTestingWithoutSortingContext) {
848   LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 0, 0, 0,
849                                            /* depths */ 0, 1, 0);
850   EXPECT_EQ(right_child_, hit_layer);
851 }
852 
TEST_F(LayerTreeImplTest,HitTestingDistinctSortingContext)853 TEST_F(LayerTreeImplTest, HitTestingDistinctSortingContext) {
854   LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 10, 11, 12,
855                                            /* depths */ 0, 1, 0);
856   EXPECT_EQ(right_child_, hit_layer);
857 }
858 
TEST_F(LayerTreeImplTest,HitTestingSameSortingContextParentWins)859 TEST_F(LayerTreeImplTest, HitTestingSameSortingContextParentWins) {
860   LayerImpl* hit_layer = HitTestSimpleTree(/* sorting_contexts */ 10, 10, 10,
861                                            /* depths */ 0, -1, -1);
862   EXPECT_EQ(top_, hit_layer);
863 }
864 
TEST_F(LayerTreeImplTest,HitTestingForMultipleLayersAtVaryingDepths)865 TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) {
866   LayerImpl* root = root_layer();
867   root->SetBounds(gfx::Size(100, 100));
868   root->SetDrawsContent(true);
869   root->SetHitTestable(true);
870   GetTransformNode(root)->flattens_inherited_transform = false;
871   GetTransformNode(root)->sorting_context_id = 1;
872 
873   // child 1 and child2 are initialized to overlap between x=50 and x=60.
874   // grand_child is set to overlap both child1 and child2 between y=50 and
875   // y=60.  The expected stacking order is: (front) child2, (second)
876   // grand_child, (third) child1, and (back) the root layer behind all other
877   // layers.
878 
879   LayerImpl* child1 = AddLayer<LayerImpl>();
880   child1->SetBounds(gfx::Size(50, 50));
881   child1->SetDrawsContent(true);
882   child1->SetHitTestable(true);
883   CopyProperties(root, child1);
884   auto& child1_transform_node = CreateTransformNode(child1);
885   child1_transform_node.post_translation = gfx::Vector2dF(10.f, 10.f);
886   child1_transform_node.flattens_inherited_transform = false;
887   child1_transform_node.sorting_context_id = 1;
888 
889   // Remember that grand_child is positioned with respect to its parent (i.e.
890   // child1).  In screen space, the intended position is (10, 50), with size
891   // 100 x 50.
892   LayerImpl* grand_child1 = AddLayer<LayerImpl>();
893   grand_child1->SetBounds(gfx::Size(100, 50));
894   grand_child1->SetDrawsContent(true);
895   grand_child1->SetHitTestable(true);
896   CopyProperties(child1, grand_child1);
897   auto& grand_child1_transform_node = CreateTransformNode(grand_child1);
898   grand_child1_transform_node.post_translation = gfx::Vector2dF(0.f, 40.f);
899   grand_child1_transform_node.flattens_inherited_transform = false;
900 
901   LayerImpl* child2 = AddLayer<LayerImpl>();
902   child2->SetBounds(gfx::Size(50, 50));
903   gfx::Transform translate_z;
904   translate_z.Translate3d(0, 0, 10.f);
905   child2->SetDrawsContent(true);
906   child2->SetHitTestable(true);
907   CopyProperties(root, child2);
908   auto& child2_transform_node = CreateTransformNode(child2);
909   child2_transform_node.local = translate_z;
910   child2_transform_node.post_translation = gfx::Vector2dF(50.f, 10.f);
911   child2_transform_node.flattens_inherited_transform = false;
912   child2_transform_node.sorting_context_id = 1;
913 
914   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
915   UpdateDrawProperties(host_impl().active_tree());
916 
917   // Sanity check the scenario we just created.
918   ASSERT_TRUE(child1);
919   ASSERT_TRUE(child2);
920   ASSERT_TRUE(grand_child1);
921   ASSERT_EQ(1u, GetRenderSurfaceList().size());
922 
923   // Nothing overlaps the root_layer at (1, 1), so hit testing there should find
924   // the root layer.
925   gfx::PointF test_point = gfx::PointF(1.f, 1.f);
926   LayerImpl* result_layer =
927       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
928   EXPECT_EQ(root, result_layer);
929 
930   // At (15, 15), child1 and root are the only layers. child1 is expected to be
931   // on top.
932   test_point = gfx::PointF(15.f, 15.f);
933   result_layer =
934       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
935   EXPECT_EQ(child1, result_layer);
936 
937   // At (51, 20), child1 and child2 overlap. child2 is expected to be on top,
938   // as it was transformed to the foreground.
939   test_point = gfx::PointF(51.f, 20.f);
940   result_layer =
941       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
942   EXPECT_EQ(child2, result_layer);
943 
944   // At (80, 51), child2 and grand_child1 overlap. child2 is expected to
945   // be on top, as it was transformed to the foreground.
946   test_point = gfx::PointF(80.f, 51.f);
947   result_layer =
948       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
949   EXPECT_EQ(child2, result_layer);
950 
951   // At (51, 51), child1, child2 and grand_child1 overlap. child2 is expected to
952   // be on top, as it was transformed to the foreground.
953   test_point = gfx::PointF(51.f, 51.f);
954   result_layer =
955       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
956   EXPECT_EQ(child2, result_layer);
957 
958   // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
959   // be on top, as it descends from child1.
960   test_point = gfx::PointF(20.f, 51.f);
961   result_layer =
962       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
963   EXPECT_EQ(grand_child1, result_layer);
964 }
965 
TEST_F(LayerTreeImplTest,HitTestingRespectsClipParents)966 TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) {
967   LayerImpl* root = root_layer();
968   root->SetBounds(gfx::Size(100, 100));
969   root->SetDrawsContent(true);
970   root->SetHitTestable(true);
971 
972   LayerImpl* child = AddLayer<LayerImpl>();
973   child->SetBounds(gfx::Size(1, 1));
974   child->SetDrawsContent(true);
975   child->SetHitTestable(true);
976   CopyProperties(root, child);
977   child->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f));
978   CreateClipNode(child);
979 
980   LayerImpl* scroll_child = AddLayer<LayerImpl>();
981   scroll_child->SetBounds(gfx::Size(200, 200));
982   scroll_child->SetDrawsContent(true);
983   scroll_child->SetHitTestable(true);
984   CopyProperties(root, scroll_child);
985   scroll_child->SetClipTreeIndex(child->clip_tree_index());
986 
987   LayerImpl* grand_child = AddLayer<LayerImpl>();
988   grand_child->SetBounds(gfx::Size(200, 200));
989   grand_child->SetDrawsContent(true);
990   grand_child->SetHitTestable(true);
991   CopyProperties(scroll_child, grand_child);
992   CreateEffectNode(grand_child).render_surface_reason =
993       RenderSurfaceReason::kTest;
994 
995   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
996   UpdateDrawProperties(host_impl().active_tree());
997 
998   gfx::PointF test_point(12.f, 52.f);
999   LayerImpl* result_layer =
1000       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
1001   // The |test_point| should have been clipped away by |child|, so the only
1002   // thing that should be hit is |root|.
1003   EXPECT_EQ(root, result_layer);
1004 }
1005 
TEST_F(LayerTreeImplTest,HitTestingForMultipleLayerLists)1006 TEST_F(LayerTreeImplTest, HitTestingForMultipleLayerLists) {
1007   //
1008   // The geometry is set up similarly to the previous case, but
1009   // all layers are forced to be render surfaces now.
1010   //
1011   LayerImpl* root = root_layer();
1012   root->SetBounds(gfx::Size(100, 100));
1013   root->SetDrawsContent(true);
1014   root->SetHitTestable(true);
1015 
1016   // child 1 and child2 are initialized to overlap between x=50 and x=60.
1017   // grand_child is set to overlap both child1 and child2 between y=50 and
1018   // y=60.  The expected stacking order is: (front) child2, (second)
1019   // grand_child, (third) child1, and (back) the root layer behind all other
1020   // layers.
1021 
1022   LayerImpl* child1 = AddLayer<LayerImpl>();
1023   child1->SetBounds(gfx::Size(50, 50));
1024   child1->SetDrawsContent(true);
1025   child1->SetHitTestable(true);
1026   CopyProperties(root, child1);
1027   CreateTransformNode(child1).post_translation = gfx::Vector2dF(10.f, 10.f);
1028   CreateEffectNode(child1).render_surface_reason = RenderSurfaceReason::kTest;
1029 
1030   // Remember that grand_child is positioned with respect to its parent (i.e.
1031   // child1).  In screen space, the intended position is (10, 50), with size
1032   // 100 x 50.
1033   LayerImpl* grand_child1 = AddLayer<LayerImpl>();
1034   grand_child1->SetBounds(gfx::Size(100, 50));
1035   grand_child1->SetDrawsContent(true);
1036   grand_child1->SetHitTestable(true);
1037   CopyProperties(child1, grand_child1);
1038   CreateTransformNode(grand_child1).post_translation =
1039       gfx::Vector2dF(0.f, 40.f);
1040   CreateEffectNode(grand_child1).render_surface_reason =
1041       RenderSurfaceReason::kTest;
1042 
1043   LayerImpl* child2 = AddLayer<LayerImpl>();
1044   child2->SetBounds(gfx::Size(50, 50));
1045   child2->SetDrawsContent(true);
1046   child2->SetHitTestable(true);
1047   CopyProperties(root, child2);
1048   CreateTransformNode(child2).post_translation = gfx::Vector2dF(50.f, 10.f);
1049   CreateEffectNode(child2).render_surface_reason = RenderSurfaceReason::kTest;
1050 
1051   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
1052   UpdateDrawProperties(host_impl().active_tree());
1053 
1054   // Sanity check the scenario we just created.
1055   ASSERT_TRUE(child1);
1056   ASSERT_TRUE(child2);
1057   ASSERT_TRUE(grand_child1);
1058   ASSERT_TRUE(GetRenderSurface(child1));
1059   ASSERT_TRUE(GetRenderSurface(child2));
1060   ASSERT_TRUE(GetRenderSurface(grand_child1));
1061   ASSERT_EQ(4u, GetRenderSurfaceList().size());
1062   // The root surface has the root layer, and child1's and child2's render
1063   // surfaces.
1064   ASSERT_EQ(3, GetRenderSurface(root)->num_contributors());
1065   // The child1 surface has the child1 layer and grand_child1's render surface.
1066   ASSERT_EQ(2, GetRenderSurface(child1)->num_contributors());
1067   ASSERT_EQ(1, GetRenderSurface(child2)->num_contributors());
1068   ASSERT_EQ(1, GetRenderSurface(grand_child1)->num_contributors());
1069   EXPECT_TRUE(root_layer()->contributes_to_drawn_render_surface());
1070   EXPECT_TRUE(child1->contributes_to_drawn_render_surface());
1071   EXPECT_TRUE(grand_child1->contributes_to_drawn_render_surface());
1072   EXPECT_TRUE(child2->contributes_to_drawn_render_surface());
1073 
1074   // Nothing overlaps the root at (1, 1), so hit testing there should find
1075   // the root layer.
1076   gfx::PointF test_point(1.f, 1.f);
1077   LayerImpl* result_layer =
1078       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
1079   EXPECT_EQ(root, result_layer);
1080 
1081   // At (15, 15), child1 and root are the only layers. child1 is expected to be
1082   // on top.
1083   test_point = gfx::PointF(15.f, 15.f);
1084   result_layer =
1085       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
1086   EXPECT_EQ(child1, result_layer);
1087 
1088   // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
1089   test_point = gfx::PointF(51.f, 20.f);
1090   result_layer =
1091       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
1092   EXPECT_EQ(child2, result_layer);
1093 
1094   // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
1095   // top.
1096   test_point = gfx::PointF(80.f, 51.f);
1097   result_layer =
1098       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
1099   EXPECT_EQ(child2, result_layer);
1100 
1101   // At (51, 51), all layers overlap each other. child2 is expected to be on top
1102   // of all other layers.
1103   test_point = gfx::PointF(51.f, 51.f);
1104   result_layer =
1105       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
1106   EXPECT_EQ(child2, result_layer);
1107 
1108   // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
1109   // be on top.
1110   test_point = gfx::PointF(20.f, 51.f);
1111   result_layer =
1112       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
1113   EXPECT_EQ(grand_child1, result_layer);
1114 }
1115 
TEST_F(LayerTreeImplTest,HitCheckingTouchHandlerRegionsForSingleLayer)1116 TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSingleLayer) {
1117   TouchActionRegion touch_action_region;
1118   touch_action_region.Union(TouchAction::kNone, gfx::Rect(10, 10, 50, 50));
1119 
1120   LayerImpl* root = root_layer();
1121   root->SetBounds(gfx::Size(100, 100));
1122   root->SetDrawsContent(true);
1123   root->SetHitTestable(true);
1124 
1125   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
1126   UpdateDrawProperties(host_impl().active_tree());
1127 
1128   // Sanity check the scenario we just created.
1129   ASSERT_EQ(1u, GetRenderSurfaceList().size());
1130   ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());
1131 
1132   // Hit checking for any point should return a null pointer for a layer without
1133   // any touch event handler regions.
1134   gfx::PointF test_point(11.f, 11.f);
1135   LayerImpl* result_layer =
1136       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1137           test_point);
1138   EXPECT_FALSE(result_layer);
1139 
1140   root->SetTouchActionRegion(touch_action_region);
1141   // Hit checking for a point outside the layer should return a null pointer.
1142   test_point = gfx::PointF(101.f, 101.f);
1143   result_layer =
1144       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1145           test_point);
1146   EXPECT_FALSE(result_layer);
1147 
1148   test_point = gfx::PointF(-1.f, -1.f);
1149   result_layer =
1150       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1151           test_point);
1152   EXPECT_FALSE(result_layer);
1153 
1154   // Hit checking for a point inside the layer, but outside the touch handler
1155   // region should return a null pointer.
1156   test_point = gfx::PointF(1.f, 1.f);
1157   result_layer =
1158       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1159           test_point);
1160   EXPECT_FALSE(result_layer);
1161 
1162   test_point = gfx::PointF(99.f, 99.f);
1163   result_layer =
1164       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1165           test_point);
1166   EXPECT_FALSE(result_layer);
1167 
1168   // Hit checking for a point inside the touch event handler region should
1169   // return the root layer.
1170   test_point = gfx::PointF(11.f, 11.f);
1171   result_layer =
1172       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1173           test_point);
1174   EXPECT_EQ(root, result_layer);
1175 
1176   test_point = gfx::PointF(59.f, 59.f);
1177   result_layer =
1178       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1179           test_point);
1180   EXPECT_EQ(root, result_layer);
1181 }
1182 
TEST_F(LayerTreeImplTest,HitCheckingTouchHandlerRegionsForUninvertibleTransform)1183 TEST_F(LayerTreeImplTest,
1184        HitCheckingTouchHandlerRegionsForUninvertibleTransform) {
1185   LayerImpl* root = root_layer();
1186 
1187   gfx::Transform uninvertible_transform;
1188   uninvertible_transform.matrix().set(0, 0, 0.0);
1189   uninvertible_transform.matrix().set(1, 1, 0.0);
1190   uninvertible_transform.matrix().set(2, 2, 0.0);
1191   uninvertible_transform.matrix().set(3, 3, 0.0);
1192   ASSERT_FALSE(uninvertible_transform.IsInvertible());
1193 
1194   TouchActionRegion touch_action_region;
1195   touch_action_region.Union(TouchAction::kNone, gfx::Rect(10, 10, 50, 50));
1196 
1197   LayerImpl* layer = AddLayer<LayerImpl>();
1198   layer->SetBounds(gfx::Size(100, 100));
1199   layer->SetDrawsContent(true);
1200   layer->SetHitTestable(true);
1201   layer->SetTouchActionRegion(touch_action_region);
1202   root->SetBounds(layer->bounds());
1203   CopyProperties(root, layer);
1204   CreateTransformNode(layer).local = uninvertible_transform;
1205 
1206   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
1207   UpdateDrawProperties(host_impl().active_tree());
1208 
1209   // Sanity check the scenario we just created.
1210   ASSERT_EQ(1u, GetRenderSurfaceList().size());
1211   ASSERT_FALSE(layer->ScreenSpaceTransform().IsInvertible());
1212 
1213   // Hit checking any point should not hit the touch handler region on the
1214   // layer. If the invertible matrix is accidentally ignored and treated like an
1215   // identity, then the hit testing will incorrectly hit the layer when it
1216   // shouldn't.
1217   gfx::PointF test_point(1.f, 1.f);
1218   LayerImpl* result_layer =
1219       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1220           test_point);
1221   EXPECT_FALSE(result_layer);
1222 
1223   test_point = gfx::PointF(10.f, 10.f);
1224   result_layer =
1225       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1226           test_point);
1227   EXPECT_FALSE(result_layer);
1228 
1229   test_point = gfx::PointF(10.f, 30.f);
1230   result_layer =
1231       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1232           test_point);
1233   EXPECT_FALSE(result_layer);
1234 
1235   test_point = gfx::PointF(50.f, 50.f);
1236   result_layer =
1237       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1238           test_point);
1239   EXPECT_FALSE(result_layer);
1240 
1241   test_point = gfx::PointF(67.f, 48.f);
1242   result_layer =
1243       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1244           test_point);
1245   EXPECT_FALSE(result_layer);
1246 
1247   test_point = gfx::PointF(99.f, 99.f);
1248   result_layer =
1249       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1250           test_point);
1251   EXPECT_FALSE(result_layer);
1252 
1253   test_point = gfx::PointF(-1.f, -1.f);
1254   result_layer =
1255       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1256           test_point);
1257   EXPECT_FALSE(result_layer);
1258 }
1259 
TEST_F(LayerTreeImplTest,HitCheckingTouchHandlerRegionsForSinglePositionedLayer)1260 TEST_F(LayerTreeImplTest,
1261        HitCheckingTouchHandlerRegionsForSinglePositionedLayer) {
1262   TouchActionRegion touch_action_region;
1263   touch_action_region.Union(TouchAction::kNone, gfx::Rect(10, 10, 50, 50));
1264 
1265   // This layer is positioned, and hit testing should correctly know where the
1266   // layer is located.
1267   LayerImpl* test_layer = AddLayer<LayerImpl>();
1268   test_layer->SetBounds(gfx::Size(100, 100));
1269   test_layer->SetDrawsContent(true);
1270   test_layer->SetHitTestable(true);
1271   test_layer->SetTouchActionRegion(touch_action_region);
1272   CopyProperties(root_layer(), test_layer);
1273   test_layer->SetOffsetToTransformParent(gfx::Vector2dF(50.f, 50.f));
1274 
1275   host_impl().active_tree()->SetDeviceViewportRect(
1276       gfx::Rect(test_layer->bounds()));
1277   UpdateDrawProperties(host_impl().active_tree());
1278 
1279   // Sanity check the scenario we just created.
1280   ASSERT_EQ(1u, GetRenderSurfaceList().size());
1281   ASSERT_EQ(1, GetRenderSurface(test_layer)->num_contributors());
1282 
1283   // Hit checking for a point outside the layer should return a null pointer.
1284   gfx::PointF test_point(49.f, 49.f);
1285   LayerImpl* result_layer =
1286       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1287           test_point);
1288   EXPECT_FALSE(result_layer);
1289 
1290   // Even though the layer has a touch handler region containing (101, 101), it
1291   // should not be visible there since the root render surface would clamp it.
1292   test_point = gfx::PointF(101.f, 101.f);
1293   result_layer =
1294       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1295           test_point);
1296   EXPECT_FALSE(result_layer);
1297 
1298   // Hit checking for a point inside the layer, but outside the touch handler
1299   // region should return a null pointer.
1300   test_point = gfx::PointF(51.f, 51.f);
1301   result_layer =
1302       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1303           test_point);
1304   EXPECT_FALSE(result_layer);
1305 
1306   // Hit checking for a point inside the touch event handler region should
1307   // return the test layer.
1308   test_point = gfx::PointF(61.f, 61.f);
1309   result_layer =
1310       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1311           test_point);
1312   EXPECT_EQ(test_layer, result_layer);
1313 
1314   test_point = gfx::PointF(99.f, 99.f);
1315   result_layer =
1316       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1317           test_point);
1318   EXPECT_EQ(test_layer, result_layer);
1319 }
1320 
TEST_F(LayerTreeImplTest,HitCheckingTouchHandlerRegionsForSingleLayerWithDeviceScale)1321 TEST_F(LayerTreeImplTest,
1322        HitCheckingTouchHandlerRegionsForSingleLayerWithDeviceScale) {
1323   // The layer's device_scale_factor and page_scale_factor should scale the
1324   // content rect and we should be able to hit the touch handler region by
1325   // scaling the points accordingly.
1326 
1327   // Set the bounds of the root layer big enough to fit the child when scaled.
1328   LayerImpl* root = root_layer();
1329   root->SetBounds(gfx::Size(100, 100));
1330 
1331   LayerImpl* page_scale_layer = AddLayer<LayerImpl>();
1332   CopyProperties(root, page_scale_layer);
1333   CreateTransformNode(page_scale_layer);
1334 
1335   TouchActionRegion touch_action_region;
1336   touch_action_region.Union(TouchAction::kNone, gfx::Rect(10, 10, 30, 30));
1337   LayerImpl* test_layer = AddLayer<LayerImpl>();
1338   test_layer->SetBounds(gfx::Size(50, 50));
1339   test_layer->SetDrawsContent(true);
1340   test_layer->SetHitTestable(true);
1341   test_layer->SetTouchActionRegion(touch_action_region);
1342   CopyProperties(page_scale_layer, test_layer);
1343   test_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 25.f));
1344 
1345   float device_scale_factor = 3.f;
1346   float page_scale_factor = 5.f;
1347   float max_page_scale_factor = 10.f;
1348   gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize(
1349       root->bounds(), device_scale_factor * page_scale_factor);
1350   host_impl().active_tree()->SetDeviceViewportRect(
1351       gfx::Rect(scaled_bounds_for_root));
1352 
1353   host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor);
1354   LayerTreeImpl::ViewportPropertyIds viewport_property_ids;
1355   viewport_property_ids.page_scale_transform =
1356       page_scale_layer->transform_tree_index();
1357   host_impl().active_tree()->SetViewportPropertyIds(viewport_property_ids);
1358   host_impl().active_tree()->PushPageScaleFromMainThread(
1359       page_scale_factor, page_scale_factor, max_page_scale_factor);
1360   host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
1361   UpdateDrawProperties(host_impl().active_tree());
1362 
1363   // Sanity check the scenario we just created.
1364   // The visible content rect for test_layer is actually 100x100, even though
1365   // its layout size is 50x50, positioned at 25x25.
1366   ASSERT_EQ(1u, GetRenderSurfaceList().size());
1367   ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());
1368 
1369   // Check whether the child layer fits into the root after scaled.
1370   EXPECT_EQ(gfx::Rect(test_layer->bounds()), test_layer->visible_layer_rect());
1371 
1372   // Hit checking for a point outside the layer should return a null pointer
1373   // (the root layer does not have a touch event handler, so it will not be
1374   // tested either).
1375   gfx::PointF test_point(76.f, 76.f);
1376   test_point =
1377       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1378   LayerImpl* result_layer =
1379       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1380           test_point);
1381   EXPECT_FALSE(result_layer);
1382 
1383   // Hit checking for a point inside the layer, but outside the touch handler
1384   // region should return a null pointer.
1385   test_point = gfx::PointF(26.f, 26.f);
1386   test_point =
1387       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1388   result_layer =
1389       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1390           test_point);
1391   EXPECT_FALSE(result_layer);
1392 
1393   test_point = gfx::PointF(34.f, 34.f);
1394   test_point =
1395       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1396   result_layer =
1397       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1398           test_point);
1399   EXPECT_FALSE(result_layer);
1400 
1401   test_point = gfx::PointF(65.f, 65.f);
1402   test_point =
1403       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1404   result_layer =
1405       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1406           test_point);
1407   EXPECT_FALSE(result_layer);
1408 
1409   test_point = gfx::PointF(74.f, 74.f);
1410   test_point =
1411       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1412   result_layer =
1413       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1414           test_point);
1415   EXPECT_FALSE(result_layer);
1416 
1417   // Hit checking for a point inside the touch event handler region should
1418   // return the root layer.
1419   test_point = gfx::PointF(35.f, 35.f);
1420   test_point =
1421       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1422   result_layer =
1423       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1424           test_point);
1425   EXPECT_EQ(test_layer, result_layer);
1426 
1427   test_point = gfx::PointF(64.f, 64.f);
1428   test_point =
1429       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1430   result_layer =
1431       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1432           test_point);
1433   EXPECT_EQ(test_layer, result_layer);
1434 
1435   // Check update of page scale factor on the active tree when page scale layer
1436   // is also the root layer.
1437   page_scale_factor *= 1.5f;
1438   host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
1439   EXPECT_EQ(page_scale_layer->transform_tree_index(),
1440             host_impl().active_tree()->PageScaleTransformNode()->id);
1441 
1442   test_point = gfx::PointF(35.f, 35.f);
1443   test_point =
1444       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1445   result_layer =
1446       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1447           test_point);
1448   EXPECT_EQ(test_layer, result_layer);
1449 
1450   test_point = gfx::PointF(64.f, 64.f);
1451   test_point =
1452       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1453   result_layer =
1454       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1455           test_point);
1456   EXPECT_EQ(test_layer, result_layer);
1457 }
1458 
TEST_F(LayerTreeImplTest,HitCheckingTouchHandlerRegionsForSimpleClippedLayer)1459 TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerRegionsForSimpleClippedLayer) {
1460   // Test that hit-checking will only work for the visible portion of a layer,
1461   // and not the entire layer bounds. Here we just test the simple axis-aligned
1462   // case.
1463   LayerImpl* root = root_layer();
1464   root->SetBounds(gfx::Size(100, 100));
1465 
1466   LayerImpl* clipping_layer = AddLayer<LayerImpl>();
1467   // this layer is positioned, and hit testing should correctly know where
1468   // the layer is located.
1469   clipping_layer->SetBounds(gfx::Size(50, 50));
1470   clipping_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 25.f));
1471   CopyProperties(root, clipping_layer);
1472   CreateClipNode(clipping_layer);
1473 
1474   TouchActionRegion touch_action_region;
1475   touch_action_region.Union(TouchAction::kNone, gfx::Rect(10, 10, 50, 50));
1476 
1477   LayerImpl* child = AddLayer<LayerImpl>();
1478   child->SetBounds(gfx::Size(300, 300));
1479   child->SetDrawsContent(true);
1480   child->SetHitTestable(true);
1481   child->SetTouchActionRegion(touch_action_region);
1482   CopyProperties(clipping_layer, child);
1483   child->SetOffsetToTransformParent(
1484       gfx::Vector2dF(-50.f, -50.f) +
1485       clipping_layer->offset_to_transform_parent());
1486 
1487   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
1488   UpdateDrawProperties(host_impl().active_tree());
1489 
1490   // Sanity check the scenario we just created.
1491   ASSERT_EQ(1u, GetRenderSurfaceList().size());
1492   ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());
1493   EXPECT_TRUE(child->contributes_to_drawn_render_surface());
1494 
1495   // Hit checking for a point outside the layer should return a null pointer.
1496   // Despite the child layer being very large, it should be clipped to the root
1497   // layer's bounds.
1498   gfx::PointF test_point(24.f, 24.f);
1499   LayerImpl* result_layer =
1500       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1501           test_point);
1502   EXPECT_FALSE(result_layer);
1503 
1504   // Hit checking for a point inside the layer, but outside the touch handler
1505   // region should return a null pointer.
1506   test_point = gfx::PointF(35.f, 35.f);
1507   result_layer =
1508       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1509           test_point);
1510   EXPECT_FALSE(result_layer);
1511 
1512   test_point = gfx::PointF(74.f, 74.f);
1513   result_layer =
1514       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1515           test_point);
1516   EXPECT_FALSE(result_layer);
1517 
1518   // Hit checking for a point inside the touch event handler region should
1519   // return the root layer.
1520   test_point = gfx::PointF(25.f, 25.f);
1521   result_layer =
1522       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1523           test_point);
1524   EXPECT_EQ(child, result_layer);
1525 
1526   test_point = gfx::PointF(34.f, 34.f);
1527   result_layer =
1528       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1529           test_point);
1530   EXPECT_EQ(child, result_layer);
1531 }
1532 
TEST_F(LayerTreeImplTest,HitCheckingTouchHandlerRegionsForClippedLayerWithDeviceScale)1533 TEST_F(LayerTreeImplTest,
1534        HitCheckingTouchHandlerRegionsForClippedLayerWithDeviceScale) {
1535   // The layer's device_scale_factor and page_scale_factor should scale the
1536   // content rect and we should be able to hit the touch handler region by
1537   // scaling the points accordingly.
1538 
1539   // Set the bounds of the root layer big enough to fit the child when scaled.
1540   LayerImpl* root = root_layer();
1541   root->SetBounds(gfx::Size(100, 100));
1542 
1543   LayerImpl* surface = AddLayer<LayerImpl>();
1544   surface->SetBounds(gfx::Size(100, 100));
1545   CopyProperties(root, surface);
1546   CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
1547 
1548   LayerImpl* clipping_layer = AddLayer<LayerImpl>();
1549   // This layer is positioned, and hit testing should correctly know where
1550   // the layer is located.
1551   clipping_layer->SetBounds(gfx::Size(50, 50));
1552   CopyProperties(surface, clipping_layer);
1553   clipping_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 20.f));
1554   CreateClipNode(clipping_layer);
1555 
1556   TouchActionRegion touch_action_region;
1557   touch_action_region.Union(TouchAction::kNone, gfx::Rect(0, 0, 300, 300));
1558 
1559   LayerImpl* child = AddLayer<LayerImpl>();
1560   child->SetBounds(gfx::Size(300, 300));
1561   child->SetDrawsContent(true);
1562   child->SetHitTestable(true);
1563   child->SetTouchActionRegion(touch_action_region);
1564   CopyProperties(clipping_layer, child);
1565   child->SetOffsetToTransformParent(
1566       gfx::Vector2dF(-50.f, -50.f) +
1567       clipping_layer->offset_to_transform_parent());
1568 
1569   float device_scale_factor = 3.f;
1570   float page_scale_factor = 1.f;
1571   float max_page_scale_factor = 1.f;
1572   gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize(
1573       root->bounds(), device_scale_factor * page_scale_factor);
1574   host_impl().active_tree()->SetDeviceViewportRect(
1575       gfx::Rect(scaled_bounds_for_root));
1576 
1577   host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor);
1578   host_impl().active_tree()->PushPageScaleFromMainThread(
1579       page_scale_factor, page_scale_factor, max_page_scale_factor);
1580   host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
1581   UpdateDrawProperties(host_impl().active_tree());
1582 
1583   // Sanity check the scenario we just created.
1584   ASSERT_EQ(2u, GetRenderSurfaceList().size());
1585 
1586   // Hit checking for a point outside the layer should return a null pointer.
1587   // Despite the child layer being very large, it should be clipped to the root
1588   // layer's bounds.
1589   gfx::PointF test_point(24.f, 24.f);
1590   test_point =
1591       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1592   LayerImpl* result_layer =
1593       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1594           test_point);
1595   EXPECT_FALSE(result_layer);
1596 
1597   // Hit checking for a point inside the touch event handler region should
1598   // return the child layer.
1599   test_point = gfx::PointF(25.f, 25.f);
1600   test_point =
1601       gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
1602   result_layer =
1603       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1604           test_point);
1605   EXPECT_EQ(child, result_layer);
1606 }
1607 
TEST_F(LayerTreeImplTest,HitCheckingTouchHandlerOverlappingRegions)1608 TEST_F(LayerTreeImplTest, HitCheckingTouchHandlerOverlappingRegions) {
1609   LayerImpl* root = root_layer();
1610   root->SetBounds(gfx::Size(100, 100));
1611 
1612   LayerImpl* touch_layer = AddLayer<LayerImpl>();
1613   // this layer is positioned, and hit testing should correctly know where
1614   // the layer is located.
1615   touch_layer->SetBounds(gfx::Size(50, 50));
1616   touch_layer->SetDrawsContent(true);
1617   touch_layer->SetHitTestable(true);
1618   TouchActionRegion touch_action_region;
1619   touch_action_region.Union(TouchAction::kNone, gfx::Rect(0, 0, 50, 50));
1620   touch_layer->SetTouchActionRegion(touch_action_region);
1621   CopyProperties(root, touch_layer);
1622 
1623   LayerImpl* notouch_layer = AddLayer<LayerImpl>();
1624   // this layer is positioned, and hit testing should correctly know where
1625   // the layer is located.
1626   notouch_layer->SetBounds(gfx::Size(50, 50));
1627   notouch_layer->SetDrawsContent(true);
1628   notouch_layer->SetHitTestable(true);
1629   CopyProperties(root, notouch_layer);
1630   notouch_layer->SetOffsetToTransformParent(gfx::Vector2dF(0, 25));
1631 
1632   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
1633   UpdateDrawProperties(host_impl().active_tree());
1634 
1635   // Sanity check the scenario we just created.
1636   ASSERT_EQ(1u, GetRenderSurfaceList().size());
1637   ASSERT_EQ(2, GetRenderSurface(root)->num_contributors());
1638   EXPECT_TRUE(touch_layer->contributes_to_drawn_render_surface());
1639   EXPECT_TRUE(notouch_layer->contributes_to_drawn_render_surface());
1640 
1641   gfx::PointF test_point(35.f, 35.f);
1642   LayerImpl* result_layer =
1643       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1644           test_point);
1645 
1646   // We should have passed through the no-touch layer and found the layer
1647   // behind it.
1648   EXPECT_TRUE(result_layer);
1649 
1650   notouch_layer->SetContentsOpaque(true);
1651   result_layer =
1652       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1653           test_point);
1654 
1655   // Even with an opaque layer in the middle, we should still find the layer
1656   // with
1657   // the touch handler behind it (since we can't assume that opaque layers are
1658   // opaque to hit testing).
1659   EXPECT_TRUE(result_layer);
1660 
1661   test_point = gfx::PointF(35.f, 15.f);
1662   result_layer =
1663       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1664           test_point);
1665   EXPECT_EQ(touch_layer, result_layer);
1666 
1667   test_point = gfx::PointF(35.f, 65.f);
1668   result_layer =
1669       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1670           test_point);
1671   EXPECT_FALSE(result_layer);
1672 }
1673 
TEST_F(LayerTreeImplTest,HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn)1674 TEST_F(LayerTreeImplTest, HitTestingTouchHandlerRegionsForLayerThatIsNotDrawn) {
1675   LayerImpl* root = root_layer();
1676   root->SetBounds(gfx::Size(100, 100));
1677   root->SetDrawsContent(true);
1678   root->SetHitTestable(true);
1679 
1680   TouchActionRegion touch_action_region;
1681   touch_action_region.Union(TouchAction::kNone, gfx::Rect(10, 10, 30, 30));
1682   LayerImpl* test_layer = AddLayer<LayerImpl>();
1683   test_layer->SetBounds(gfx::Size(50, 50));
1684   test_layer->SetDrawsContent(false);
1685   test_layer->SetHitTestable(false);
1686   test_layer->SetTouchActionRegion(touch_action_region);
1687   CopyProperties(root, test_layer);
1688 
1689   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
1690   UpdateDrawProperties(host_impl().active_tree());
1691 
1692   // As test_layer doesn't draw content, it shouldn't contribute content to the
1693   // root surface.
1694   ASSERT_EQ(1u, GetRenderSurfaceList().size());
1695   EXPECT_FALSE(test_layer->contributes_to_drawn_render_surface());
1696 
1697   // Hit testing for a point outside the test layer should return null pointer.
1698   // We also implicitly check that the updated screen space transform of a layer
1699   // that is not in drawn render surface layer list (test_layer) is used during
1700   // hit testing (becuase the point is inside test_layer with respect to the old
1701   // screen space transform).
1702   gfx::PointF test_point(24.f, 24.f);
1703   test_layer->SetOffsetToTransformParent(gfx::Vector2dF(25.f, 25.f));
1704   gfx::Transform expected_screen_space_transform;
1705   expected_screen_space_transform.Translate(25.f, 25.f);
1706 
1707   UpdateDrawProperties(host_impl().active_tree());
1708   LayerImpl* result_layer =
1709       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1710           test_point);
1711   EXPECT_FALSE(result_layer);
1712   EXPECT_FALSE(test_layer->contributes_to_drawn_render_surface());
1713   EXPECT_TRANSFORMATION_MATRIX_EQ(
1714       expected_screen_space_transform,
1715       draw_property_utils::ScreenSpaceTransform(
1716           test_layer,
1717           host_impl().active_tree()->property_trees()->transform_tree));
1718 
1719   // We change the position of the test layer such that the test point is now
1720   // inside the test_layer.
1721   test_layer->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f));
1722   test_layer->NoteLayerPropertyChanged();
1723   expected_screen_space_transform.MakeIdentity();
1724   expected_screen_space_transform.Translate(10.f, 10.f);
1725 
1726   UpdateDrawProperties(host_impl().active_tree());
1727   result_layer =
1728       host_impl().active_tree()->FindLayerThatIsHitByPointInTouchHandlerRegion(
1729           test_point);
1730   ASSERT_TRUE(result_layer);
1731   ASSERT_EQ(test_layer, result_layer);
1732   EXPECT_FALSE(result_layer->contributes_to_drawn_render_surface());
1733   EXPECT_TRANSFORMATION_MATRIX_EQ(
1734       expected_screen_space_transform,
1735       draw_property_utils::ScreenSpaceTransform(
1736           test_layer,
1737           host_impl().active_tree()->property_trees()->transform_tree));
1738 }
1739 
TEST_F(LayerTreeImplTest,SelectionBoundsForSingleLayer)1740 TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) {
1741   LayerImpl* root = root_layer();
1742   root->SetBounds(gfx::Size(100, 100));
1743   root->SetDrawsContent(true);
1744 
1745   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
1746   UpdateDrawProperties(host_impl().active_tree());
1747 
1748   // Sanity check the scenario we just created.
1749   ASSERT_EQ(1u, GetRenderSurfaceList().size());
1750   ASSERT_EQ(1, GetRenderSurface(root)->num_contributors());
1751 
1752   LayerSelection input;
1753 
1754   input.start.type = gfx::SelectionBound::LEFT;
1755   input.start.edge_start = gfx::Point(10, 10);
1756   input.start.edge_end = gfx::Point(10, 20);
1757   input.start.layer_id = root->id();
1758 
1759   input.end.type = gfx::SelectionBound::RIGHT;
1760   input.end.edge_start = gfx::Point(50, 10);
1761   input.end.edge_end = gfx::Point(50, 30);
1762   input.end.layer_id = root->id();
1763 
1764   viz::Selection<gfx::SelectionBound> output;
1765 
1766   // Empty input bounds should produce empty output bounds.
1767   host_impl().active_tree()->GetViewportSelection(&output);
1768   EXPECT_EQ(gfx::SelectionBound(), output.start);
1769   EXPECT_EQ(gfx::SelectionBound(), output.end);
1770 
1771   // Selection bounds should produce distinct left and right bounds.
1772   host_impl().active_tree()->RegisterSelection(input);
1773   host_impl().active_tree()->GetViewportSelection(&output);
1774   EXPECT_EQ(input.start.type, output.start.type());
1775   EXPECT_EQ(gfx::PointF(input.start.edge_end), output.start.edge_end());
1776   EXPECT_EQ(gfx::PointF(input.start.edge_start), output.start.edge_start());
1777   EXPECT_EQ(gfx::PointF(input.start.edge_end), output.start.visible_edge_end());
1778   EXPECT_EQ(gfx::PointF(input.start.edge_start),
1779             output.start.visible_edge_start());
1780   EXPECT_TRUE(output.start.visible());
1781   EXPECT_EQ(input.end.type, output.end.type());
1782   EXPECT_EQ(gfx::PointF(input.end.edge_end), output.end.edge_end());
1783   EXPECT_EQ(gfx::PointF(input.end.edge_start), output.end.edge_start());
1784   EXPECT_EQ(gfx::PointF(input.end.edge_end), output.end.visible_edge_end());
1785   EXPECT_EQ(gfx::PointF(input.end.edge_start), output.end.visible_edge_start());
1786   EXPECT_TRUE(output.end.visible());
1787 
1788   // Selection bounds should produce distinct left and right bounds for the
1789   // vertical text.
1790   input.start.type = gfx::SelectionBound::LEFT;
1791   input.start.edge_start = gfx::Point(20, 10);
1792   input.start.edge_end = gfx::Point(10, 10);
1793   input.start.layer_id = root->id();
1794 
1795   input.end.type = gfx::SelectionBound::RIGHT;
1796   input.end.edge_start = gfx::Point(30, 20);
1797   input.end.edge_end = gfx::Point(50, 20);
1798   input.end.layer_id = root->id();
1799 
1800   host_impl().active_tree()->RegisterSelection(input);
1801   host_impl().active_tree()->GetViewportSelection(&output);
1802   EXPECT_EQ(input.start.type, output.start.type());
1803   EXPECT_EQ(gfx::PointF(input.start.edge_end), output.start.edge_end());
1804   EXPECT_EQ(gfx::PointF(input.start.edge_start), output.start.edge_start());
1805   EXPECT_EQ(gfx::PointF(input.start.edge_end), output.start.visible_edge_end());
1806   EXPECT_EQ(gfx::PointF(input.start.edge_start),
1807             output.start.visible_edge_start());
1808   EXPECT_TRUE(output.start.visible());
1809   EXPECT_EQ(input.end.type, output.end.type());
1810   EXPECT_EQ(gfx::PointF(input.end.edge_end), output.end.edge_end());
1811   EXPECT_EQ(gfx::PointF(input.end.edge_start), output.end.edge_start());
1812   EXPECT_EQ(gfx::PointF(input.end.edge_end), output.end.visible_edge_end());
1813   EXPECT_EQ(gfx::PointF(input.end.edge_start), output.end.visible_edge_start());
1814   EXPECT_TRUE(output.end.visible());
1815 
1816   // Insertion bounds should produce identical left and right bounds.
1817   LayerSelection insertion_input;
1818   insertion_input.start.type = gfx::SelectionBound::CENTER;
1819   insertion_input.start.edge_start = gfx::Point(15, 10);
1820   insertion_input.start.edge_end = gfx::Point(15, 30);
1821   insertion_input.start.layer_id = root->id();
1822   insertion_input.end = insertion_input.start;
1823   host_impl().active_tree()->RegisterSelection(insertion_input);
1824   host_impl().active_tree()->GetViewportSelection(&output);
1825   EXPECT_EQ(insertion_input.start.type, output.start.type());
1826   EXPECT_EQ(gfx::PointF(insertion_input.start.edge_end),
1827             output.start.edge_end());
1828   EXPECT_EQ(gfx::PointF(insertion_input.start.edge_start),
1829             output.start.edge_start());
1830   EXPECT_EQ(gfx::PointF(insertion_input.start.edge_end),
1831             output.start.visible_edge_end());
1832   EXPECT_EQ(gfx::PointF(insertion_input.start.edge_start),
1833             output.start.visible_edge_start());
1834   EXPECT_TRUE(output.start.visible());
1835   EXPECT_EQ(output.start, output.end);
1836 }
1837 
TEST_F(LayerTreeImplTest,SelectionBoundsForPartialOccludedLayers)1838 TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) {
1839   LayerImpl* root = root_layer();
1840   root->SetDrawsContent(true);
1841   root->SetBounds(gfx::Size(100, 100));
1842 
1843   gfx::Vector2dF clipping_offset(10, 10);
1844 
1845   LayerImpl* clipping_layer = AddLayer<LayerImpl>();
1846   // The clipping layer should occlude the right selection bound.
1847   clipping_layer->SetBounds(gfx::Size(50, 50));
1848   CopyProperties(root, clipping_layer);
1849   clipping_layer->SetOffsetToTransformParent(clipping_offset);
1850   CreateClipNode(clipping_layer);
1851 
1852   LayerImpl* clipped_layer = AddLayer<LayerImpl>();
1853   clipped_layer->SetBounds(gfx::Size(100, 100));
1854   clipped_layer->SetDrawsContent(true);
1855   CopyProperties(clipping_layer, clipped_layer);
1856   clipped_layer->SetOffsetToTransformParent(
1857       clipping_layer->offset_to_transform_parent());
1858 
1859   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
1860   UpdateDrawProperties(host_impl().active_tree());
1861 
1862   // Sanity check the scenario we just created.
1863   ASSERT_EQ(1u, GetRenderSurfaceList().size());
1864 
1865   LayerSelection input;
1866   input.start.type = gfx::SelectionBound::LEFT;
1867   input.start.edge_start = gfx::Point(25, 10);
1868   input.start.edge_end = gfx::Point(25, 30);
1869   input.start.layer_id = clipped_layer->id();
1870 
1871   input.end.type = gfx::SelectionBound::RIGHT;
1872   input.end.edge_start = gfx::Point(75, 10);
1873   input.end.edge_end = gfx::Point(75, 30);
1874   input.end.layer_id = clipped_layer->id();
1875   host_impl().active_tree()->RegisterSelection(input);
1876 
1877   // The right bound should be occluded by the clip layer.
1878   viz::Selection<gfx::SelectionBound> output;
1879   host_impl().active_tree()->GetViewportSelection(&output);
1880   EXPECT_EQ(input.start.type, output.start.type());
1881   auto expected_output_edge_start = gfx::PointF(input.start.edge_start);
1882   auto expected_output_edge_end = gfx::PointF(input.start.edge_end);
1883   expected_output_edge_start.Offset(clipping_offset.x(), clipping_offset.y());
1884   expected_output_edge_end.Offset(clipping_offset.x(), clipping_offset.y());
1885   EXPECT_EQ(expected_output_edge_start, output.start.edge_start());
1886   EXPECT_EQ(expected_output_edge_end, output.start.edge_end());
1887   EXPECT_EQ(expected_output_edge_start, output.start.visible_edge_start());
1888   EXPECT_EQ(expected_output_edge_end, output.start.visible_edge_end());
1889   EXPECT_TRUE(output.start.visible());
1890   EXPECT_EQ(input.end.type, output.end.type());
1891   expected_output_edge_start = gfx::PointF(input.end.edge_start);
1892   expected_output_edge_end = gfx::PointF(input.end.edge_end);
1893   expected_output_edge_end.Offset(clipping_offset.x(), clipping_offset.y());
1894   expected_output_edge_start.Offset(clipping_offset.x(), clipping_offset.y());
1895   EXPECT_EQ(expected_output_edge_start, output.end.edge_start());
1896   EXPECT_EQ(expected_output_edge_end, output.end.edge_end());
1897 
1898   gfx::RectF visible_layer_rect(clipped_layer->visible_layer_rect());
1899   gfx::PointF expected_output_visible_edge_start;
1900   gfx::PointF expected_output_visible_edge_end;
1901   std::tie(expected_output_visible_edge_start,
1902            expected_output_visible_edge_end) =
1903       GetVisibleSelectionEndPoints(visible_layer_rect,
1904                                    gfx::PointF(input.end.edge_start),
1905                                    gfx::PointF(input.end.edge_end));
1906   expected_output_visible_edge_start.Offset(clipping_offset.x(),
1907                                             clipping_offset.y());
1908   expected_output_visible_edge_end.Offset(clipping_offset.x(),
1909                                           clipping_offset.y());
1910 
1911   EXPECT_EQ(expected_output_visible_edge_start,
1912             output.end.visible_edge_start());
1913   EXPECT_EQ(expected_output_visible_edge_end, output.end.visible_edge_end());
1914   EXPECT_FALSE(output.end.visible());
1915 
1916   // The right bound should be occluded by the clip layer for the vertical text.
1917   input.start.type = gfx::SelectionBound::LEFT;
1918   input.start.edge_start = gfx::Point(25, 10);
1919   input.start.edge_end = gfx::Point(15, 10);
1920   input.start.layer_id = clipped_layer->id();
1921 
1922   input.end.type = gfx::SelectionBound::RIGHT;
1923   input.end.edge_start = gfx::Point(75, 30);
1924   input.end.edge_end = gfx::Point(85, 30);
1925   input.end.layer_id = clipped_layer->id();
1926   host_impl().active_tree()->RegisterSelection(input);
1927 
1928   host_impl().active_tree()->GetViewportSelection(&output);
1929   EXPECT_EQ(input.start.type, output.start.type());
1930   expected_output_edge_start = gfx::PointF(input.start.edge_start);
1931   expected_output_edge_end = gfx::PointF(input.start.edge_end);
1932   expected_output_edge_start.Offset(clipping_offset.x(), clipping_offset.y());
1933   expected_output_edge_end.Offset(clipping_offset.x(), clipping_offset.y());
1934   EXPECT_EQ(expected_output_edge_start, output.start.edge_start());
1935   EXPECT_EQ(expected_output_edge_end, output.start.edge_end());
1936   EXPECT_EQ(expected_output_edge_start, output.start.visible_edge_start());
1937   EXPECT_EQ(expected_output_edge_end, output.start.visible_edge_end());
1938   EXPECT_TRUE(output.start.visible());
1939   EXPECT_EQ(input.end.type, output.end.type());
1940   expected_output_edge_start = gfx::PointF(input.end.edge_start);
1941   expected_output_edge_end = gfx::PointF(input.end.edge_end);
1942   expected_output_edge_end.Offset(clipping_offset.x(), clipping_offset.y());
1943   expected_output_edge_start.Offset(clipping_offset.x(), clipping_offset.y());
1944   EXPECT_EQ(expected_output_edge_start, output.end.edge_start());
1945   EXPECT_EQ(expected_output_edge_end, output.end.edge_end());
1946 
1947   std::tie(expected_output_visible_edge_start,
1948            expected_output_visible_edge_end) =
1949       GetVisibleSelectionEndPoints(visible_layer_rect,
1950                                    gfx::PointF(input.end.edge_start),
1951                                    gfx::PointF(input.end.edge_end));
1952   expected_output_visible_edge_start.Offset(clipping_offset.x(),
1953                                             clipping_offset.y());
1954   expected_output_visible_edge_end.Offset(clipping_offset.x(),
1955                                           clipping_offset.y());
1956 
1957   EXPECT_EQ(expected_output_visible_edge_start,
1958             output.end.visible_edge_start());
1959   EXPECT_EQ(expected_output_visible_edge_end, output.end.visible_edge_end());
1960   EXPECT_FALSE(output.end.visible());
1961 
1962   // Handles outside the viewport bounds should be marked invisible.
1963   input.start.edge_start = gfx::Point(-25, 0);
1964   input.start.edge_end = gfx::Point(-25, 20);
1965   host_impl().active_tree()->RegisterSelection(input);
1966   host_impl().active_tree()->GetViewportSelection(&output);
1967   EXPECT_FALSE(output.start.visible());
1968 
1969   input.start.edge_start = gfx::Point(0, -25);
1970   input.start.edge_end = gfx::Point(0, -5);
1971   host_impl().active_tree()->RegisterSelection(input);
1972   host_impl().active_tree()->GetViewportSelection(&output);
1973   EXPECT_FALSE(output.start.visible());
1974 
1975   // If the handle end is partially visible, the handle is marked visible.
1976   input.start.edge_start = gfx::Point(0, -20);
1977   input.start.edge_end = gfx::Point(0, 1);
1978   host_impl().active_tree()->RegisterSelection(input);
1979   host_impl().active_tree()->GetViewportSelection(&output);
1980   EXPECT_TRUE(output.start.visible());
1981 }
1982 
TEST_F(LayerTreeImplTest,SelectionBoundsForScaledLayers)1983 TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) {
1984   LayerImpl* root = root_layer();
1985   root->SetDrawsContent(true);
1986   root->SetBounds(gfx::Size(100, 100));
1987 
1988   LayerImpl* page_scale_layer = AddLayer<LayerImpl>();
1989   page_scale_layer->SetBounds(gfx::Size(50, 50));
1990   CopyProperties(root, page_scale_layer);
1991   CreateTransformNode(page_scale_layer);
1992 
1993   gfx::Vector2dF sub_layer_offset(10, 0);
1994   LayerImpl* sub_layer = AddLayer<LayerImpl>();
1995   sub_layer->SetBounds(gfx::Size(50, 50));
1996   sub_layer->SetDrawsContent(true);
1997   CopyProperties(page_scale_layer, sub_layer);
1998   sub_layer->SetOffsetToTransformParent(sub_layer_offset);
1999 
2000   UpdateDrawProperties(host_impl().active_tree());
2001 
2002   float device_scale_factor = 3.f;
2003   float page_scale_factor = 5.f;
2004   gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize(
2005       root->bounds(), device_scale_factor * page_scale_factor);
2006 
2007   LayerTreeImpl::ViewportPropertyIds viewport_property_ids;
2008   viewport_property_ids.page_scale_transform =
2009       page_scale_layer->transform_tree_index();
2010   host_impl().active_tree()->SetViewportPropertyIds(viewport_property_ids);
2011   host_impl().active_tree()->SetDeviceViewportRect(
2012       gfx::Rect(scaled_bounds_for_root));
2013   host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor);
2014   host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
2015 
2016   host_impl().active_tree()->PushPageScaleFromMainThread(
2017       page_scale_factor, page_scale_factor, page_scale_factor);
2018   host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
2019   UpdateDrawProperties(host_impl().active_tree());
2020 
2021   // Sanity check the scenario we just created.
2022   ASSERT_EQ(1u, GetRenderSurfaceList().size());
2023 
2024   LayerSelection input;
2025   input.start.type = gfx::SelectionBound::LEFT;
2026   input.start.edge_start = gfx::Point(10, 10);
2027   input.start.edge_end = gfx::Point(10, 30);
2028   input.start.layer_id = page_scale_layer->id();
2029 
2030   input.end.type = gfx::SelectionBound::RIGHT;
2031   input.end.edge_start = gfx::Point(0, 0);
2032   input.end.edge_end = gfx::Point(0, 20);
2033   input.end.layer_id = sub_layer->id();
2034   host_impl().active_tree()->RegisterSelection(input);
2035 
2036   // The viewport bounds should be properly scaled by the page scale, but should
2037   // remain in DIP coordinates.
2038   viz::Selection<gfx::SelectionBound> output;
2039   host_impl().active_tree()->GetViewportSelection(&output);
2040   EXPECT_EQ(input.start.type, output.start.type());
2041   auto expected_output_edge_start = gfx::PointF(input.start.edge_start);
2042   auto expected_output_edge_end = gfx::PointF(input.start.edge_end);
2043   expected_output_edge_start.Scale(page_scale_factor);
2044   expected_output_edge_end.Scale(page_scale_factor);
2045   EXPECT_EQ(expected_output_edge_start, output.start.edge_start());
2046   EXPECT_EQ(expected_output_edge_end, output.start.edge_end());
2047   EXPECT_EQ(expected_output_edge_start, output.start.visible_edge_start());
2048   EXPECT_EQ(expected_output_edge_end, output.start.visible_edge_end());
2049   EXPECT_TRUE(output.start.visible());
2050   EXPECT_EQ(input.end.type, output.end.type());
2051 
2052   expected_output_edge_start = gfx::PointF(input.end.edge_start);
2053   expected_output_edge_end = gfx::PointF(input.end.edge_end);
2054   expected_output_edge_start.Offset(sub_layer_offset.x(), sub_layer_offset.y());
2055   expected_output_edge_end.Offset(sub_layer_offset.x(), sub_layer_offset.y());
2056   expected_output_edge_start.Scale(page_scale_factor);
2057   expected_output_edge_end.Scale(page_scale_factor);
2058   EXPECT_EQ(expected_output_edge_start, output.end.edge_start());
2059   EXPECT_EQ(expected_output_edge_end, output.end.edge_end());
2060   EXPECT_EQ(expected_output_edge_start, output.end.visible_edge_start());
2061   EXPECT_EQ(expected_output_edge_end, output.end.visible_edge_end());
2062   EXPECT_TRUE(output.end.visible());
2063 }
2064 
TEST_F(LayerTreeImplTest,SelectionBoundsForDSFEnabled)2065 TEST_F(LayerTreeImplTest, SelectionBoundsForDSFEnabled) {
2066   LayerImpl* root = root_layer();
2067   root->SetDrawsContent(true);
2068   root->SetBounds(gfx::Size(100, 100));
2069   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
2070 
2071   gfx::Vector2dF sub_layer_offset(10, 0);
2072   LayerImpl* sub_layer = AddLayer<LayerImpl>();
2073   sub_layer->SetBounds(gfx::Size(50, 50));
2074   sub_layer->SetDrawsContent(true);
2075   CopyProperties(root, sub_layer);
2076   sub_layer->SetOffsetToTransformParent(sub_layer_offset);
2077 
2078   UpdateDrawProperties(host_impl().active_tree());
2079 
2080   float device_scale_factor = 3.f;
2081   float painted_device_scale_factor = 5.f;
2082   host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor);
2083   host_impl().active_tree()->set_painted_device_scale_factor(
2084       painted_device_scale_factor);
2085 
2086   LayerSelection input;
2087   input.start.type = gfx::SelectionBound::LEFT;
2088   input.start.edge_start = gfx::Point(10, 10);
2089   input.start.edge_end = gfx::Point(10, 30);
2090   input.start.layer_id = root->id();
2091 
2092   input.end.type = gfx::SelectionBound::RIGHT;
2093   input.end.edge_start = gfx::Point(0, 0);
2094   input.end.edge_end = gfx::Point(0, 20);
2095   input.end.layer_id = sub_layer->id();
2096   host_impl().active_tree()->RegisterSelection(input);
2097 
2098   // The viewport bounds should be properly scaled by the page scale, but should
2099   // remain in DIP coordinates.
2100   viz::Selection<gfx::SelectionBound> output;
2101   host_impl().active_tree()->GetViewportSelection(&output);
2102   EXPECT_EQ(input.start.type, output.start.type());
2103   auto expected_output_edge_start = gfx::PointF(input.start.edge_start);
2104   auto expected_output_edge_end = gfx::PointF(input.start.edge_end);
2105   expected_output_edge_start.Scale(
2106       1.f / (device_scale_factor * painted_device_scale_factor));
2107   expected_output_edge_end.Scale(
2108       1.f / (device_scale_factor * painted_device_scale_factor));
2109   EXPECT_EQ(expected_output_edge_start, output.start.edge_start());
2110   EXPECT_EQ(expected_output_edge_end, output.start.edge_end());
2111   EXPECT_EQ(expected_output_edge_start, output.start.visible_edge_start());
2112   EXPECT_EQ(expected_output_edge_end, output.start.visible_edge_end());
2113   EXPECT_TRUE(output.start.visible());
2114   EXPECT_EQ(input.end.type, output.end.type());
2115 
2116   expected_output_edge_start = gfx::PointF(input.end.edge_start);
2117   expected_output_edge_end = gfx::PointF(input.end.edge_end);
2118   expected_output_edge_start.Offset(sub_layer_offset.x(), sub_layer_offset.y());
2119   expected_output_edge_end.Offset(sub_layer_offset.x(), sub_layer_offset.y());
2120   expected_output_edge_start.Scale(
2121       1.f / (device_scale_factor * painted_device_scale_factor));
2122   expected_output_edge_end.Scale(
2123       1.f / (device_scale_factor * painted_device_scale_factor));
2124   EXPECT_EQ(expected_output_edge_start, output.end.edge_start());
2125   EXPECT_EQ(expected_output_edge_end, output.end.edge_end());
2126   EXPECT_EQ(expected_output_edge_start, output.end.visible_edge_start());
2127   EXPECT_EQ(expected_output_edge_end, output.end.visible_edge_end());
2128   EXPECT_TRUE(output.end.visible());
2129 }
2130 
TEST_F(LayerTreeImplTest,SelectionBoundsWithLargeTransforms)2131 TEST_F(LayerTreeImplTest, SelectionBoundsWithLargeTransforms) {
2132   LayerImpl* root = root_layer();
2133   root->SetBounds(gfx::Size(100, 100));
2134 
2135   gfx::Transform large_transform;
2136   large_transform.Scale(SkDoubleToScalar(1e37), SkDoubleToScalar(1e37));
2137   large_transform.RotateAboutYAxis(30);
2138 
2139   LayerImpl* child = AddLayer<LayerImpl>();
2140   child->SetBounds(gfx::Size(100, 100));
2141   CopyProperties(root, child);
2142   CreateTransformNode(child).local = large_transform;
2143 
2144   LayerImpl* grand_child = AddLayer<LayerImpl>();
2145   grand_child->SetBounds(gfx::Size(100, 100));
2146   grand_child->SetDrawsContent(true);
2147   CopyProperties(child, grand_child);
2148   CreateTransformNode(grand_child).local = large_transform;
2149 
2150   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
2151   UpdateDrawProperties(host_impl().active_tree());
2152 
2153   LayerSelection input;
2154 
2155   input.start.type = gfx::SelectionBound::LEFT;
2156   input.start.edge_start = gfx::Point(10, 10);
2157   input.start.edge_end = gfx::Point(10, 20);
2158   input.start.layer_id = grand_child->id();
2159 
2160   input.end.type = gfx::SelectionBound::RIGHT;
2161   input.end.edge_start = gfx::Point(50, 10);
2162   input.end.edge_end = gfx::Point(50, 30);
2163   input.end.layer_id = grand_child->id();
2164 
2165   host_impl().active_tree()->RegisterSelection(input);
2166 
2167   viz::Selection<gfx::SelectionBound> output;
2168   host_impl().active_tree()->GetViewportSelection(&output);
2169 
2170   // edge_end and edge_start aren't allowed to have NaNs, so the selection
2171   // should be empty.
2172   EXPECT_EQ(gfx::SelectionBound(), output.start);
2173   EXPECT_EQ(gfx::SelectionBound(), output.end);
2174 }
2175 
TEST_F(LayerTreeImplTest,NumLayersTestOne)2176 TEST_F(LayerTreeImplTest, NumLayersTestOne) {
2177   // Root is created by the test harness.
2178   EXPECT_EQ(1u, host_impl().active_tree()->NumLayers());
2179   EXPECT_TRUE(root_layer());
2180   // Create another layer, should increment.
2181   AddLayer<LayerImpl>();
2182   EXPECT_EQ(2u, host_impl().active_tree()->NumLayers());
2183 }
2184 
TEST_F(LayerTreeImplTest,NumLayersSmallTree)2185 TEST_F(LayerTreeImplTest, NumLayersSmallTree) {
2186   EXPECT_EQ(1u, host_impl().active_tree()->NumLayers());
2187   AddLayer<LayerImpl>();
2188   AddLayer<LayerImpl>();
2189   AddLayer<LayerImpl>();
2190   EXPECT_EQ(4u, host_impl().active_tree()->NumLayers());
2191 }
2192 
TEST_F(LayerTreeImplTest,DeviceScaleFactorNeedsDrawPropertiesUpdate)2193 TEST_F(LayerTreeImplTest, DeviceScaleFactorNeedsDrawPropertiesUpdate) {
2194   host_impl().active_tree()->UpdateDrawProperties();
2195   EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties());
2196   host_impl().active_tree()->SetDeviceScaleFactor(1.f);
2197   EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties());
2198   host_impl().active_tree()->SetDeviceScaleFactor(2.f);
2199   EXPECT_TRUE(host_impl().active_tree()->needs_update_draw_properties());
2200 }
2201 
TEST_F(LayerTreeImplTest,RasterColorSpaceDoesNotNeedDrawPropertiesUpdate)2202 TEST_F(LayerTreeImplTest, RasterColorSpaceDoesNotNeedDrawPropertiesUpdate) {
2203   host_impl().active_tree()->SetRasterColorSpace(
2204       gfx::ColorSpace::CreateXYZD50());
2205   host_impl().active_tree()->UpdateDrawProperties();
2206   EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties());
2207   host_impl().active_tree()->SetRasterColorSpace(gfx::ColorSpace::CreateSRGB());
2208   EXPECT_FALSE(host_impl().active_tree()->needs_update_draw_properties());
2209 }
2210 
TEST_F(LayerTreeImplTest,HitTestingCorrectLayerWheelListener)2211 TEST_F(LayerTreeImplTest, HitTestingCorrectLayerWheelListener) {
2212   host_impl().active_tree()->set_event_listener_properties(
2213       EventListenerClass::kMouseWheel, EventListenerProperties::kBlocking);
2214 
2215   LayerImpl* root = root_layer();
2216   LayerImpl* top = AddLayer<LayerImpl>();
2217   LayerImpl* left_child = AddLayer<LayerImpl>();
2218   LayerImpl* right_child = AddLayer<LayerImpl>();
2219 
2220   {
2221     gfx::Transform translate_z;
2222     translate_z.Translate3d(0, 0, 10);
2223     top->SetBounds(gfx::Size(100, 100));
2224     top->SetDrawsContent(true);
2225     top->SetHitTestable(true);
2226     CopyProperties(root, top);
2227     CreateTransformNode(top).local = translate_z;
2228   }
2229   {
2230     gfx::Transform translate_z;
2231     translate_z.Translate3d(0, 0, 10);
2232     left_child->SetBounds(gfx::Size(100, 100));
2233     left_child->SetDrawsContent(true);
2234     left_child->SetHitTestable(true);
2235     CopyProperties(top, left_child);
2236     CreateTransformNode(left_child).local = translate_z;
2237   }
2238   {
2239     gfx::Transform translate_z;
2240     translate_z.Translate3d(0, 0, 10);
2241     right_child->SetBounds(gfx::Size(100, 100));
2242     CopyProperties(top, right_child);
2243     CreateTransformNode(right_child).local = translate_z;
2244   }
2245 
2246   host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
2247   UpdateDrawProperties(host_impl().active_tree());
2248   CHECK_EQ(1u, GetRenderSurfaceList().size());
2249 
2250   gfx::PointF test_point = gfx::PointF(1.f, 1.f);
2251   LayerImpl* result_layer =
2252       host_impl().active_tree()->FindLayerThatIsHitByPoint(test_point);
2253 
2254   EXPECT_EQ(left_child, result_layer);
2255 }
2256 
2257 namespace {
2258 
2259 class PersistentSwapPromise
2260     : public SwapPromise,
2261       public base::SupportsWeakPtr<PersistentSwapPromise> {
2262  public:
2263   PersistentSwapPromise() = default;
2264   ~PersistentSwapPromise() override = default;
2265 
DidActivate()2266   void DidActivate() override {}
2267   MOCK_METHOD1(WillSwap, void(viz::CompositorFrameMetadata* metadata));
2268   MOCK_METHOD0(DidSwap, void());
2269 
DidNotSwap(DidNotSwapReason reason)2270   DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
2271     return DidNotSwapAction::KEEP_ACTIVE;
2272   }
2273 
OnCommit()2274   void OnCommit() override {}
TraceId() const2275   int64_t TraceId() const override { return 0; }
2276 };
2277 
2278 class NotPersistentSwapPromise
2279     : public SwapPromise,
2280       public base::SupportsWeakPtr<NotPersistentSwapPromise> {
2281  public:
2282   NotPersistentSwapPromise() = default;
2283   ~NotPersistentSwapPromise() override = default;
2284 
DidActivate()2285   void DidActivate() override {}
WillSwap(viz::CompositorFrameMetadata * metadata)2286   void WillSwap(viz::CompositorFrameMetadata* metadata) override {}
DidSwap()2287   void DidSwap() override {}
2288 
DidNotSwap(DidNotSwapReason reason)2289   DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override {
2290     return DidNotSwapAction::BREAK_PROMISE;
2291   }
2292 
OnCommit()2293   void OnCommit() override {}
TraceId() const2294   int64_t TraceId() const override { return 0; }
2295 };
2296 
2297 }  // namespace
2298 
TEST_F(LayerTreeImplTest,PersistentSwapPromisesAreKeptAlive)2299 TEST_F(LayerTreeImplTest, PersistentSwapPromisesAreKeptAlive) {
2300   const size_t promises_count = 2;
2301 
2302   std::vector<base::WeakPtr<PersistentSwapPromise>> persistent_promises;
2303   std::vector<std::unique_ptr<PersistentSwapPromise>>
2304       persistent_promises_to_pass;
2305   for (size_t i = 0; i < promises_count; ++i) {
2306     persistent_promises_to_pass.push_back(
2307         std::make_unique<PersistentSwapPromise>());
2308   }
2309 
2310   for (auto& promise : persistent_promises_to_pass) {
2311     persistent_promises.push_back(promise->AsWeakPtr());
2312     host_impl().active_tree()->QueueSwapPromise(std::move(promise));
2313   }
2314 
2315   std::vector<std::unique_ptr<SwapPromise>> promises;
2316   host_impl().active_tree()->PassSwapPromises(std::move(promises));
2317   host_impl().active_tree()->BreakSwapPromises(
2318       SwapPromise::DidNotSwapReason::SWAP_FAILS);
2319 
2320   ASSERT_EQ(promises_count, persistent_promises.size());
2321   for (size_t i = 0; i < persistent_promises.size(); ++i) {
2322     SCOPED_TRACE(testing::Message() << "While checking case #" << i);
2323     ASSERT_TRUE(persistent_promises[i]);
2324     EXPECT_CALL(*persistent_promises[i], WillSwap(testing::_));
2325   }
2326   host_impl().active_tree()->FinishSwapPromises(nullptr);
2327 }
2328 
TEST_F(LayerTreeImplTest,NotPersistentSwapPromisesAreDroppedWhenSwapFails)2329 TEST_F(LayerTreeImplTest, NotPersistentSwapPromisesAreDroppedWhenSwapFails) {
2330   const size_t promises_count = 2;
2331 
2332   std::vector<base::WeakPtr<NotPersistentSwapPromise>> not_persistent_promises;
2333   std::vector<std::unique_ptr<NotPersistentSwapPromise>>
2334       not_persistent_promises_to_pass;
2335   for (size_t i = 0; i < promises_count; ++i) {
2336     not_persistent_promises_to_pass.push_back(
2337         std::make_unique<NotPersistentSwapPromise>());
2338   }
2339 
2340   for (auto& promise : not_persistent_promises_to_pass) {
2341     not_persistent_promises.push_back(promise->AsWeakPtr());
2342     host_impl().active_tree()->QueueSwapPromise(std::move(promise));
2343   }
2344   std::vector<std::unique_ptr<SwapPromise>> promises;
2345   host_impl().active_tree()->PassSwapPromises(std::move(promises));
2346 
2347   ASSERT_EQ(promises_count, not_persistent_promises.size());
2348   for (size_t i = 0; i < not_persistent_promises.size(); ++i) {
2349     EXPECT_FALSE(not_persistent_promises[i]) << "While checking case #" << i;
2350   }
2351 
2352   // Finally, check that not persistent promise doesn't survive
2353   // |LayerTreeImpl::BreakSwapPromises|.
2354   {
2355     std::unique_ptr<NotPersistentSwapPromise> promise(
2356         new NotPersistentSwapPromise());
2357     auto weak_promise = promise->AsWeakPtr();
2358     host_impl().active_tree()->QueueSwapPromise(std::move(promise));
2359     host_impl().active_tree()->BreakSwapPromises(
2360         SwapPromise::DidNotSwapReason::SWAP_FAILS);
2361     EXPECT_FALSE(weak_promise);
2362   }
2363 }
2364 
TEST_F(LayerTreeImplTest,TrackPictureLayersWithPaintWorklets)2365 TEST_F(LayerTreeImplTest, TrackPictureLayersWithPaintWorklets) {
2366   host_impl().CreatePendingTree();
2367   LayerTreeImpl* pending_tree = host_impl().pending_tree();
2368 
2369   // Initially there are no layers in the set.
2370   EXPECT_EQ(pending_tree->picture_layers_with_paint_worklets().size(), 0u);
2371 
2372   auto* root = EnsureRootLayerInPendingTree();
2373   root->SetBounds(gfx::Size(100, 100));
2374 
2375   // Add three layers; two with PaintWorklets and one without.
2376   auto* child1 = AddLayerInPendingTree<PictureLayerImpl>();
2377   child1->SetBounds(gfx::Size(100, 100));
2378   auto* child2 = AddLayerInPendingTree<PictureLayerImpl>();
2379   child2->SetBounds(gfx::Size(100, 100));
2380   auto* child3 = AddLayerInPendingTree<PictureLayerImpl>();
2381   child3->SetBounds(gfx::Size(100, 100));
2382 
2383   CopyProperties(root, child1);
2384   CopyProperties(root, child2);
2385   CopyProperties(root, child3);
2386 
2387   Region empty_invalidation;
2388   scoped_refptr<RasterSource> raster_source1(
2389       FakeRasterSource::CreateFilledWithPaintWorklet(child1->bounds()));
2390   child1->UpdateRasterSource(raster_source1, &empty_invalidation, nullptr,
2391                              nullptr);
2392   scoped_refptr<RasterSource> raster_source3(
2393       FakeRasterSource::CreateFilledWithPaintWorklet(child3->bounds()));
2394   child3->UpdateRasterSource(raster_source3, &empty_invalidation, nullptr,
2395                              nullptr);
2396 
2397   // The set should correctly track which layers are in it.
2398   const base::flat_set<PictureLayerImpl*>& layers =
2399       pending_tree->picture_layers_with_paint_worklets();
2400   EXPECT_EQ(layers.size(), 2u);
2401   EXPECT_TRUE(layers.contains(child1));
2402   EXPECT_TRUE(layers.contains(child3));
2403 
2404   // Test explicitly removing a layer from the set.
2405   scoped_refptr<RasterSource> empty_raster_source(
2406       FakeRasterSource::CreateFilled(child1->bounds()));
2407   child1->UpdateRasterSource(empty_raster_source, &empty_invalidation, nullptr,
2408                              nullptr);
2409   EXPECT_EQ(layers.size(), 1u);
2410   EXPECT_FALSE(layers.contains(child1));
2411 
2412   pending_tree->DetachLayers();
2413   EXPECT_EQ(layers.size(), 0u);
2414 }
2415 
2416 namespace {
2417 class CommitToPendingTreeLayerTreeImplTestSettings : public LayerListSettings {
2418  public:
CommitToPendingTreeLayerTreeImplTestSettings()2419   CommitToPendingTreeLayerTreeImplTestSettings() {
2420     commit_to_active_tree = false;
2421   }
2422 };
2423 
2424 class CommitToPendingTreeLayerTreeImplTest : public LayerTreeImplTest {
2425  public:
CommitToPendingTreeLayerTreeImplTest()2426   CommitToPendingTreeLayerTreeImplTest()
2427       : LayerTreeImplTest(CommitToPendingTreeLayerTreeImplTestSettings()) {}
2428 };
2429 }  // namespace
2430 
TEST_F(CommitToPendingTreeLayerTreeImplTest,ElementIdToAnimationMapsTrackOnlyOnSyncTree)2431 TEST_F(CommitToPendingTreeLayerTreeImplTest,
2432        ElementIdToAnimationMapsTrackOnlyOnSyncTree) {
2433   ASSERT_FALSE(host_impl().CommitToActiveTree());
2434 
2435   // When we have a pending tree (e.g. commit_to_active_tree is false), the
2436   // various ElementId to animation maps should not track anything for the
2437   // active tree (as they are only used on the sync tree).
2438   LayerTreeImpl* active_tree = host_impl().active_tree();
2439   UpdateDrawProperties(active_tree);
2440   LayerImpl* active_root = active_tree->root_layer();
2441 
2442   auto& active_opacity_map =
2443       active_tree->element_id_to_opacity_animations_for_testing();
2444   ASSERT_EQ(active_opacity_map.size(), 0u);
2445   active_tree->SetOpacityMutated(active_root->element_id(), 0.5f);
2446   EXPECT_EQ(active_opacity_map.size(), 0u);
2447 
2448   auto& active_transform_map =
2449       active_tree->element_id_to_transform_animations_for_testing();
2450   ASSERT_EQ(active_transform_map.size(), 0u);
2451   active_tree->SetTransformMutated(active_root->element_id(), gfx::Transform());
2452   EXPECT_EQ(active_transform_map.size(), 0u);
2453 
2454   auto& active_filter_map =
2455       active_tree->element_id_to_filter_animations_for_testing();
2456   ASSERT_EQ(active_filter_map.size(), 0u);
2457   active_tree->SetFilterMutated(active_root->element_id(), FilterOperations());
2458   EXPECT_EQ(active_filter_map.size(), 0u);
2459 
2460   // The pending/recycle tree however should track them. Here we need two nodes
2461   // (the root and a child) as we will be adding entries for both the pending
2462   // and recycle tree cases.
2463   host_impl().CreatePendingTree();
2464   LayerTreeImpl* pending_tree = host_impl().pending_tree();
2465   LayerImpl* pending_root = EnsureRootLayerInPendingTree();
2466   pending_root->SetBounds(gfx::Size(1, 1));
2467   LayerImpl* child = AddLayerInPendingTree<LayerImpl>();
2468   pending_tree->SetElementIdsForTesting();
2469 
2470   // A scale transform forces a TransformNode.
2471   gfx::Transform scale3d;
2472   scale3d.Scale3d(1, 1, 0.5);
2473   CopyProperties(pending_root, child);
2474   CreateTransformNode(child).local = scale3d;
2475   // A non-one opacity forces an EffectNode.
2476   CreateEffectNode(child).opacity = 0.9f;
2477 
2478   UpdateDrawProperties(pending_tree);
2479 
2480   auto& pending_opacity_map =
2481       pending_tree->element_id_to_opacity_animations_for_testing();
2482   ASSERT_EQ(pending_opacity_map.size(), 0u);
2483   pending_tree->SetOpacityMutated(pending_root->element_id(), 0.5f);
2484   EXPECT_EQ(pending_opacity_map.size(), 1u);
2485 
2486   auto& pending_transform_map =
2487       pending_tree->element_id_to_transform_animations_for_testing();
2488   ASSERT_EQ(pending_transform_map.size(), 0u);
2489   pending_tree->SetTransformMutated(pending_root->element_id(),
2490                                     gfx::Transform());
2491   EXPECT_EQ(pending_transform_map.size(), 1u);
2492 
2493   auto& pending_filter_map =
2494       pending_tree->element_id_to_filter_animations_for_testing();
2495   ASSERT_EQ(pending_filter_map.size(), 0u);
2496   pending_tree->SetFilterMutated(pending_root->element_id(),
2497                                  FilterOperations());
2498   EXPECT_EQ(pending_filter_map.size(), 1u);
2499 
2500   // Finally, check the recycle tree - this should still track them.
2501   host_impl().ActivateSyncTree();
2502   LayerTreeImpl* recycle_tree = host_impl().recycle_tree();
2503   ASSERT_TRUE(recycle_tree);
2504 
2505   auto& recycle_opacity_map =
2506       recycle_tree->element_id_to_opacity_animations_for_testing();
2507   ASSERT_EQ(recycle_opacity_map.size(), 1u);
2508   recycle_tree->SetOpacityMutated(child->element_id(), 0.5f);
2509   EXPECT_EQ(recycle_opacity_map.size(), 2u);
2510 
2511   auto& recycle_transform_map =
2512       recycle_tree->element_id_to_transform_animations_for_testing();
2513   ASSERT_EQ(recycle_transform_map.size(), 1u);
2514   recycle_tree->SetTransformMutated(child->element_id(), gfx::Transform());
2515   EXPECT_EQ(recycle_transform_map.size(), 2u);
2516 
2517   auto& recycle_filter_map =
2518       recycle_tree->element_id_to_filter_animations_for_testing();
2519   ASSERT_EQ(recycle_filter_map.size(), 1u);
2520   recycle_tree->SetFilterMutated(child->element_id(), FilterOperations());
2521   EXPECT_EQ(recycle_filter_map.size(), 2u);
2522 }
2523 
TEST_F(LayerTreeImplTest,ElementIdToAnimationMapsTrackOnlyOnSyncTree)2524 TEST_F(LayerTreeImplTest, ElementIdToAnimationMapsTrackOnlyOnSyncTree) {
2525   ASSERT_TRUE(host_impl().CommitToActiveTree());
2526 
2527   // When we are commiting directly to the active tree, the various ElementId to
2528   // animation maps should track on the active tree (as it is the sync tree, and
2529   // they are used on the sync tree).
2530   LayerTreeImpl* active_tree = host_impl().active_tree();
2531   UpdateDrawProperties(active_tree);
2532   LayerImpl* root = active_tree->root_layer();
2533 
2534   auto& opacity_map =
2535       active_tree->element_id_to_opacity_animations_for_testing();
2536   ASSERT_EQ(opacity_map.size(), 0u);
2537   active_tree->SetOpacityMutated(root->element_id(), 0.5f);
2538   EXPECT_EQ(opacity_map.size(), 1u);
2539 
2540   auto& transform_map =
2541       active_tree->element_id_to_transform_animations_for_testing();
2542   ASSERT_EQ(transform_map.size(), 0u);
2543   active_tree->SetTransformMutated(root->element_id(), gfx::Transform());
2544   EXPECT_EQ(transform_map.size(), 1u);
2545 
2546   auto& filter_map = active_tree->element_id_to_filter_animations_for_testing();
2547   ASSERT_EQ(filter_map.size(), 0u);
2548   active_tree->SetFilterMutated(root->element_id(), FilterOperations());
2549   EXPECT_EQ(filter_map.size(), 1u);
2550 }
2551 
TEST_F(LayerTreeImplTest,FrameElementIdHitTestSimple)2552 TEST_F(LayerTreeImplTest, FrameElementIdHitTestSimple) {
2553   LayerImpl* frame_layer = AddLayer<LayerImpl>();
2554   frame_layer->SetBounds(gfx::Size(50, 50));
2555   frame_layer->SetDrawsContent(true);
2556   frame_layer->SetHitTestable(true);
2557   frame_layer->SetFrameElementId(ElementId(0x10));
2558   CopyProperties(root_layer(), frame_layer);
2559 
2560   UpdateDrawProperties(host_impl().active_tree());
2561 
2562   EXPECT_EQ(host_impl().FindFrameElementIdAtPoint(gfx::PointF(10, 10)),
2563             ElementId(0x10));
2564 }
2565 
TEST_F(LayerTreeImplTest,FrameElementIdHitTestOverlap)2566 TEST_F(LayerTreeImplTest, FrameElementIdHitTestOverlap) {
2567   LayerImpl* frame_layer = AddLayer<LayerImpl>();
2568   frame_layer->SetBounds(gfx::Size(50, 50));
2569   frame_layer->SetHitTestable(true);
2570   frame_layer->SetFrameElementId(ElementId(0x10));
2571   CopyProperties(root_layer(), frame_layer);
2572 
2573   LayerImpl* occluding_frame_layer = AddLayer<LayerImpl>();
2574   occluding_frame_layer->SetBounds(gfx::Size(50, 50));
2575   occluding_frame_layer->SetHitTestable(true);
2576   occluding_frame_layer->SetFrameElementId(ElementId(0x20));
2577   CopyProperties(root_layer(), occluding_frame_layer);
2578   occluding_frame_layer->SetOffsetToTransformParent(gfx::Vector2dF(25, 25));
2579 
2580   UpdateDrawProperties(host_impl().active_tree());
2581 
2582   EXPECT_EQ(host_impl().FindFrameElementIdAtPoint(gfx::PointF(30, 30)),
2583             ElementId(0x20));
2584 }
2585 
TEST_F(LayerTreeImplTest,FrameElementIdHitTestOverlapSimpleClip)2586 TEST_F(LayerTreeImplTest, FrameElementIdHitTestOverlapSimpleClip) {
2587   LayerImpl* frame_layer = AddLayer<LayerImpl>();
2588   frame_layer->SetBounds(gfx::Size(50, 50));
2589   frame_layer->SetHitTestable(true);
2590   frame_layer->SetFrameElementId(ElementId(0x10));
2591   CopyProperties(root_layer(), frame_layer);
2592 
2593   LayerImpl* clipped_frame_layer = AddLayer<LayerImpl>();
2594   clipped_frame_layer->SetBounds(gfx::Size(50, 50));
2595   clipped_frame_layer->SetHitTestable(true);
2596   clipped_frame_layer->SetFrameElementId(ElementId(0x20));
2597   CopyProperties(root_layer(), clipped_frame_layer);
2598   clipped_frame_layer->SetOffsetToTransformParent(gfx::Vector2dF(25, 25));
2599 
2600   // Create a clip excluding the overlapped region.
2601   auto& clip_node = CreateClipNode(clipped_frame_layer);
2602   clip_node.clip = gfx::RectF(40, 40, 10, 10);
2603 
2604   UpdateDrawProperties(host_impl().active_tree());
2605 
2606   // Ensure that the overlapping (clipped) layer isn't targeted.
2607   EXPECT_EQ(host_impl().FindFrameElementIdAtPoint(gfx::PointF(30, 30)),
2608             ElementId(0x10));
2609 }
2610 
TEST_F(LayerTreeImplTest,FrameElementIdHitTestOverlapRoundedCorners)2611 TEST_F(LayerTreeImplTest, FrameElementIdHitTestOverlapRoundedCorners) {
2612   LayerImpl* frame_layer = AddLayer<LayerImpl>();
2613   frame_layer->SetBounds(gfx::Size(50, 50));
2614   frame_layer->SetHitTestable(true);
2615   frame_layer->SetFrameElementId(ElementId(0x10));
2616   CopyProperties(root_layer(), frame_layer);
2617 
2618   LayerImpl* rounded_frame_layer = AddLayer<LayerImpl>();
2619   rounded_frame_layer->SetBounds(gfx::Size(50, 50));
2620   rounded_frame_layer->SetHitTestable(true);
2621   rounded_frame_layer->SetFrameElementId(ElementId(0x20));
2622   CopyProperties(root_layer(), rounded_frame_layer);
2623   rounded_frame_layer->SetOffsetToTransformParent(gfx::Vector2dF(25, 25));
2624 
2625   // Add rounded corners to the layer, which are unable to be hit tested by the
2626   // simple quad-based logic.
2627   CreateEffectNode(rounded_frame_layer).rounded_corner_bounds =
2628       gfx::RRectF(25, 25, 50, 50, 5);
2629 
2630   UpdateDrawProperties(host_impl().active_tree());
2631 
2632   // The lookup should bail out in the presence of a complex clip/mask on the
2633   // target chain.
2634   EXPECT_FALSE(host_impl().FindFrameElementIdAtPoint(gfx::PointF(30, 30)));
2635 }
2636 
2637 class LayerTreeImplOcclusionSettings : public LayerListSettings {
2638  public:
LayerTreeImplOcclusionSettings(bool enabled)2639   explicit LayerTreeImplOcclusionSettings(bool enabled) {
2640     enable_occlusion = enabled;
2641     minimum_occlusion_tracking_size = gfx::Size(1, 1);
2642   }
2643 };
2644 
2645 class LayerTreeImplOcclusionTest : public LayerTreeImplTest {
2646  public:
LayerTreeImplOcclusionTest(bool enable_occlusion)2647   explicit LayerTreeImplOcclusionTest(bool enable_occlusion)
2648       : LayerTreeImplTest(LayerTreeImplOcclusionSettings(enable_occlusion)),
2649         enable_occlusion_(enable_occlusion) {}
2650 
TestOcclusion()2651   void TestOcclusion() {
2652     LayerImpl* root = root_layer();
2653     root->SetBounds(gfx::Size(100, 100));
2654 
2655     // Create a 50x50 layer in the center of our root bounds.
2656     LayerImpl* bottom_layer = AddLayer<LayerImpl>();
2657     bottom_layer->SetBounds(gfx::Size(50, 50));
2658     bottom_layer->SetDrawsContent(true);
2659     bottom_layer->SetContentsOpaque(true);
2660     CopyProperties(root, bottom_layer);
2661     bottom_layer->SetOffsetToTransformParent(gfx::Vector2dF(25, 25));
2662 
2663     // Create a full-bounds 100x100 layer which occludes the 50x50 layer.
2664     LayerImpl* occluding_layer = AddLayer<LayerImpl>();
2665     occluding_layer->SetBounds(gfx::Size(100, 100));
2666     occluding_layer->SetDrawsContent(true);
2667     occluding_layer->SetContentsOpaque(true);
2668     CopyProperties(root, occluding_layer);
2669 
2670     host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
2671     UpdateDrawProperties(host_impl().active_tree());
2672 
2673     LayerTreeImpl* active_tree = host_impl().active_tree();
2674     if (enable_occlusion_) {
2675       // With occlusion on, the root is fully occluded, as is the bottom layer.
2676       EXPECT_TRUE(active_tree->UnoccludedScreenSpaceRegion().IsEmpty());
2677       EXPECT_TRUE(bottom_layer->draw_properties()
2678                       .occlusion_in_content_space.HasOcclusion());
2679     } else {
2680       // With occlusion off, the full root should be unoccluded and the bottom
2681       // layer should have no occlusion.
2682       EXPECT_TRUE(active_tree->UnoccludedScreenSpaceRegion().Contains(
2683           gfx::Rect(root->bounds())));
2684       EXPECT_FALSE(bottom_layer->draw_properties()
2685                        .occlusion_in_content_space.HasOcclusion());
2686     }
2687   }
2688 
2689  private:
2690   bool enable_occlusion_;
2691 };
2692 
2693 class LayerTreeImplOcclusionDisabledTest : public LayerTreeImplOcclusionTest {
2694  public:
LayerTreeImplOcclusionDisabledTest()2695   LayerTreeImplOcclusionDisabledTest() : LayerTreeImplOcclusionTest(false) {}
2696 };
2697 
2698 class LayerTreeImplOcclusionEnabledTest : public LayerTreeImplOcclusionTest {
2699  public:
LayerTreeImplOcclusionEnabledTest()2700   LayerTreeImplOcclusionEnabledTest() : LayerTreeImplOcclusionTest(true) {}
2701 };
2702 
TEST_F(LayerTreeImplOcclusionDisabledTest,OcclusionDisabled)2703 TEST_F(LayerTreeImplOcclusionDisabledTest, OcclusionDisabled) {
2704   TestOcclusion();
2705 }
2706 
TEST_F(LayerTreeImplOcclusionEnabledTest,OcclusionEnabled)2707 TEST_F(LayerTreeImplOcclusionEnabledTest, OcclusionEnabled) {
2708   TestOcclusion();
2709 }
2710 
2711 }  // namespace
2712 }  // namespace cc
2713