1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/trees/layer_tree_host_common.h"
6
7 #include <set>
8
9 #include "cc/animation/layer_animation_controller.h"
10 #include "cc/base/math_util.h"
11 #include "cc/layers/content_layer.h"
12 #include "cc/layers/content_layer_client.h"
13 #include "cc/layers/heads_up_display_layer_impl.h"
14 #include "cc/layers/layer.h"
15 #include "cc/layers/layer_client.h"
16 #include "cc/layers/layer_impl.h"
17 #include "cc/layers/render_surface.h"
18 #include "cc/layers/render_surface_impl.h"
19 #include "cc/output/copy_output_request.h"
20 #include "cc/output/copy_output_result.h"
21 #include "cc/test/animation_test_common.h"
22 #include "cc/test/fake_impl_proxy.h"
23 #include "cc/test/fake_layer_tree_host.h"
24 #include "cc/test/fake_layer_tree_host_impl.h"
25 #include "cc/test/geometry_test_utils.h"
26 #include "cc/trees/layer_tree_impl.h"
27 #include "cc/trees/proxy.h"
28 #include "cc/trees/single_thread_proxy.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "ui/gfx/quad_f.h"
32 #include "ui/gfx/size_conversions.h"
33 #include "ui/gfx/transform.h"
34
35 namespace cc {
36 namespace {
37
38 class LayerTreeHostCommonTestBase {
39 protected:
40 template <typename LayerType>
SetLayerPropertiesForTestingInternal(LayerType * layer,const gfx::Transform & transform,const gfx::Transform & sublayer_transform,gfx::PointF anchor,gfx::PointF position,gfx::Size bounds,bool preserves3d)41 void SetLayerPropertiesForTestingInternal(
42 LayerType* layer,
43 const gfx::Transform& transform,
44 const gfx::Transform& sublayer_transform,
45 gfx::PointF anchor,
46 gfx::PointF position,
47 gfx::Size bounds,
48 bool preserves3d) {
49 layer->SetTransform(transform);
50 layer->SetSublayerTransform(sublayer_transform);
51 layer->SetAnchorPoint(anchor);
52 layer->SetPosition(position);
53 layer->SetBounds(bounds);
54 layer->SetPreserves3d(preserves3d);
55 }
56
SetLayerPropertiesForTesting(Layer * layer,const gfx::Transform & transform,const gfx::Transform & sublayer_transform,gfx::PointF anchor,gfx::PointF position,gfx::Size bounds,bool preserves3d)57 void SetLayerPropertiesForTesting(Layer* layer,
58 const gfx::Transform& transform,
59 const gfx::Transform& sublayer_transform,
60 gfx::PointF anchor,
61 gfx::PointF position,
62 gfx::Size bounds,
63 bool preserves3d) {
64 SetLayerPropertiesForTestingInternal<Layer>(layer,
65 transform,
66 sublayer_transform,
67 anchor,
68 position,
69 bounds,
70 preserves3d);
71 }
72
SetLayerPropertiesForTesting(LayerImpl * layer,const gfx::Transform & transform,const gfx::Transform & sublayer_transform,gfx::PointF anchor,gfx::PointF position,gfx::Size bounds,bool preserves3d)73 void SetLayerPropertiesForTesting(LayerImpl* layer,
74 const gfx::Transform& transform,
75 const gfx::Transform& sublayer_transform,
76 gfx::PointF anchor,
77 gfx::PointF position,
78 gfx::Size bounds,
79 bool preserves3d) {
80 SetLayerPropertiesForTestingInternal<LayerImpl>(layer,
81 transform,
82 sublayer_transform,
83 anchor,
84 position,
85 bounds,
86 preserves3d);
87 layer->SetContentBounds(bounds);
88 }
89
ExecuteCalculateDrawProperties(Layer * root_layer,float device_scale_factor,float page_scale_factor,Layer * page_scale_application_layer,bool can_use_lcd_text)90 void ExecuteCalculateDrawProperties(Layer* root_layer,
91 float device_scale_factor,
92 float page_scale_factor,
93 Layer* page_scale_application_layer,
94 bool can_use_lcd_text) {
95 EXPECT_TRUE(page_scale_application_layer || (page_scale_factor == 1.f));
96 gfx::Transform identity_matrix;
97 gfx::Size device_viewport_size =
98 gfx::Size(root_layer->bounds().width() * device_scale_factor,
99 root_layer->bounds().height() * device_scale_factor);
100
101 render_surface_layer_list_.reset(new RenderSurfaceLayerList);
102
103 // We are probably not testing what is intended if the root_layer bounds are
104 // empty.
105 DCHECK(!root_layer->bounds().IsEmpty());
106 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
107 root_layer, device_viewport_size, render_surface_layer_list_.get());
108 inputs.device_scale_factor = device_scale_factor;
109 inputs.page_scale_factor = page_scale_factor;
110 inputs.page_scale_application_layer = page_scale_application_layer;
111 inputs.can_use_lcd_text = can_use_lcd_text;
112 inputs.can_adjust_raster_scales = true;
113 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
114 }
115
ExecuteCalculateDrawProperties(LayerImpl * root_layer,float device_scale_factor,float page_scale_factor,LayerImpl * page_scale_application_layer,bool can_use_lcd_text)116 void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
117 float device_scale_factor,
118 float page_scale_factor,
119 LayerImpl* page_scale_application_layer,
120 bool can_use_lcd_text) {
121 gfx::Transform identity_matrix;
122 LayerImplList dummy_render_surface_layer_list;
123 gfx::Size device_viewport_size =
124 gfx::Size(root_layer->bounds().width() * device_scale_factor,
125 root_layer->bounds().height() * device_scale_factor);
126
127 // We are probably not testing what is intended if the root_layer bounds are
128 // empty.
129 DCHECK(!root_layer->bounds().IsEmpty());
130 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
131 root_layer, device_viewport_size, &dummy_render_surface_layer_list);
132 inputs.device_scale_factor = device_scale_factor;
133 inputs.page_scale_factor = page_scale_factor;
134 inputs.page_scale_application_layer = page_scale_application_layer;
135 inputs.can_use_lcd_text = can_use_lcd_text;
136 inputs.can_adjust_raster_scales = true;
137 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
138 }
139
140 template <class LayerType>
ExecuteCalculateDrawProperties(LayerType * root_layer)141 void ExecuteCalculateDrawProperties(LayerType* root_layer) {
142 LayerType* page_scale_application_layer = NULL;
143 ExecuteCalculateDrawProperties(
144 root_layer, 1.f, 1.f, page_scale_application_layer, false);
145 }
146
147 template <class LayerType>
ExecuteCalculateDrawProperties(LayerType * root_layer,float device_scale_factor)148 void ExecuteCalculateDrawProperties(LayerType* root_layer,
149 float device_scale_factor) {
150 LayerType* page_scale_application_layer = NULL;
151 ExecuteCalculateDrawProperties(root_layer,
152 device_scale_factor,
153 1.f,
154 page_scale_application_layer,
155 false);
156 }
157
158 template <class LayerType>
ExecuteCalculateDrawProperties(LayerType * root_layer,float device_scale_factor,float page_scale_factor,LayerType * page_scale_application_layer)159 void ExecuteCalculateDrawProperties(LayerType* root_layer,
160 float device_scale_factor,
161 float page_scale_factor,
162 LayerType* page_scale_application_layer) {
163 ExecuteCalculateDrawProperties(root_layer,
164 device_scale_factor,
165 page_scale_factor,
166 page_scale_application_layer,
167 false);
168 }
169
render_surface_layer_list() const170 RenderSurfaceLayerList* render_surface_layer_list() const {
171 return render_surface_layer_list_.get();
172 }
173
174 private:
175 scoped_ptr<RenderSurfaceLayerList> render_surface_layer_list_;
176 };
177
178 class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase,
179 public testing::Test {
180 };
181
182 class LayerWithForcedDrawsContent : public Layer {
183 public:
LayerWithForcedDrawsContent()184 LayerWithForcedDrawsContent() : Layer() {}
185
186 virtual bool DrawsContent() const OVERRIDE;
187
188 private:
~LayerWithForcedDrawsContent()189 virtual ~LayerWithForcedDrawsContent() {}
190 };
191
DrawsContent() const192 bool LayerWithForcedDrawsContent::DrawsContent() const { return true; }
193
194 class MockContentLayerClient : public ContentLayerClient {
195 public:
MockContentLayerClient()196 MockContentLayerClient() {}
~MockContentLayerClient()197 virtual ~MockContentLayerClient() {}
PaintContents(SkCanvas * canvas,gfx::Rect clip,gfx::RectF * opaque)198 virtual void PaintContents(SkCanvas* canvas,
199 gfx::Rect clip,
200 gfx::RectF* opaque) OVERRIDE {}
DidChangeLayerCanUseLCDText()201 virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
202 };
203
CreateDrawableContentLayer(ContentLayerClient * delegate)204 scoped_refptr<ContentLayer> CreateDrawableContentLayer(
205 ContentLayerClient* delegate) {
206 scoped_refptr<ContentLayer> to_return = ContentLayer::Create(delegate);
207 to_return->SetIsDrawable(true);
208 return to_return;
209 }
210
211 #define EXPECT_CONTENTS_SCALE_EQ(expected, layer) \
212 do { \
213 EXPECT_FLOAT_EQ(expected, layer->contents_scale_x()); \
214 EXPECT_FLOAT_EQ(expected, layer->contents_scale_y()); \
215 } while (false)
216
TEST_F(LayerTreeHostCommonTest,TransformsForNoOpLayer)217 TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) {
218 // Sanity check: For layers positioned at zero, with zero size,
219 // and with identity transforms, then the draw transform,
220 // screen space transform, and the hierarchy passed on to children
221 // layers should also be identity transforms.
222
223 scoped_refptr<Layer> parent = Layer::Create();
224 scoped_refptr<Layer> child = Layer::Create();
225 scoped_refptr<Layer> grand_child = Layer::Create();
226 parent->AddChild(child);
227 child->AddChild(grand_child);
228
229 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
230 host->SetRootLayer(parent);
231
232 gfx::Transform identity_matrix;
233 SetLayerPropertiesForTesting(parent.get(),
234 identity_matrix,
235 identity_matrix,
236 gfx::PointF(),
237 gfx::PointF(),
238 gfx::Size(100, 100),
239 false);
240 SetLayerPropertiesForTesting(child.get(),
241 identity_matrix,
242 identity_matrix,
243 gfx::PointF(),
244 gfx::PointF(),
245 gfx::Size(),
246 false);
247 SetLayerPropertiesForTesting(grand_child.get(),
248 identity_matrix,
249 identity_matrix,
250 gfx::PointF(),
251 gfx::PointF(),
252 gfx::Size(),
253 false);
254
255 ExecuteCalculateDrawProperties(parent.get());
256
257 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
258 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
259 child->screen_space_transform());
260 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
261 grand_child->draw_transform());
262 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
263 grand_child->screen_space_transform());
264 }
265
TEST_F(LayerTreeHostCommonTest,TransformsForSingleLayer)266 TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) {
267 gfx::Transform identity_matrix;
268 scoped_refptr<Layer> layer = Layer::Create();
269
270 scoped_refptr<Layer> root = Layer::Create();
271 SetLayerPropertiesForTesting(root.get(),
272 identity_matrix,
273 identity_matrix,
274 gfx::PointF(),
275 gfx::PointF(),
276 gfx::Size(1, 2),
277 false);
278 root->AddChild(layer);
279
280 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
281 host->SetRootLayer(root);
282
283 // Case 1: setting the sublayer transform should not affect this layer's draw
284 // transform or screen-space transform.
285 gfx::Transform arbitrary_translation;
286 arbitrary_translation.Translate(10.0, 20.0);
287 SetLayerPropertiesForTesting(layer.get(),
288 identity_matrix,
289 arbitrary_translation,
290 gfx::PointF(),
291 gfx::PointF(),
292 gfx::Size(100, 100),
293 false);
294 ExecuteCalculateDrawProperties(root.get());
295 gfx::Transform expected_draw_transform = identity_matrix;
296 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_draw_transform,
297 layer->draw_transform());
298 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
299 layer->screen_space_transform());
300
301 // Case 2: Setting the bounds of the layer should not affect either the draw
302 // transform or the screenspace transform.
303 gfx::Transform translation_to_center;
304 translation_to_center.Translate(5.0, 6.0);
305 SetLayerPropertiesForTesting(layer.get(),
306 identity_matrix,
307 identity_matrix,
308 gfx::PointF(),
309 gfx::PointF(),
310 gfx::Size(10, 12),
311 false);
312 ExecuteCalculateDrawProperties(root.get());
313 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, layer->draw_transform());
314 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
315 layer->screen_space_transform());
316
317 // Case 3: The anchor point by itself (without a layer transform) should have
318 // no effect on the transforms.
319 SetLayerPropertiesForTesting(layer.get(),
320 identity_matrix,
321 identity_matrix,
322 gfx::PointF(0.25f, 0.25f),
323 gfx::PointF(),
324 gfx::Size(10, 12),
325 false);
326 ExecuteCalculateDrawProperties(root.get());
327 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, layer->draw_transform());
328 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
329 layer->screen_space_transform());
330
331 // Case 4: A change in actual position affects both the draw transform and
332 // screen space transform.
333 gfx::Transform position_transform;
334 position_transform.Translate(0.f, 1.2f);
335 SetLayerPropertiesForTesting(layer.get(),
336 identity_matrix,
337 identity_matrix,
338 gfx::PointF(0.25f, 0.25f),
339 gfx::PointF(0.f, 1.2f),
340 gfx::Size(10, 12),
341 false);
342 ExecuteCalculateDrawProperties(root.get());
343 EXPECT_TRANSFORMATION_MATRIX_EQ(position_transform, layer->draw_transform());
344 EXPECT_TRANSFORMATION_MATRIX_EQ(position_transform,
345 layer->screen_space_transform());
346
347 // Case 5: In the correct sequence of transforms, the layer transform should
348 // pre-multiply the translation_to_center. This is easily tested by using a
349 // scale transform, because scale and translation are not commutative.
350 gfx::Transform layer_transform;
351 layer_transform.Scale3d(2.0, 2.0, 1.0);
352 SetLayerPropertiesForTesting(layer.get(),
353 layer_transform,
354 identity_matrix,
355 gfx::PointF(),
356 gfx::PointF(),
357 gfx::Size(10, 12),
358 false);
359 ExecuteCalculateDrawProperties(root.get());
360 EXPECT_TRANSFORMATION_MATRIX_EQ(layer_transform, layer->draw_transform());
361 EXPECT_TRANSFORMATION_MATRIX_EQ(layer_transform,
362 layer->screen_space_transform());
363
364 // Case 6: The layer transform should occur with respect to the anchor point.
365 gfx::Transform translation_to_anchor;
366 translation_to_anchor.Translate(5.0, 0.0);
367 gfx::Transform expected_result =
368 translation_to_anchor * layer_transform * Inverse(translation_to_anchor);
369 SetLayerPropertiesForTesting(layer.get(),
370 layer_transform,
371 identity_matrix,
372 gfx::PointF(0.5f, 0.f),
373 gfx::PointF(),
374 gfx::Size(10, 12),
375 false);
376 ExecuteCalculateDrawProperties(root.get());
377 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result, layer->draw_transform());
378 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result,
379 layer->screen_space_transform());
380
381 // Case 7: Verify that position pre-multiplies the layer transform. The
382 // current implementation of CalculateDrawProperties does this implicitly, but
383 // it is still worth testing to detect accidental regressions.
384 expected_result = position_transform * translation_to_anchor *
385 layer_transform * Inverse(translation_to_anchor);
386 SetLayerPropertiesForTesting(layer.get(),
387 layer_transform,
388 identity_matrix,
389 gfx::PointF(0.5f, 0.f),
390 gfx::PointF(0.f, 1.2f),
391 gfx::Size(10, 12),
392 false);
393 ExecuteCalculateDrawProperties(root.get());
394 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result, layer->draw_transform());
395 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_result,
396 layer->screen_space_transform());
397 }
398
TEST_F(LayerTreeHostCommonTest,TransformsAboutScrollOffset)399 TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) {
400 const gfx::Vector2d kScrollOffset(50, 100);
401 const gfx::Vector2dF kScrollDelta(2.34f, 5.67f);
402 const gfx::Vector2d kMaxScrollOffset(200, 200);
403 const gfx::PointF kScrollLayerPosition(-kScrollOffset.x(),
404 -kScrollOffset.y());
405 const float kPageScale = 0.888f;
406 const float kDeviceScale = 1.666f;
407
408 FakeImplProxy proxy;
409 FakeLayerTreeHostImpl host_impl(&proxy);
410
411 gfx::Transform identity_matrix;
412 scoped_ptr<LayerImpl> sublayer_scoped_ptr(
413 LayerImpl::Create(host_impl.active_tree(), 1));
414 LayerImpl* sublayer = sublayer_scoped_ptr.get();
415 sublayer->SetContentsScale(kPageScale * kDeviceScale,
416 kPageScale * kDeviceScale);
417 SetLayerPropertiesForTesting(sublayer,
418 identity_matrix,
419 identity_matrix,
420 gfx::Point(),
421 gfx::PointF(),
422 gfx::Size(500, 500),
423 false);
424
425 scoped_ptr<LayerImpl> scroll_layerScopedPtr(
426 LayerImpl::Create(host_impl.active_tree(), 2));
427 LayerImpl* scroll_layer = scroll_layerScopedPtr.get();
428 SetLayerPropertiesForTesting(scroll_layer,
429 identity_matrix,
430 identity_matrix,
431 gfx::PointF(),
432 gfx::PointF(),
433 gfx::Size(10, 20),
434 false);
435 scroll_layer->SetScrollable(true);
436 scroll_layer->SetMaxScrollOffset(kMaxScrollOffset);
437 scroll_layer->SetScrollOffset(kScrollOffset);
438 scroll_layer->SetScrollDelta(kScrollDelta);
439 gfx::Transform impl_transform;
440 scroll_layer->AddChild(sublayer_scoped_ptr.Pass());
441
442 scoped_ptr<LayerImpl> root(LayerImpl::Create(host_impl.active_tree(), 3));
443 SetLayerPropertiesForTesting(root.get(),
444 identity_matrix,
445 identity_matrix,
446 gfx::PointF(),
447 gfx::PointF(),
448 gfx::Size(3, 4),
449 false);
450 root->AddChild(scroll_layerScopedPtr.Pass());
451
452 ExecuteCalculateDrawProperties(
453 root.get(), kDeviceScale, kPageScale, scroll_layer->parent());
454 gfx::Transform expected_transform = identity_matrix;
455 gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta;
456 sub_layer_screen_position.Scale(kPageScale * kDeviceScale);
457 expected_transform.Translate(MathUtil::Round(sub_layer_screen_position.x()),
458 MathUtil::Round(sub_layer_screen_position.y()));
459 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
460 sublayer->draw_transform());
461 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
462 sublayer->screen_space_transform());
463
464 gfx::Transform arbitrary_translate;
465 const float kTranslateX = 10.6f;
466 const float kTranslateY = 20.6f;
467 arbitrary_translate.Translate(kTranslateX, kTranslateY);
468 SetLayerPropertiesForTesting(scroll_layer,
469 arbitrary_translate,
470 identity_matrix,
471 gfx::PointF(),
472 gfx::PointF(),
473 gfx::Size(10, 20),
474 false);
475 ExecuteCalculateDrawProperties(
476 root.get(), kDeviceScale, kPageScale, scroll_layer->parent());
477 expected_transform.MakeIdentity();
478 expected_transform.Translate(
479 MathUtil::Round(kTranslateX * kPageScale * kDeviceScale +
480 sub_layer_screen_position.x()),
481 MathUtil::Round(kTranslateY * kPageScale * kDeviceScale +
482 sub_layer_screen_position.y()));
483 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
484 sublayer->draw_transform());
485 }
486
TEST_F(LayerTreeHostCommonTest,TransformsForSimpleHierarchy)487 TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) {
488 gfx::Transform identity_matrix;
489 scoped_refptr<Layer> root = Layer::Create();
490 scoped_refptr<Layer> parent = Layer::Create();
491 scoped_refptr<Layer> child = Layer::Create();
492 scoped_refptr<Layer> grand_child = Layer::Create();
493 root->AddChild(parent);
494 parent->AddChild(child);
495 child->AddChild(grand_child);
496
497 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
498 host->SetRootLayer(root);
499
500 // One-time setup of root layer
501 SetLayerPropertiesForTesting(root.get(),
502 identity_matrix,
503 identity_matrix,
504 gfx::PointF(),
505 gfx::PointF(),
506 gfx::Size(1, 2),
507 false);
508
509 // Case 1: parent's anchor point should not affect child or grand_child.
510 SetLayerPropertiesForTesting(parent.get(),
511 identity_matrix,
512 identity_matrix,
513 gfx::PointF(0.25f, 0.25f),
514 gfx::PointF(),
515 gfx::Size(10, 12),
516 false);
517 SetLayerPropertiesForTesting(child.get(),
518 identity_matrix,
519 identity_matrix,
520 gfx::PointF(),
521 gfx::PointF(),
522 gfx::Size(16, 18),
523 false);
524 SetLayerPropertiesForTesting(grand_child.get(),
525 identity_matrix,
526 identity_matrix,
527 gfx::PointF(),
528 gfx::PointF(),
529 gfx::Size(76, 78),
530 false);
531 ExecuteCalculateDrawProperties(root.get());
532 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
533 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
534 child->screen_space_transform());
535 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
536 grand_child->draw_transform());
537 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
538 grand_child->screen_space_transform());
539
540 // Case 2: parent's position affects child and grand_child.
541 gfx::Transform parent_position_transform;
542 parent_position_transform.Translate(0.f, 1.2f);
543 SetLayerPropertiesForTesting(parent.get(),
544 identity_matrix,
545 identity_matrix,
546 gfx::PointF(0.25f, 0.25f),
547 gfx::PointF(0.f, 1.2f),
548 gfx::Size(10, 12),
549 false);
550 SetLayerPropertiesForTesting(child.get(),
551 identity_matrix,
552 identity_matrix,
553 gfx::PointF(),
554 gfx::PointF(),
555 gfx::Size(16, 18),
556 false);
557 SetLayerPropertiesForTesting(grand_child.get(),
558 identity_matrix,
559 identity_matrix,
560 gfx::PointF(),
561 gfx::PointF(),
562 gfx::Size(76, 78),
563 false);
564 ExecuteCalculateDrawProperties(root.get());
565 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform,
566 child->draw_transform());
567 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform,
568 child->screen_space_transform());
569 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform,
570 grand_child->draw_transform());
571 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_position_transform,
572 grand_child->screen_space_transform());
573
574 // Case 3: parent's local transform affects child and grandchild
575 gfx::Transform parent_layer_transform;
576 parent_layer_transform.Scale3d(2.0, 2.0, 1.0);
577 gfx::Transform parent_translation_to_anchor;
578 parent_translation_to_anchor.Translate(2.5, 3.0);
579 gfx::Transform parent_composite_transform =
580 parent_translation_to_anchor * parent_layer_transform *
581 Inverse(parent_translation_to_anchor);
582 SetLayerPropertiesForTesting(parent.get(),
583 parent_layer_transform,
584 identity_matrix,
585 gfx::PointF(0.25f, 0.25f),
586 gfx::PointF(),
587 gfx::Size(10, 12),
588 false);
589 SetLayerPropertiesForTesting(child.get(),
590 identity_matrix,
591 identity_matrix,
592 gfx::PointF(),
593 gfx::PointF(),
594 gfx::Size(16, 18),
595 false);
596 SetLayerPropertiesForTesting(grand_child.get(),
597 identity_matrix,
598 identity_matrix,
599 gfx::PointF(),
600 gfx::PointF(),
601 gfx::Size(76, 78),
602 false);
603 ExecuteCalculateDrawProperties(root.get());
604 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
605 child->draw_transform());
606 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
607 child->screen_space_transform());
608 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
609 grand_child->draw_transform());
610 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
611 grand_child->screen_space_transform());
612
613 // Case 4: parent's sublayer matrix affects child and grandchild scaling is
614 // used here again so that the correct sequence of transforms is properly
615 // tested. Note that preserves3d is false, but the sublayer matrix should
616 // retain its 3D properties when given to child. But then, the child also
617 // does not preserve3D. When it gives its hierarchy to the grand_child, it
618 // should be flattened to 2D.
619 gfx::Transform parent_sublayer_matrix;
620 parent_sublayer_matrix.Scale3d(10.f, 10.f, 3.3f);
621 // Sublayer matrix is applied to the anchor point of the parent layer.
622 parent_composite_transform =
623 parent_translation_to_anchor * parent_layer_transform *
624 Inverse(parent_translation_to_anchor) * parent_translation_to_anchor *
625 parent_sublayer_matrix * Inverse(parent_translation_to_anchor);
626 gfx::Transform flattened_composite_transform = parent_composite_transform;
627 flattened_composite_transform.FlattenTo2d();
628 SetLayerPropertiesForTesting(parent.get(),
629 parent_layer_transform,
630 parent_sublayer_matrix,
631 gfx::PointF(0.25f, 0.25f),
632 gfx::PointF(),
633 gfx::Size(10, 12),
634 false);
635 SetLayerPropertiesForTesting(child.get(),
636 identity_matrix,
637 identity_matrix,
638 gfx::PointF(),
639 gfx::PointF(),
640 gfx::Size(16, 18),
641 false);
642 SetLayerPropertiesForTesting(grand_child.get(),
643 identity_matrix,
644 identity_matrix,
645 gfx::PointF(),
646 gfx::PointF(),
647 gfx::Size(76, 78),
648 false);
649 ExecuteCalculateDrawProperties(root.get());
650 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
651 child->draw_transform());
652 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
653 child->screen_space_transform());
654 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_composite_transform,
655 grand_child->draw_transform());
656 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_composite_transform,
657 grand_child->screen_space_transform());
658
659 // Case 5: same as Case 4, except that child does preserve 3D, so the
660 // grand_child should receive the non-flattened composite transform.
661 SetLayerPropertiesForTesting(parent.get(),
662 parent_layer_transform,
663 parent_sublayer_matrix,
664 gfx::PointF(0.25f, 0.25f),
665 gfx::PointF(),
666 gfx::Size(10, 12),
667 false);
668 SetLayerPropertiesForTesting(child.get(),
669 identity_matrix,
670 identity_matrix,
671 gfx::PointF(),
672 gfx::PointF(),
673 gfx::Size(16, 18),
674 true);
675 SetLayerPropertiesForTesting(grand_child.get(),
676 identity_matrix,
677 identity_matrix,
678 gfx::PointF(),
679 gfx::PointF(),
680 gfx::Size(76, 78),
681 false);
682 ExecuteCalculateDrawProperties(root.get());
683 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
684 child->draw_transform());
685 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
686 child->screen_space_transform());
687 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
688 grand_child->draw_transform());
689 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
690 grand_child->screen_space_transform());
691 }
692
TEST_F(LayerTreeHostCommonTest,TransformsForSingleRenderSurface)693 TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) {
694 scoped_refptr<Layer> root = Layer::Create();
695 scoped_refptr<Layer> parent = Layer::Create();
696 scoped_refptr<Layer> child = Layer::Create();
697 scoped_refptr<LayerWithForcedDrawsContent> grand_child =
698 make_scoped_refptr(new LayerWithForcedDrawsContent());
699 root->AddChild(parent);
700 parent->AddChild(child);
701 child->AddChild(grand_child);
702
703 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
704 host->SetRootLayer(root);
705
706 // One-time setup of root layer
707 gfx::Transform identity_matrix;
708 SetLayerPropertiesForTesting(root.get(),
709 identity_matrix,
710 identity_matrix,
711 gfx::PointF(),
712 gfx::PointF(),
713 gfx::Size(1, 2),
714 false);
715
716 // Child is set up so that a new render surface should be created.
717 child->SetOpacity(0.5f);
718 child->SetForceRenderSurface(true);
719
720 gfx::Transform parent_layer_transform;
721 parent_layer_transform.Scale3d(1.f, 0.9f, 1.f);
722 gfx::Transform parent_translation_to_anchor;
723 parent_translation_to_anchor.Translate(25.0, 30.0);
724 gfx::Transform parent_sublayer_matrix;
725 parent_sublayer_matrix.Scale3d(0.9f, 1.f, 3.3f);
726
727 gfx::Transform parent_composite_transform =
728 parent_translation_to_anchor * parent_layer_transform *
729 Inverse(parent_translation_to_anchor) * parent_translation_to_anchor *
730 parent_sublayer_matrix * Inverse(parent_translation_to_anchor);
731 gfx::Vector2dF parent_composite_scale =
732 MathUtil::ComputeTransform2dScaleComponents(parent_composite_transform,
733 1.f);
734 gfx::Transform surface_sublayer_transform;
735 surface_sublayer_transform.Scale(parent_composite_scale.x(),
736 parent_composite_scale.y());
737 gfx::Transform surface_sublayer_composite_transform =
738 parent_composite_transform * Inverse(surface_sublayer_transform);
739
740 // Child's render surface should not exist yet.
741 ASSERT_FALSE(child->render_surface());
742
743 SetLayerPropertiesForTesting(parent.get(),
744 parent_layer_transform,
745 parent_sublayer_matrix,
746 gfx::PointF(0.25f, 0.25f),
747 gfx::PointF(),
748 gfx::Size(100, 120),
749 false);
750 SetLayerPropertiesForTesting(child.get(),
751 identity_matrix,
752 identity_matrix,
753 gfx::PointF(),
754 gfx::PointF(),
755 gfx::Size(16, 18),
756 false);
757 SetLayerPropertiesForTesting(grand_child.get(),
758 identity_matrix,
759 identity_matrix,
760 gfx::PointF(),
761 gfx::PointF(),
762 gfx::Size(8, 10),
763 false);
764 ExecuteCalculateDrawProperties(root.get());
765
766 // Render surface should have been created now.
767 ASSERT_TRUE(child->render_surface());
768 ASSERT_EQ(child, child->render_target());
769
770 // The child layer's draw transform should refer to its new render surface.
771 // The screen-space transform, however, should still refer to the root.
772 EXPECT_TRANSFORMATION_MATRIX_EQ(surface_sublayer_transform,
773 child->draw_transform());
774 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
775 child->screen_space_transform());
776
777 // Because the grand_child is the only drawable content, the child's render
778 // surface will tighten its bounds to the grand_child. The scale at which the
779 // surface's subtree is drawn must be removed from the composite transform.
780 EXPECT_TRANSFORMATION_MATRIX_EQ(
781 surface_sublayer_composite_transform,
782 child->render_target()->render_surface()->draw_transform());
783
784 // The screen space is the same as the target since the child surface draws
785 // into the root.
786 EXPECT_TRANSFORMATION_MATRIX_EQ(
787 surface_sublayer_composite_transform,
788 child->render_target()->render_surface()->screen_space_transform());
789 }
790
TEST_F(LayerTreeHostCommonTest,SublayerTransformWithAnchorPoint)791 TEST_F(LayerTreeHostCommonTest, SublayerTransformWithAnchorPoint) {
792 // crbug.com/157961 - we were always applying the sublayer transform about
793 // the center of the layer, rather than the anchor point.
794
795 scoped_refptr<Layer> root = Layer::Create();
796 scoped_refptr<Layer> parent = Layer::Create();
797 scoped_refptr<LayerWithForcedDrawsContent> child =
798 make_scoped_refptr(new LayerWithForcedDrawsContent());
799 root->AddChild(parent);
800 parent->AddChild(child);
801
802 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
803 host->SetRootLayer(root);
804
805 gfx::Transform identity_matrix;
806 gfx::Transform parent_sublayer_matrix;
807 parent_sublayer_matrix.ApplyPerspectiveDepth(2.0);
808 gfx::PointF parent_anchor_point(0.2f, 0.8f);
809
810 SetLayerPropertiesForTesting(root.get(),
811 identity_matrix,
812 identity_matrix,
813 gfx::PointF(),
814 gfx::PointF(),
815 gfx::Size(1, 2),
816 false);
817 SetLayerPropertiesForTesting(parent.get(),
818 identity_matrix,
819 parent_sublayer_matrix,
820 parent_anchor_point,
821 gfx::PointF(),
822 gfx::Size(100, 100),
823 false);
824 SetLayerPropertiesForTesting(child.get(),
825 identity_matrix,
826 identity_matrix,
827 gfx::PointF(),
828 gfx::PointF(),
829 gfx::Size(10, 10),
830 false);
831 ExecuteCalculateDrawProperties(root.get());
832
833 gfx::Transform expected_child_draw_transform;
834 expected_child_draw_transform.Translate(20.0, 80.0);
835 expected_child_draw_transform.ApplyPerspectiveDepth(2.0);
836 expected_child_draw_transform.Translate(-20.0, -80.0);
837 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_draw_transform,
838 child->draw_transform());
839 }
840
TEST_F(LayerTreeHostCommonTest,TransformsForReplica)841 TEST_F(LayerTreeHostCommonTest, TransformsForReplica) {
842 scoped_refptr<Layer> root = Layer::Create();
843 scoped_refptr<Layer> parent = Layer::Create();
844 scoped_refptr<Layer> child = Layer::Create();
845 scoped_refptr<Layer> child_replica = Layer::Create();
846 scoped_refptr<LayerWithForcedDrawsContent> grand_child =
847 make_scoped_refptr(new LayerWithForcedDrawsContent());
848 root->AddChild(parent);
849 parent->AddChild(child);
850 child->AddChild(grand_child);
851 child->SetReplicaLayer(child_replica.get());
852
853 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
854 host->SetRootLayer(root);
855
856 // One-time setup of root layer
857 gfx::Transform identity_matrix;
858 SetLayerPropertiesForTesting(root.get(),
859 identity_matrix,
860 identity_matrix,
861 gfx::PointF(),
862 gfx::PointF(),
863 gfx::Size(1, 2),
864 false);
865
866 // Child is set up so that a new render surface should be created.
867 child->SetOpacity(0.5f);
868
869 gfx::Transform parent_layer_transform;
870 parent_layer_transform.Scale3d(2.0, 2.0, 1.0);
871 gfx::Transform parent_translation_to_anchor;
872 parent_translation_to_anchor.Translate(2.5, 3.0);
873 gfx::Transform parent_sublayer_matrix;
874 parent_sublayer_matrix.Scale3d(10.f, 10.f, 3.3f);
875 gfx::Transform parent_composite_transform =
876 parent_translation_to_anchor * parent_layer_transform *
877 Inverse(parent_translation_to_anchor) * parent_translation_to_anchor *
878 parent_sublayer_matrix * Inverse(parent_translation_to_anchor);
879 gfx::Transform replica_layer_transform;
880 replica_layer_transform.Scale3d(3.0, 3.0, 1.0);
881 gfx::Vector2dF parent_composite_scale =
882 MathUtil::ComputeTransform2dScaleComponents(parent_composite_transform,
883 1.f);
884 gfx::Transform surface_sublayer_transform;
885 surface_sublayer_transform.Scale(parent_composite_scale.x(),
886 parent_composite_scale.y());
887 gfx::Transform replica_composite_transform =
888 parent_composite_transform * replica_layer_transform *
889 Inverse(surface_sublayer_transform);
890
891 // Child's render surface should not exist yet.
892 ASSERT_FALSE(child->render_surface());
893
894 SetLayerPropertiesForTesting(parent.get(),
895 parent_layer_transform,
896 parent_sublayer_matrix,
897 gfx::PointF(0.25f, 0.25f),
898 gfx::PointF(),
899 gfx::Size(10, 12),
900 false);
901 SetLayerPropertiesForTesting(child.get(),
902 identity_matrix,
903 identity_matrix,
904 gfx::PointF(),
905 gfx::PointF(),
906 gfx::Size(16, 18),
907 false);
908 SetLayerPropertiesForTesting(grand_child.get(),
909 identity_matrix,
910 identity_matrix,
911 gfx::PointF(),
912 gfx::PointF(-0.5f, -0.5f),
913 gfx::Size(1, 1),
914 false);
915 SetLayerPropertiesForTesting(child_replica.get(),
916 replica_layer_transform,
917 identity_matrix,
918 gfx::PointF(),
919 gfx::PointF(),
920 gfx::Size(),
921 false);
922 ExecuteCalculateDrawProperties(root.get());
923
924 // Render surface should have been created now.
925 ASSERT_TRUE(child->render_surface());
926 ASSERT_EQ(child, child->render_target());
927
928 EXPECT_TRANSFORMATION_MATRIX_EQ(
929 replica_composite_transform,
930 child->render_target()->render_surface()->replica_draw_transform());
931 EXPECT_TRANSFORMATION_MATRIX_EQ(replica_composite_transform,
932 child->render_target()->render_surface()
933 ->replica_screen_space_transform());
934 }
935
TEST_F(LayerTreeHostCommonTest,TransformsForRenderSurfaceHierarchy)936 TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) {
937 // This test creates a more complex tree and verifies it all at once. This
938 // covers the following cases:
939 // - layers that are described w.r.t. a render surface: should have draw
940 // transforms described w.r.t. that surface
941 // - A render surface described w.r.t. an ancestor render surface: should
942 // have a draw transform described w.r.t. that ancestor surface
943 // - Replicas of a render surface are described w.r.t. the replica's
944 // transform around its anchor, along with the surface itself.
945 // - Sanity check on recursion: verify transforms of layers described w.r.t.
946 // a render surface that is described w.r.t. an ancestor render surface.
947 // - verifying that each layer has a reference to the correct render surface
948 // and render target values.
949
950 scoped_refptr<Layer> root = Layer::Create();
951 scoped_refptr<Layer> parent = Layer::Create();
952 scoped_refptr<Layer> render_surface1 = Layer::Create();
953 scoped_refptr<Layer> render_surface2 = Layer::Create();
954 scoped_refptr<Layer> child_of_root = Layer::Create();
955 scoped_refptr<Layer> child_of_rs1 = Layer::Create();
956 scoped_refptr<Layer> child_of_rs2 = Layer::Create();
957 scoped_refptr<Layer> replica_of_rs1 = Layer::Create();
958 scoped_refptr<Layer> replica_of_rs2 = Layer::Create();
959 scoped_refptr<Layer> grand_child_of_root = Layer::Create();
960 scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs1 =
961 make_scoped_refptr(new LayerWithForcedDrawsContent());
962 scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs2 =
963 make_scoped_refptr(new LayerWithForcedDrawsContent());
964 root->AddChild(parent);
965 parent->AddChild(render_surface1);
966 parent->AddChild(child_of_root);
967 render_surface1->AddChild(child_of_rs1);
968 render_surface1->AddChild(render_surface2);
969 render_surface2->AddChild(child_of_rs2);
970 child_of_root->AddChild(grand_child_of_root);
971 child_of_rs1->AddChild(grand_child_of_rs1);
972 child_of_rs2->AddChild(grand_child_of_rs2);
973 render_surface1->SetReplicaLayer(replica_of_rs1.get());
974 render_surface2->SetReplicaLayer(replica_of_rs2.get());
975
976 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
977 host->SetRootLayer(root);
978
979 // In combination with descendant draws content, opacity != 1 forces the layer
980 // to have a new render surface.
981 render_surface1->SetOpacity(0.5f);
982 render_surface2->SetOpacity(0.33f);
983
984 // One-time setup of root layer
985 gfx::Transform identity_matrix;
986 SetLayerPropertiesForTesting(root.get(),
987 identity_matrix,
988 identity_matrix,
989 gfx::PointF(),
990 gfx::PointF(),
991 gfx::Size(1, 2),
992 false);
993
994 // All layers in the tree are initialized with an anchor at .25 and a size of
995 // (10,10). matrix "A" is the composite layer transform used in all layers,
996 // centered about the anchor point. matrix "B" is the sublayer transform used
997 // in all layers, centered about the center position of the layer. matrix "R"
998 // is the composite replica transform used in all replica layers.
999 //
1000 // x component tests that layer_transform and sublayer_transform are done in
1001 // the right order (translation and scale are noncommutative). y component
1002 // has a translation by 1 for every ancestor, which indicates the "depth" of
1003 // the layer in the hierarchy.
1004 gfx::Transform translation_to_anchor;
1005 translation_to_anchor.Translate(2.5, 0.0);
1006 gfx::Transform layer_transform;
1007 layer_transform.Translate(1.0, 1.0);
1008 gfx::Transform sublayer_transform;
1009 sublayer_transform.Scale3d(10.0, 1.0, 1.0);
1010 gfx::Transform replica_layer_transform;
1011 replica_layer_transform.Scale3d(-2.0, 5.0, 1.0);
1012
1013 gfx::Transform A =
1014 translation_to_anchor * layer_transform * Inverse(translation_to_anchor);
1015 gfx::Transform B = translation_to_anchor * sublayer_transform *
1016 Inverse(translation_to_anchor);
1017 gfx::Transform R = A * translation_to_anchor * replica_layer_transform *
1018 Inverse(translation_to_anchor);
1019
1020 gfx::Vector2dF surface1_parent_transform_scale =
1021 MathUtil::ComputeTransform2dScaleComponents(A * B, 1.f);
1022 gfx::Transform surface1_sublayer_transform;
1023 surface1_sublayer_transform.Scale(surface1_parent_transform_scale.x(),
1024 surface1_parent_transform_scale.y());
1025
1026 // SS1 = transform given to the subtree of render_surface1
1027 gfx::Transform SS1 = surface1_sublayer_transform;
1028 // S1 = transform to move from render_surface1 pixels to the layer space of
1029 // the owning layer
1030 gfx::Transform S1 = Inverse(surface1_sublayer_transform);
1031
1032 gfx::Vector2dF surface2_parent_transform_scale =
1033 MathUtil::ComputeTransform2dScaleComponents(SS1 * A * B, 1.f);
1034 gfx::Transform surface2_sublayer_transform;
1035 surface2_sublayer_transform.Scale(surface2_parent_transform_scale.x(),
1036 surface2_parent_transform_scale.y());
1037
1038 // SS2 = transform given to the subtree of render_surface2
1039 gfx::Transform SS2 = surface2_sublayer_transform;
1040 // S2 = transform to move from render_surface2 pixels to the layer space of
1041 // the owning layer
1042 gfx::Transform S2 = Inverse(surface2_sublayer_transform);
1043
1044 SetLayerPropertiesForTesting(parent.get(),
1045 layer_transform,
1046 sublayer_transform,
1047 gfx::PointF(0.25f, 0.f),
1048 gfx::PointF(),
1049 gfx::Size(10, 10),
1050 false);
1051 SetLayerPropertiesForTesting(render_surface1.get(),
1052 layer_transform,
1053 sublayer_transform,
1054 gfx::PointF(0.25f, 0.f),
1055 gfx::PointF(),
1056 gfx::Size(10, 10),
1057 false);
1058 SetLayerPropertiesForTesting(render_surface2.get(),
1059 layer_transform,
1060 sublayer_transform,
1061 gfx::PointF(0.25f, 0.f),
1062 gfx::PointF(),
1063 gfx::Size(10, 10),
1064 false);
1065 SetLayerPropertiesForTesting(child_of_root.get(),
1066 layer_transform,
1067 sublayer_transform,
1068 gfx::PointF(0.25f, 0.f),
1069 gfx::PointF(),
1070 gfx::Size(10, 10),
1071 false);
1072 SetLayerPropertiesForTesting(child_of_rs1.get(),
1073 layer_transform,
1074 sublayer_transform,
1075 gfx::PointF(0.25f, 0.f),
1076 gfx::PointF(),
1077 gfx::Size(10, 10),
1078 false);
1079 SetLayerPropertiesForTesting(child_of_rs2.get(),
1080 layer_transform,
1081 sublayer_transform,
1082 gfx::PointF(0.25f, 0.f),
1083 gfx::PointF(),
1084 gfx::Size(10, 10),
1085 false);
1086 SetLayerPropertiesForTesting(grand_child_of_root.get(),
1087 layer_transform,
1088 sublayer_transform,
1089 gfx::PointF(0.25f, 0.f),
1090 gfx::PointF(),
1091 gfx::Size(10, 10),
1092 false);
1093 SetLayerPropertiesForTesting(grand_child_of_rs1.get(),
1094 layer_transform,
1095 sublayer_transform,
1096 gfx::PointF(0.25f, 0.f),
1097 gfx::PointF(),
1098 gfx::Size(10, 10),
1099 false);
1100 SetLayerPropertiesForTesting(grand_child_of_rs2.get(),
1101 layer_transform,
1102 sublayer_transform,
1103 gfx::PointF(0.25f, 0.f),
1104 gfx::PointF(),
1105 gfx::Size(10, 10),
1106 false);
1107 SetLayerPropertiesForTesting(replica_of_rs1.get(),
1108 replica_layer_transform,
1109 sublayer_transform,
1110 gfx::PointF(0.25f, 0.f),
1111 gfx::PointF(),
1112 gfx::Size(),
1113 false);
1114 SetLayerPropertiesForTesting(replica_of_rs2.get(),
1115 replica_layer_transform,
1116 sublayer_transform,
1117 gfx::PointF(0.25f, 0.f),
1118 gfx::PointF(),
1119 gfx::Size(),
1120 false);
1121
1122 ExecuteCalculateDrawProperties(root.get());
1123
1124 // Only layers that are associated with render surfaces should have an actual
1125 // RenderSurface() value.
1126 ASSERT_TRUE(root->render_surface());
1127 ASSERT_FALSE(child_of_root->render_surface());
1128 ASSERT_FALSE(grand_child_of_root->render_surface());
1129
1130 ASSERT_TRUE(render_surface1->render_surface());
1131 ASSERT_FALSE(child_of_rs1->render_surface());
1132 ASSERT_FALSE(grand_child_of_rs1->render_surface());
1133
1134 ASSERT_TRUE(render_surface2->render_surface());
1135 ASSERT_FALSE(child_of_rs2->render_surface());
1136 ASSERT_FALSE(grand_child_of_rs2->render_surface());
1137
1138 // Verify all render target accessors
1139 EXPECT_EQ(root, parent->render_target());
1140 EXPECT_EQ(root, child_of_root->render_target());
1141 EXPECT_EQ(root, grand_child_of_root->render_target());
1142
1143 EXPECT_EQ(render_surface1, render_surface1->render_target());
1144 EXPECT_EQ(render_surface1, child_of_rs1->render_target());
1145 EXPECT_EQ(render_surface1, grand_child_of_rs1->render_target());
1146
1147 EXPECT_EQ(render_surface2, render_surface2->render_target());
1148 EXPECT_EQ(render_surface2, child_of_rs2->render_target());
1149 EXPECT_EQ(render_surface2, grand_child_of_rs2->render_target());
1150
1151 // Verify layer draw transforms note that draw transforms are described with
1152 // respect to the nearest ancestor render surface but screen space transforms
1153 // are described with respect to the root.
1154 EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->draw_transform());
1155 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, child_of_root->draw_transform());
1156 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A,
1157 grand_child_of_root->draw_transform());
1158
1159 EXPECT_TRANSFORMATION_MATRIX_EQ(SS1, render_surface1->draw_transform());
1160 EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * B * A, child_of_rs1->draw_transform());
1161 EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * B * A * B * A,
1162 grand_child_of_rs1->draw_transform());
1163
1164 EXPECT_TRANSFORMATION_MATRIX_EQ(SS2, render_surface2->draw_transform());
1165 EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * B * A, child_of_rs2->draw_transform());
1166 EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * B * A * B * A,
1167 grand_child_of_rs2->draw_transform());
1168
1169 // Verify layer screen-space transforms
1170 //
1171 EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->screen_space_transform());
1172 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A,
1173 child_of_root->screen_space_transform());
1174 EXPECT_TRANSFORMATION_MATRIX_EQ(
1175 A * B * A * B * A, grand_child_of_root->screen_space_transform());
1176
1177 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A,
1178 render_surface1->screen_space_transform());
1179 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A,
1180 child_of_rs1->screen_space_transform());
1181 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A,
1182 grand_child_of_rs1->screen_space_transform());
1183
1184 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A,
1185 render_surface2->screen_space_transform());
1186 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A,
1187 child_of_rs2->screen_space_transform());
1188 EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * B * A * B * A,
1189 grand_child_of_rs2->screen_space_transform());
1190
1191 // Verify render surface transforms.
1192 //
1193 // Draw transform of render surface 1 is described with respect to root.
1194 EXPECT_TRANSFORMATION_MATRIX_EQ(
1195 A * B * A * S1, render_surface1->render_surface()->draw_transform());
1196 EXPECT_TRANSFORMATION_MATRIX_EQ(
1197 A * B * R * S1,
1198 render_surface1->render_surface()->replica_draw_transform());
1199 EXPECT_TRANSFORMATION_MATRIX_EQ(
1200 A * B * A * S1,
1201 render_surface1->render_surface()->screen_space_transform());
1202 EXPECT_TRANSFORMATION_MATRIX_EQ(
1203 A * B * R * S1,
1204 render_surface1->render_surface()->replica_screen_space_transform());
1205 // Draw transform of render surface 2 is described with respect to render
1206 // surface 1.
1207 EXPECT_TRANSFORMATION_MATRIX_EQ(
1208 SS1 * B * A * S2, render_surface2->render_surface()->draw_transform());
1209 EXPECT_TRANSFORMATION_MATRIX_EQ(
1210 SS1 * B * R * S2,
1211 render_surface2->render_surface()->replica_draw_transform());
1212 EXPECT_TRANSFORMATION_MATRIX_EQ(
1213 A * B * A * B * A * S2,
1214 render_surface2->render_surface()->screen_space_transform());
1215 EXPECT_TRANSFORMATION_MATRIX_EQ(
1216 A * B * A * B * R * S2,
1217 render_surface2->render_surface()->replica_screen_space_transform());
1218
1219 // Sanity check. If these fail there is probably a bug in the test itself. It
1220 // is expected that we correctly set up transforms so that the y-component of
1221 // the screen-space transform encodes the "depth" of the layer in the tree.
1222 EXPECT_FLOAT_EQ(1.0, parent->screen_space_transform().matrix().get(1, 3));
1223 EXPECT_FLOAT_EQ(2.0,
1224 child_of_root->screen_space_transform().matrix().get(1, 3));
1225 EXPECT_FLOAT_EQ(
1226 3.0, grand_child_of_root->screen_space_transform().matrix().get(1, 3));
1227
1228 EXPECT_FLOAT_EQ(2.0,
1229 render_surface1->screen_space_transform().matrix().get(1, 3));
1230 EXPECT_FLOAT_EQ(3.0,
1231 child_of_rs1->screen_space_transform().matrix().get(1, 3));
1232 EXPECT_FLOAT_EQ(
1233 4.0, grand_child_of_rs1->screen_space_transform().matrix().get(1, 3));
1234
1235 EXPECT_FLOAT_EQ(3.0,
1236 render_surface2->screen_space_transform().matrix().get(1, 3));
1237 EXPECT_FLOAT_EQ(4.0,
1238 child_of_rs2->screen_space_transform().matrix().get(1, 3));
1239 EXPECT_FLOAT_EQ(
1240 5.0, grand_child_of_rs2->screen_space_transform().matrix().get(1, 3));
1241 }
1242
TEST_F(LayerTreeHostCommonTest,TransformsForFlatteningLayer)1243 TEST_F(LayerTreeHostCommonTest, TransformsForFlatteningLayer) {
1244 // For layers that flatten their subtree, there should be an orthographic
1245 // projection (for x and y values) in the middle of the transform sequence.
1246 // Note that the way the code is currently implemented, it is not expected to
1247 // use a canonical orthographic projection.
1248
1249 scoped_refptr<Layer> root = Layer::Create();
1250 scoped_refptr<Layer> child = Layer::Create();
1251 scoped_refptr<LayerWithForcedDrawsContent> grand_child =
1252 make_scoped_refptr(new LayerWithForcedDrawsContent());
1253
1254 gfx::Transform rotation_about_y_axis;
1255 rotation_about_y_axis.RotateAboutYAxis(30.0);
1256
1257 const gfx::Transform identity_matrix;
1258 SetLayerPropertiesForTesting(root.get(),
1259 identity_matrix,
1260 identity_matrix,
1261 gfx::PointF(),
1262 gfx::PointF(),
1263 gfx::Size(100, 100),
1264 false);
1265 SetLayerPropertiesForTesting(child.get(),
1266 rotation_about_y_axis,
1267 identity_matrix,
1268 gfx::PointF(),
1269 gfx::PointF(),
1270 gfx::Size(10, 10),
1271 false);
1272 SetLayerPropertiesForTesting(grand_child.get(),
1273 rotation_about_y_axis,
1274 identity_matrix,
1275 gfx::PointF(),
1276 gfx::PointF(),
1277 gfx::Size(10, 10),
1278 false);
1279
1280 root->AddChild(child);
1281 child->AddChild(grand_child);
1282 child->SetForceRenderSurface(true);
1283
1284 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
1285 host->SetRootLayer(root);
1286
1287 // No layers in this test should preserve 3d.
1288 ASSERT_FALSE(root->preserves_3d());
1289 ASSERT_FALSE(child->preserves_3d());
1290 ASSERT_FALSE(grand_child->preserves_3d());
1291
1292 gfx::Transform expected_child_draw_transform = rotation_about_y_axis;
1293 gfx::Transform expected_child_screen_space_transform = rotation_about_y_axis;
1294 gfx::Transform expected_grand_child_draw_transform =
1295 rotation_about_y_axis; // draws onto child's render surface
1296 gfx::Transform flattened_rotation_about_y = rotation_about_y_axis;
1297 flattened_rotation_about_y.FlattenTo2d();
1298 gfx::Transform expected_grand_child_screen_space_transform =
1299 flattened_rotation_about_y * rotation_about_y_axis;
1300
1301 ExecuteCalculateDrawProperties(root.get());
1302
1303 // The child's draw transform should have been taken by its surface.
1304 ASSERT_TRUE(child->render_surface());
1305 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_draw_transform,
1306 child->render_surface()->draw_transform());
1307 EXPECT_TRANSFORMATION_MATRIX_EQ(
1308 expected_child_screen_space_transform,
1309 child->render_surface()->screen_space_transform());
1310 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
1311 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_screen_space_transform,
1312 child->screen_space_transform());
1313 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_draw_transform,
1314 grand_child->draw_transform());
1315 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform,
1316 grand_child->screen_space_transform());
1317 }
1318
TEST_F(LayerTreeHostCommonTest,TransformsForDegenerateIntermediateLayer)1319 TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) {
1320 // A layer that is empty in one axis, but not the other, was accidentally
1321 // skipping a necessary translation. Without that translation, the coordinate
1322 // space of the layer's draw transform is incorrect.
1323 //
1324 // Normally this isn't a problem, because the layer wouldn't be drawn anyway,
1325 // but if that layer becomes a render surface, then its draw transform is
1326 // implicitly inherited by the rest of the subtree, which then is positioned
1327 // incorrectly as a result.
1328
1329 scoped_refptr<Layer> root = Layer::Create();
1330 scoped_refptr<Layer> child = Layer::Create();
1331 scoped_refptr<LayerWithForcedDrawsContent> grand_child =
1332 make_scoped_refptr(new LayerWithForcedDrawsContent());
1333
1334 // The child height is zero, but has non-zero width that should be accounted
1335 // for while computing draw transforms.
1336 const gfx::Transform identity_matrix;
1337 SetLayerPropertiesForTesting(root.get(),
1338 identity_matrix,
1339 identity_matrix,
1340 gfx::PointF(),
1341 gfx::PointF(),
1342 gfx::Size(100, 100),
1343 false);
1344 SetLayerPropertiesForTesting(child.get(),
1345 identity_matrix,
1346 identity_matrix,
1347 gfx::PointF(),
1348 gfx::PointF(),
1349 gfx::Size(10, 0),
1350 false);
1351 SetLayerPropertiesForTesting(grand_child.get(),
1352 identity_matrix,
1353 identity_matrix,
1354 gfx::PointF(),
1355 gfx::PointF(),
1356 gfx::Size(10, 10),
1357 false);
1358
1359 root->AddChild(child);
1360 child->AddChild(grand_child);
1361 child->SetForceRenderSurface(true);
1362
1363 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
1364 host->SetRootLayer(root);
1365
1366 ExecuteCalculateDrawProperties(root.get());
1367
1368 ASSERT_TRUE(child->render_surface());
1369 // This is the real test, the rest are sanity checks.
1370 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
1371 child->render_surface()->draw_transform());
1372 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, child->draw_transform());
1373 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix,
1374 grand_child->draw_transform());
1375 }
1376
TEST_F(LayerTreeHostCommonTest,TransformAboveRootLayer)1377 TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) {
1378 // Transformations applied at the root of the tree should be forwarded
1379 // to child layers instead of applied to the root RenderSurface.
1380 const gfx::Transform identity_matrix;
1381 scoped_refptr<Layer> root = Layer::Create();
1382 scoped_refptr<Layer> child = Layer::Create();
1383 child->SetScrollable(true);
1384 root->AddChild(child);
1385
1386 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
1387 host->SetRootLayer(root);
1388
1389 SetLayerPropertiesForTesting(root.get(),
1390 identity_matrix,
1391 identity_matrix,
1392 gfx::PointF(),
1393 gfx::PointF(),
1394 gfx::Size(20, 20),
1395 false);
1396 SetLayerPropertiesForTesting(child.get(),
1397 identity_matrix,
1398 identity_matrix,
1399 gfx::PointF(),
1400 gfx::PointF(),
1401 gfx::Size(20, 20),
1402 false);
1403
1404 gfx::Transform translate;
1405 translate.Translate(50, 50);
1406 {
1407 RenderSurfaceLayerList render_surface_layer_list;
1408 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1409 root.get(), root->bounds(), translate, &render_surface_layer_list);
1410 inputs.can_adjust_raster_scales = true;
1411 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1412 EXPECT_EQ(translate, root->draw_properties().target_space_transform);
1413 EXPECT_EQ(translate, child->draw_properties().target_space_transform);
1414 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
1415 }
1416
1417 gfx::Transform scale;
1418 scale.Scale(2, 2);
1419 {
1420 RenderSurfaceLayerList render_surface_layer_list;
1421 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1422 root.get(), root->bounds(), scale, &render_surface_layer_list);
1423 inputs.can_adjust_raster_scales = true;
1424 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1425 EXPECT_EQ(scale, root->draw_properties().target_space_transform);
1426 EXPECT_EQ(scale, child->draw_properties().target_space_transform);
1427 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
1428 }
1429
1430 gfx::Transform rotate;
1431 rotate.Rotate(2);
1432 {
1433 RenderSurfaceLayerList render_surface_layer_list;
1434 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1435 root.get(), root->bounds(), rotate, &render_surface_layer_list);
1436 inputs.can_adjust_raster_scales = true;
1437 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1438 EXPECT_EQ(rotate, root->draw_properties().target_space_transform);
1439 EXPECT_EQ(rotate, child->draw_properties().target_space_transform);
1440 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
1441 }
1442
1443 gfx::Transform composite;
1444 composite.ConcatTransform(translate);
1445 composite.ConcatTransform(scale);
1446 composite.ConcatTransform(rotate);
1447 {
1448 RenderSurfaceLayerList render_surface_layer_list;
1449 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1450 root.get(), root->bounds(), composite, &render_surface_layer_list);
1451 inputs.can_adjust_raster_scales = true;
1452 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1453 EXPECT_EQ(composite, root->draw_properties().target_space_transform);
1454 EXPECT_EQ(composite, child->draw_properties().target_space_transform);
1455 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
1456 }
1457
1458 // Verify it composes correctly with device scale.
1459 float device_scale_factor = 1.5f;
1460
1461 {
1462 RenderSurfaceLayerList render_surface_layer_list;
1463 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1464 root.get(), root->bounds(), translate, &render_surface_layer_list);
1465 inputs.device_scale_factor = device_scale_factor;
1466 inputs.can_adjust_raster_scales = true;
1467 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1468 gfx::Transform device_scaled_translate = translate;
1469 device_scaled_translate.Scale(device_scale_factor, device_scale_factor);
1470 EXPECT_EQ(device_scaled_translate,
1471 root->draw_properties().target_space_transform);
1472 EXPECT_EQ(device_scaled_translate,
1473 child->draw_properties().target_space_transform);
1474 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
1475 }
1476
1477 // Verify it composes correctly with page scale.
1478 float page_scale_factor = 2.f;
1479
1480 {
1481 RenderSurfaceLayerList render_surface_layer_list;
1482 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1483 root.get(), root->bounds(), translate, &render_surface_layer_list);
1484 inputs.page_scale_factor = page_scale_factor;
1485 inputs.page_scale_application_layer = root.get();
1486 inputs.can_adjust_raster_scales = true;
1487 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1488 gfx::Transform page_scaled_translate = translate;
1489 page_scaled_translate.Scale(page_scale_factor, page_scale_factor);
1490 EXPECT_EQ(translate, root->draw_properties().target_space_transform);
1491 EXPECT_EQ(page_scaled_translate,
1492 child->draw_properties().target_space_transform);
1493 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
1494 }
1495
1496 // Verify that it composes correctly with transforms directly on root layer.
1497 root->SetTransform(composite);
1498 root->SetSublayerTransform(composite);
1499
1500 {
1501 RenderSurfaceLayerList render_surface_layer_list;
1502 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1503 root.get(), root->bounds(), composite, &render_surface_layer_list);
1504 inputs.can_adjust_raster_scales = true;
1505 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1506 gfx::Transform compositeSquared = composite;
1507 compositeSquared.ConcatTransform(composite);
1508 gfx::Transform compositeCubed = compositeSquared;
1509 compositeCubed.ConcatTransform(composite);
1510 EXPECT_TRANSFORMATION_MATRIX_EQ(
1511 compositeSquared, root->draw_properties().target_space_transform);
1512 EXPECT_TRANSFORMATION_MATRIX_EQ(
1513 compositeCubed, child->draw_properties().target_space_transform);
1514 EXPECT_EQ(identity_matrix, root->render_surface()->draw_transform());
1515 }
1516 }
1517
TEST_F(LayerTreeHostCommonTest,RenderSurfaceListForRenderSurfaceWithClippedLayer)1518 TEST_F(LayerTreeHostCommonTest,
1519 RenderSurfaceListForRenderSurfaceWithClippedLayer) {
1520 scoped_refptr<Layer> parent = Layer::Create();
1521 scoped_refptr<Layer> render_surface1 = Layer::Create();
1522 scoped_refptr<LayerWithForcedDrawsContent> child =
1523 make_scoped_refptr(new LayerWithForcedDrawsContent());
1524
1525 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
1526 host->SetRootLayer(parent);
1527
1528
1529 const gfx::Transform identity_matrix;
1530 SetLayerPropertiesForTesting(parent.get(),
1531 identity_matrix,
1532 identity_matrix,
1533 gfx::PointF(),
1534 gfx::PointF(),
1535 gfx::Size(10, 10),
1536 false);
1537 SetLayerPropertiesForTesting(render_surface1.get(),
1538 identity_matrix,
1539 identity_matrix,
1540 gfx::PointF(),
1541 gfx::PointF(),
1542 gfx::Size(10, 10),
1543 false);
1544 SetLayerPropertiesForTesting(child.get(),
1545 identity_matrix,
1546 identity_matrix,
1547 gfx::PointF(),
1548 gfx::PointF(30.f, 30.f),
1549 gfx::Size(10, 10),
1550 false);
1551
1552 parent->AddChild(render_surface1);
1553 parent->SetMasksToBounds(true);
1554 render_surface1->AddChild(child);
1555 render_surface1->SetForceRenderSurface(true);
1556
1557 RenderSurfaceLayerList render_surface_layer_list;
1558 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1559 parent.get(),
1560 parent->bounds(),
1561 gfx::Transform(),
1562 &render_surface_layer_list);
1563 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1564
1565 // The child layer's content is entirely outside the parent's clip rect, so
1566 // the intermediate render surface should not be listed here, even if it was
1567 // forced to be created. Render surfaces without children or visible content
1568 // are unexpected at draw time (e.g. we might try to create a content texture
1569 // of size 0).
1570 ASSERT_TRUE(parent->render_surface());
1571 ASSERT_FALSE(render_surface1->render_surface());
1572 EXPECT_EQ(1U, render_surface_layer_list.size());
1573 }
1574
TEST_F(LayerTreeHostCommonTest,RenderSurfaceListForTransparentChild)1575 TEST_F(LayerTreeHostCommonTest, RenderSurfaceListForTransparentChild) {
1576 scoped_refptr<Layer> parent = Layer::Create();
1577 scoped_refptr<Layer> render_surface1 = Layer::Create();
1578 scoped_refptr<LayerWithForcedDrawsContent> child =
1579 make_scoped_refptr(new LayerWithForcedDrawsContent());
1580
1581 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
1582 host->SetRootLayer(parent);
1583
1584 const gfx::Transform identity_matrix;
1585 SetLayerPropertiesForTesting(render_surface1.get(),
1586 identity_matrix,
1587 identity_matrix,
1588 gfx::PointF(),
1589 gfx::PointF(),
1590 gfx::Size(10, 10),
1591 false);
1592 SetLayerPropertiesForTesting(child.get(),
1593 identity_matrix,
1594 identity_matrix,
1595 gfx::PointF(),
1596 gfx::PointF(),
1597 gfx::Size(10, 10),
1598 false);
1599
1600 parent->AddChild(render_surface1);
1601 render_surface1->AddChild(child);
1602 render_surface1->SetForceRenderSurface(true);
1603 render_surface1->SetOpacity(0.f);
1604
1605 RenderSurfaceLayerList render_surface_layer_list;
1606 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1607 parent.get(), parent->bounds(), &render_surface_layer_list);
1608 inputs.can_adjust_raster_scales = true;
1609 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1610
1611 // Since the layer is transparent, render_surface1->render_surface() should
1612 // not have gotten added anywhere. Also, the drawable content rect should not
1613 // have been extended by the children.
1614 ASSERT_TRUE(parent->render_surface());
1615 EXPECT_EQ(0U, parent->render_surface()->layer_list().size());
1616 EXPECT_EQ(1U, render_surface_layer_list.size());
1617 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
1618 EXPECT_EQ(gfx::Rect(), parent->drawable_content_rect());
1619 }
1620
TEST_F(LayerTreeHostCommonTest,ForceRenderSurface)1621 TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) {
1622 scoped_refptr<Layer> parent = Layer::Create();
1623 scoped_refptr<Layer> render_surface1 = Layer::Create();
1624 scoped_refptr<LayerWithForcedDrawsContent> child =
1625 make_scoped_refptr(new LayerWithForcedDrawsContent());
1626 render_surface1->SetForceRenderSurface(true);
1627
1628 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
1629 host->SetRootLayer(parent);
1630
1631 const gfx::Transform identity_matrix;
1632 SetLayerPropertiesForTesting(parent.get(),
1633 identity_matrix,
1634 identity_matrix,
1635 gfx::PointF(),
1636 gfx::PointF(),
1637 gfx::Size(10, 10),
1638 false);
1639 SetLayerPropertiesForTesting(render_surface1.get(),
1640 identity_matrix,
1641 identity_matrix,
1642 gfx::PointF(),
1643 gfx::PointF(),
1644 gfx::Size(10, 10),
1645 false);
1646 SetLayerPropertiesForTesting(child.get(),
1647 identity_matrix,
1648 identity_matrix,
1649 gfx::PointF(),
1650 gfx::PointF(),
1651 gfx::Size(10, 10),
1652 false);
1653
1654 parent->AddChild(render_surface1);
1655 render_surface1->AddChild(child);
1656
1657 // Sanity check before the actual test
1658 EXPECT_FALSE(parent->render_surface());
1659 EXPECT_FALSE(render_surface1->render_surface());
1660
1661 {
1662 RenderSurfaceLayerList render_surface_layer_list;
1663 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1664 parent.get(), parent->bounds(), &render_surface_layer_list);
1665 inputs.can_adjust_raster_scales = true;
1666 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1667
1668 // The root layer always creates a render surface
1669 EXPECT_TRUE(parent->render_surface());
1670 EXPECT_TRUE(render_surface1->render_surface());
1671 EXPECT_EQ(2U, render_surface_layer_list.size());
1672 }
1673
1674 {
1675 RenderSurfaceLayerList render_surface_layer_list;
1676 render_surface1->SetForceRenderSurface(false);
1677 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1678 parent.get(), parent->bounds(), &render_surface_layer_list);
1679 inputs.can_adjust_raster_scales = true;
1680 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1681 EXPECT_TRUE(parent->render_surface());
1682 EXPECT_FALSE(render_surface1->render_surface());
1683 EXPECT_EQ(1U, render_surface_layer_list.size());
1684 }
1685 }
1686
TEST_F(LayerTreeHostCommonTest,ClipRectCullsRenderSurfaces)1687 TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) {
1688 // The entire subtree of layers that are outside the clip rect should be
1689 // culled away, and should not affect the render_surface_layer_list.
1690 //
1691 // The test tree is set up as follows:
1692 // - all layers except the leaf_nodes are forced to be a new render surface
1693 // that have something to draw.
1694 // - parent is a large container layer.
1695 // - child has masksToBounds=true to cause clipping.
1696 // - grand_child is positioned outside of the child's bounds
1697 // - great_grand_child is also kept outside child's bounds.
1698 //
1699 // In this configuration, grand_child and great_grand_child are completely
1700 // outside the clip rect, and they should never get scheduled on the list of
1701 // render surfaces.
1702 //
1703
1704 const gfx::Transform identity_matrix;
1705 scoped_refptr<Layer> parent = Layer::Create();
1706 scoped_refptr<Layer> child = Layer::Create();
1707 scoped_refptr<Layer> grand_child = Layer::Create();
1708 scoped_refptr<Layer> great_grand_child = Layer::Create();
1709 scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 =
1710 make_scoped_refptr(new LayerWithForcedDrawsContent());
1711 scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 =
1712 make_scoped_refptr(new LayerWithForcedDrawsContent());
1713 parent->AddChild(child);
1714 child->AddChild(grand_child);
1715 grand_child->AddChild(great_grand_child);
1716
1717 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
1718 host->SetRootLayer(parent);
1719
1720 // leaf_node1 ensures that parent and child are kept on the
1721 // render_surface_layer_list, even though grand_child and great_grand_child
1722 // should be clipped.
1723 child->AddChild(leaf_node1);
1724 great_grand_child->AddChild(leaf_node2);
1725
1726 SetLayerPropertiesForTesting(parent.get(),
1727 identity_matrix,
1728 identity_matrix,
1729 gfx::PointF(),
1730 gfx::PointF(),
1731 gfx::Size(500, 500),
1732 false);
1733 SetLayerPropertiesForTesting(child.get(),
1734 identity_matrix,
1735 identity_matrix,
1736 gfx::PointF(),
1737 gfx::PointF(),
1738 gfx::Size(20, 20),
1739 false);
1740 SetLayerPropertiesForTesting(grand_child.get(),
1741 identity_matrix,
1742 identity_matrix,
1743 gfx::PointF(),
1744 gfx::PointF(45.f, 45.f),
1745 gfx::Size(10, 10),
1746 false);
1747 SetLayerPropertiesForTesting(great_grand_child.get(),
1748 identity_matrix,
1749 identity_matrix,
1750 gfx::PointF(),
1751 gfx::PointF(),
1752 gfx::Size(10, 10),
1753 false);
1754 SetLayerPropertiesForTesting(leaf_node1.get(),
1755 identity_matrix,
1756 identity_matrix,
1757 gfx::PointF(),
1758 gfx::PointF(),
1759 gfx::Size(500, 500),
1760 false);
1761 SetLayerPropertiesForTesting(leaf_node2.get(),
1762 identity_matrix,
1763 identity_matrix,
1764 gfx::PointF(),
1765 gfx::PointF(),
1766 gfx::Size(20, 20),
1767 false);
1768
1769 child->SetMasksToBounds(true);
1770 child->SetOpacity(0.4f);
1771 child->SetForceRenderSurface(true);
1772 grand_child->SetOpacity(0.5f);
1773 great_grand_child->SetOpacity(0.4f);
1774
1775 RenderSurfaceLayerList render_surface_layer_list;
1776 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1777 parent.get(), parent->bounds(), &render_surface_layer_list);
1778 inputs.can_adjust_raster_scales = true;
1779 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1780
1781 ASSERT_EQ(2U, render_surface_layer_list.size());
1782 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
1783 EXPECT_EQ(child->id(), render_surface_layer_list.at(1)->id());
1784 }
1785
TEST_F(LayerTreeHostCommonTest,ClipRectCullsSurfaceWithoutVisibleContent)1786 TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) {
1787 // When a render surface has a clip rect, it is used to clip the content rect
1788 // of the surface. When the render surface is animating its transforms, then
1789 // the content rect's position in the clip rect is not defined on the main
1790 // thread, and its content rect should not be clipped.
1791
1792 // The test tree is set up as follows:
1793 // - parent is a container layer that masksToBounds=true to cause clipping.
1794 // - child is a render surface, which has a clip rect set to the bounds of
1795 // the parent.
1796 // - grand_child is a render surface, and the only visible content in child.
1797 // It is positioned outside of the clip rect from parent.
1798
1799 // In this configuration, grand_child should be outside the clipped
1800 // content rect of the child, making grand_child not appear in the
1801 // render_surface_layer_list. However, when we place an animation on the
1802 // child, this clipping should be avoided and we should keep the grand_child
1803 // in the render_surface_layer_list.
1804
1805 const gfx::Transform identity_matrix;
1806 scoped_refptr<Layer> parent = Layer::Create();
1807 scoped_refptr<Layer> child = Layer::Create();
1808 scoped_refptr<Layer> grand_child = Layer::Create();
1809 scoped_refptr<LayerWithForcedDrawsContent> leaf_node =
1810 make_scoped_refptr(new LayerWithForcedDrawsContent());
1811 parent->AddChild(child);
1812 child->AddChild(grand_child);
1813 grand_child->AddChild(leaf_node);
1814
1815 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
1816 host->SetRootLayer(parent);
1817
1818 SetLayerPropertiesForTesting(parent.get(),
1819 identity_matrix,
1820 identity_matrix,
1821 gfx::PointF(),
1822 gfx::PointF(),
1823 gfx::Size(100, 100),
1824 false);
1825 SetLayerPropertiesForTesting(child.get(),
1826 identity_matrix,
1827 identity_matrix,
1828 gfx::PointF(),
1829 gfx::PointF(),
1830 gfx::Size(20, 20),
1831 false);
1832 SetLayerPropertiesForTesting(grand_child.get(),
1833 identity_matrix,
1834 identity_matrix,
1835 gfx::PointF(),
1836 gfx::PointF(200.f, 200.f),
1837 gfx::Size(10, 10),
1838 false);
1839 SetLayerPropertiesForTesting(leaf_node.get(),
1840 identity_matrix,
1841 identity_matrix,
1842 gfx::PointF(),
1843 gfx::PointF(),
1844 gfx::Size(10, 10),
1845 false);
1846
1847 parent->SetMasksToBounds(true);
1848 child->SetOpacity(0.4f);
1849 child->SetForceRenderSurface(true);
1850 grand_child->SetOpacity(0.4f);
1851 grand_child->SetForceRenderSurface(true);
1852
1853 {
1854 RenderSurfaceLayerList render_surface_layer_list;
1855 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1856 parent.get(), parent->bounds(), &render_surface_layer_list);
1857 inputs.can_adjust_raster_scales = true;
1858 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1859
1860 // Without an animation, we should cull child and grand_child from the
1861 // render_surface_layer_list.
1862 ASSERT_EQ(1U, render_surface_layer_list.size());
1863 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
1864 }
1865
1866 // Now put an animating transform on child.
1867 AddAnimatedTransformToController(
1868 child->layer_animation_controller(), 10.0, 30, 0);
1869
1870 {
1871 RenderSurfaceLayerList render_surface_layer_list;
1872 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1873 parent.get(), parent->bounds(), &render_surface_layer_list);
1874 inputs.can_adjust_raster_scales = true;
1875 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1876
1877 // With an animating transform, we should keep child and grand_child in the
1878 // render_surface_layer_list.
1879 ASSERT_EQ(3U, render_surface_layer_list.size());
1880 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
1881 EXPECT_EQ(child->id(), render_surface_layer_list.at(1)->id());
1882 EXPECT_EQ(grand_child->id(), render_surface_layer_list.at(2)->id());
1883 }
1884 }
1885
TEST_F(LayerTreeHostCommonTest,IsClippedIsSetCorrectly)1886 TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectly) {
1887 // Layer's IsClipped() property is set to true when:
1888 // - the layer clips its subtree, e.g. masks to bounds,
1889 // - the layer is clipped by an ancestor that contributes to the same
1890 // render target,
1891 // - a surface is clipped by an ancestor that contributes to the same
1892 // render target.
1893 //
1894 // In particular, for a layer that owns a render surface:
1895 // - the render surface inherits any clip from ancestors, and does NOT
1896 // pass that clipped status to the layer itself.
1897 // - but if the layer itself masks to bounds, it is considered clipped
1898 // and propagates the clip to the subtree.
1899
1900 const gfx::Transform identity_matrix;
1901 scoped_refptr<Layer> root = Layer::Create();
1902 scoped_refptr<Layer> parent = Layer::Create();
1903 scoped_refptr<Layer> child1 = Layer::Create();
1904 scoped_refptr<Layer> child2 = Layer::Create();
1905 scoped_refptr<Layer> grand_child = Layer::Create();
1906 scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 =
1907 make_scoped_refptr(new LayerWithForcedDrawsContent());
1908 scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 =
1909 make_scoped_refptr(new LayerWithForcedDrawsContent());
1910 root->AddChild(parent);
1911 parent->AddChild(child1);
1912 parent->AddChild(child2);
1913 child1->AddChild(grand_child);
1914 child2->AddChild(leaf_node2);
1915 grand_child->AddChild(leaf_node1);
1916
1917 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
1918 host->SetRootLayer(root);
1919
1920 child2->SetForceRenderSurface(true);
1921
1922 SetLayerPropertiesForTesting(root.get(),
1923 identity_matrix,
1924 identity_matrix,
1925 gfx::PointF(),
1926 gfx::PointF(),
1927 gfx::Size(100, 100),
1928 false);
1929 SetLayerPropertiesForTesting(parent.get(),
1930 identity_matrix,
1931 identity_matrix,
1932 gfx::PointF(),
1933 gfx::PointF(),
1934 gfx::Size(100, 100),
1935 false);
1936 SetLayerPropertiesForTesting(child1.get(),
1937 identity_matrix,
1938 identity_matrix,
1939 gfx::PointF(),
1940 gfx::PointF(),
1941 gfx::Size(100, 100),
1942 false);
1943 SetLayerPropertiesForTesting(child2.get(),
1944 identity_matrix,
1945 identity_matrix,
1946 gfx::PointF(),
1947 gfx::PointF(),
1948 gfx::Size(100, 100),
1949 false);
1950 SetLayerPropertiesForTesting(grand_child.get(),
1951 identity_matrix,
1952 identity_matrix,
1953 gfx::PointF(),
1954 gfx::PointF(),
1955 gfx::Size(100, 100),
1956 false);
1957 SetLayerPropertiesForTesting(leaf_node1.get(),
1958 identity_matrix,
1959 identity_matrix,
1960 gfx::PointF(),
1961 gfx::PointF(),
1962 gfx::Size(100, 100),
1963 false);
1964 SetLayerPropertiesForTesting(leaf_node2.get(),
1965 identity_matrix,
1966 identity_matrix,
1967 gfx::PointF(),
1968 gfx::PointF(),
1969 gfx::Size(100, 100),
1970 false);
1971
1972 // Case 1: nothing is clipped except the root render surface.
1973 {
1974 RenderSurfaceLayerList render_surface_layer_list;
1975 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
1976 root.get(), parent->bounds(), &render_surface_layer_list);
1977 inputs.can_adjust_raster_scales = true;
1978 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
1979
1980 ASSERT_TRUE(root->render_surface());
1981 ASSERT_TRUE(child2->render_surface());
1982
1983 EXPECT_FALSE(root->is_clipped());
1984 EXPECT_TRUE(root->render_surface()->is_clipped());
1985 EXPECT_FALSE(parent->is_clipped());
1986 EXPECT_FALSE(child1->is_clipped());
1987 EXPECT_FALSE(child2->is_clipped());
1988 EXPECT_FALSE(child2->render_surface()->is_clipped());
1989 EXPECT_FALSE(grand_child->is_clipped());
1990 EXPECT_FALSE(leaf_node1->is_clipped());
1991 EXPECT_FALSE(leaf_node2->is_clipped());
1992 }
1993
1994 // Case 2: parent masksToBounds, so the parent, child1, and child2's
1995 // surface are clipped. But layers that contribute to child2's surface are
1996 // not clipped explicitly because child2's surface already accounts for
1997 // that clip.
1998 {
1999 RenderSurfaceLayerList render_surface_layer_list;
2000 parent->SetMasksToBounds(true);
2001 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
2002 root.get(), parent->bounds(), &render_surface_layer_list);
2003 inputs.can_adjust_raster_scales = true;
2004 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
2005
2006 ASSERT_TRUE(root->render_surface());
2007 ASSERT_TRUE(child2->render_surface());
2008
2009 EXPECT_FALSE(root->is_clipped());
2010 EXPECT_TRUE(root->render_surface()->is_clipped());
2011 EXPECT_TRUE(parent->is_clipped());
2012 EXPECT_TRUE(child1->is_clipped());
2013 EXPECT_FALSE(child2->is_clipped());
2014 EXPECT_TRUE(child2->render_surface()->is_clipped());
2015 EXPECT_TRUE(grand_child->is_clipped());
2016 EXPECT_TRUE(leaf_node1->is_clipped());
2017 EXPECT_FALSE(leaf_node2->is_clipped());
2018 }
2019
2020 // Case 3: child2 masksToBounds. The layer and subtree are clipped, and
2021 // child2's render surface is not clipped.
2022 {
2023 RenderSurfaceLayerList render_surface_layer_list;
2024 parent->SetMasksToBounds(false);
2025 child2->SetMasksToBounds(true);
2026 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
2027 root.get(), parent->bounds(), &render_surface_layer_list);
2028 inputs.can_adjust_raster_scales = true;
2029 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
2030
2031 ASSERT_TRUE(root->render_surface());
2032 ASSERT_TRUE(child2->render_surface());
2033
2034 EXPECT_FALSE(root->is_clipped());
2035 EXPECT_TRUE(root->render_surface()->is_clipped());
2036 EXPECT_FALSE(parent->is_clipped());
2037 EXPECT_FALSE(child1->is_clipped());
2038 EXPECT_TRUE(child2->is_clipped());
2039 EXPECT_FALSE(child2->render_surface()->is_clipped());
2040 EXPECT_FALSE(grand_child->is_clipped());
2041 EXPECT_FALSE(leaf_node1->is_clipped());
2042 EXPECT_TRUE(leaf_node2->is_clipped());
2043 }
2044 }
2045
TEST_F(LayerTreeHostCommonTest,DrawableContentRectForLayers)2046 TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) {
2047 // Verify that layers get the appropriate DrawableContentRect when their
2048 // parent masksToBounds is true.
2049 //
2050 // grand_child1 - completely inside the region; DrawableContentRect should
2051 // be the layer rect expressed in target space.
2052 // grand_child2 - partially clipped but NOT masksToBounds; the clip rect
2053 // will be the intersection of layer bounds and the mask region.
2054 // grand_child3 - partially clipped and masksToBounds; the
2055 // DrawableContentRect will still be the intersection of layer bounds and
2056 // the mask region.
2057 // grand_child4 - outside parent's clip rect; the DrawableContentRect should
2058 // be empty.
2059 //
2060
2061 const gfx::Transform identity_matrix;
2062 scoped_refptr<Layer> parent = Layer::Create();
2063 scoped_refptr<Layer> child = Layer::Create();
2064 scoped_refptr<Layer> grand_child1 = Layer::Create();
2065 scoped_refptr<Layer> grand_child2 = Layer::Create();
2066 scoped_refptr<Layer> grand_child3 = Layer::Create();
2067 scoped_refptr<Layer> grand_child4 = Layer::Create();
2068
2069 parent->AddChild(child);
2070 child->AddChild(grand_child1);
2071 child->AddChild(grand_child2);
2072 child->AddChild(grand_child3);
2073 child->AddChild(grand_child4);
2074
2075 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
2076 host->SetRootLayer(parent);
2077
2078 SetLayerPropertiesForTesting(parent.get(),
2079 identity_matrix,
2080 identity_matrix,
2081 gfx::PointF(),
2082 gfx::PointF(),
2083 gfx::Size(500, 500),
2084 false);
2085 SetLayerPropertiesForTesting(child.get(),
2086 identity_matrix,
2087 identity_matrix,
2088 gfx::PointF(),
2089 gfx::PointF(),
2090 gfx::Size(20, 20),
2091 false);
2092 SetLayerPropertiesForTesting(grand_child1.get(),
2093 identity_matrix,
2094 identity_matrix,
2095 gfx::PointF(),
2096 gfx::PointF(5.f, 5.f),
2097 gfx::Size(10, 10),
2098 false);
2099 SetLayerPropertiesForTesting(grand_child2.get(),
2100 identity_matrix,
2101 identity_matrix,
2102 gfx::PointF(),
2103 gfx::PointF(15.f, 15.f),
2104 gfx::Size(10, 10),
2105 false);
2106 SetLayerPropertiesForTesting(grand_child3.get(),
2107 identity_matrix,
2108 identity_matrix,
2109 gfx::PointF(),
2110 gfx::PointF(15.f, 15.f),
2111 gfx::Size(10, 10),
2112 false);
2113 SetLayerPropertiesForTesting(grand_child4.get(),
2114 identity_matrix,
2115 identity_matrix,
2116 gfx::PointF(),
2117 gfx::PointF(45.f, 45.f),
2118 gfx::Size(10, 10),
2119 false);
2120
2121 child->SetMasksToBounds(true);
2122 grand_child3->SetMasksToBounds(true);
2123
2124 // Force everyone to be a render surface.
2125 child->SetOpacity(0.4f);
2126 grand_child1->SetOpacity(0.5f);
2127 grand_child2->SetOpacity(0.5f);
2128 grand_child3->SetOpacity(0.5f);
2129 grand_child4->SetOpacity(0.5f);
2130
2131 RenderSurfaceLayerList render_surface_layer_list;
2132 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
2133 parent.get(), parent->bounds(), &render_surface_layer_list);
2134 inputs.can_adjust_raster_scales = true;
2135 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
2136
2137 EXPECT_RECT_EQ(gfx::Rect(5, 5, 10, 10),
2138 grand_child1->drawable_content_rect());
2139 EXPECT_RECT_EQ(gfx::Rect(15, 15, 5, 5),
2140 grand_child3->drawable_content_rect());
2141 EXPECT_RECT_EQ(gfx::Rect(15, 15, 5, 5),
2142 grand_child3->drawable_content_rect());
2143 EXPECT_TRUE(grand_child4->drawable_content_rect().IsEmpty());
2144 }
2145
TEST_F(LayerTreeHostCommonTest,ClipRectIsPropagatedCorrectlyToSurfaces)2146 TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
2147 // Verify that render surfaces (and their layers) get the appropriate
2148 // clip rects when their parent masksToBounds is true.
2149 //
2150 // Layers that own render surfaces (at least for now) do not inherit any
2151 // clipping; instead the surface will enforce the clip for the entire subtree.
2152 // They may still have a clip rect of their own layer bounds, however, if
2153 // masksToBounds was true.
2154 const gfx::Transform identity_matrix;
2155 scoped_refptr<Layer> parent = Layer::Create();
2156 scoped_refptr<Layer> child = Layer::Create();
2157 scoped_refptr<Layer> grand_child1 = Layer::Create();
2158 scoped_refptr<Layer> grand_child2 = Layer::Create();
2159 scoped_refptr<Layer> grand_child3 = Layer::Create();
2160 scoped_refptr<Layer> grand_child4 = Layer::Create();
2161 scoped_refptr<LayerWithForcedDrawsContent> leaf_node1 =
2162 make_scoped_refptr(new LayerWithForcedDrawsContent());
2163 scoped_refptr<LayerWithForcedDrawsContent> leaf_node2 =
2164 make_scoped_refptr(new LayerWithForcedDrawsContent());
2165 scoped_refptr<LayerWithForcedDrawsContent> leaf_node3 =
2166 make_scoped_refptr(new LayerWithForcedDrawsContent());
2167 scoped_refptr<LayerWithForcedDrawsContent> leaf_node4 =
2168 make_scoped_refptr(new LayerWithForcedDrawsContent());
2169
2170 parent->AddChild(child);
2171 child->AddChild(grand_child1);
2172 child->AddChild(grand_child2);
2173 child->AddChild(grand_child3);
2174 child->AddChild(grand_child4);
2175
2176 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
2177 host->SetRootLayer(parent);
2178
2179 // the leaf nodes ensure that these grand_children become render surfaces for
2180 // this test.
2181 grand_child1->AddChild(leaf_node1);
2182 grand_child2->AddChild(leaf_node2);
2183 grand_child3->AddChild(leaf_node3);
2184 grand_child4->AddChild(leaf_node4);
2185
2186 SetLayerPropertiesForTesting(parent.get(),
2187 identity_matrix,
2188 identity_matrix,
2189 gfx::PointF(),
2190 gfx::PointF(),
2191 gfx::Size(500, 500),
2192 false);
2193 SetLayerPropertiesForTesting(child.get(),
2194 identity_matrix,
2195 identity_matrix,
2196 gfx::PointF(),
2197 gfx::PointF(),
2198 gfx::Size(20, 20),
2199 false);
2200 SetLayerPropertiesForTesting(grand_child1.get(),
2201 identity_matrix,
2202 identity_matrix,
2203 gfx::PointF(),
2204 gfx::PointF(5.f, 5.f),
2205 gfx::Size(10, 10),
2206 false);
2207 SetLayerPropertiesForTesting(grand_child2.get(),
2208 identity_matrix,
2209 identity_matrix,
2210 gfx::PointF(),
2211 gfx::PointF(15.f, 15.f),
2212 gfx::Size(10, 10),
2213 false);
2214 SetLayerPropertiesForTesting(grand_child3.get(),
2215 identity_matrix,
2216 identity_matrix,
2217 gfx::PointF(),
2218 gfx::PointF(15.f, 15.f),
2219 gfx::Size(10, 10),
2220 false);
2221 SetLayerPropertiesForTesting(grand_child4.get(),
2222 identity_matrix,
2223 identity_matrix,
2224 gfx::PointF(),
2225 gfx::PointF(45.f, 45.f),
2226 gfx::Size(10, 10),
2227 false);
2228 SetLayerPropertiesForTesting(leaf_node1.get(),
2229 identity_matrix,
2230 identity_matrix,
2231 gfx::PointF(),
2232 gfx::PointF(),
2233 gfx::Size(10, 10),
2234 false);
2235 SetLayerPropertiesForTesting(leaf_node2.get(),
2236 identity_matrix,
2237 identity_matrix,
2238 gfx::PointF(),
2239 gfx::PointF(),
2240 gfx::Size(10, 10),
2241 false);
2242 SetLayerPropertiesForTesting(leaf_node3.get(),
2243 identity_matrix,
2244 identity_matrix,
2245 gfx::PointF(),
2246 gfx::PointF(),
2247 gfx::Size(10, 10),
2248 false);
2249 SetLayerPropertiesForTesting(leaf_node4.get(),
2250 identity_matrix,
2251 identity_matrix,
2252 gfx::PointF(),
2253 gfx::PointF(),
2254 gfx::Size(10, 10),
2255 false);
2256
2257 child->SetMasksToBounds(true);
2258 grand_child3->SetMasksToBounds(true);
2259 grand_child4->SetMasksToBounds(true);
2260
2261 // Force everyone to be a render surface.
2262 child->SetOpacity(0.4f);
2263 child->SetForceRenderSurface(true);
2264 grand_child1->SetOpacity(0.5f);
2265 grand_child1->SetForceRenderSurface(true);
2266 grand_child2->SetOpacity(0.5f);
2267 grand_child2->SetForceRenderSurface(true);
2268 grand_child3->SetOpacity(0.5f);
2269 grand_child3->SetForceRenderSurface(true);
2270 grand_child4->SetOpacity(0.5f);
2271 grand_child4->SetForceRenderSurface(true);
2272
2273 RenderSurfaceLayerList render_surface_layer_list;
2274 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
2275 parent.get(), parent->bounds(), &render_surface_layer_list);
2276 inputs.can_adjust_raster_scales = true;
2277 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
2278 ASSERT_TRUE(grand_child1->render_surface());
2279 ASSERT_TRUE(grand_child2->render_surface());
2280 ASSERT_TRUE(grand_child3->render_surface());
2281 // Because grand_child4 is entirely clipped, it is expected to not have a
2282 // render surface.
2283 EXPECT_FALSE(grand_child4->render_surface());
2284
2285 // Surfaces are clipped by their parent, but un-affected by the owning layer's
2286 // masksToBounds.
2287 EXPECT_RECT_EQ(gfx::Rect(0, 0, 20, 20),
2288 grand_child1->render_surface()->clip_rect());
2289 EXPECT_RECT_EQ(gfx::Rect(0, 0, 20, 20),
2290 grand_child2->render_surface()->clip_rect());
2291 EXPECT_RECT_EQ(gfx::Rect(0, 0, 20, 20),
2292 grand_child3->render_surface()->clip_rect());
2293 }
2294
TEST_F(LayerTreeHostCommonTest,AnimationsForRenderSurfaceHierarchy)2295 TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) {
2296 scoped_refptr<Layer> parent = Layer::Create();
2297 scoped_refptr<Layer> render_surface1 = Layer::Create();
2298 scoped_refptr<Layer> render_surface2 = Layer::Create();
2299 scoped_refptr<Layer> child_of_root = Layer::Create();
2300 scoped_refptr<Layer> child_of_rs1 = Layer::Create();
2301 scoped_refptr<Layer> child_of_rs2 = Layer::Create();
2302 scoped_refptr<Layer> grand_child_of_root = Layer::Create();
2303 scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs1 =
2304 make_scoped_refptr(new LayerWithForcedDrawsContent());
2305 scoped_refptr<LayerWithForcedDrawsContent> grand_child_of_rs2 =
2306 make_scoped_refptr(new LayerWithForcedDrawsContent());
2307 parent->AddChild(render_surface1);
2308 parent->AddChild(child_of_root);
2309 render_surface1->AddChild(child_of_rs1);
2310 render_surface1->AddChild(render_surface2);
2311 render_surface2->AddChild(child_of_rs2);
2312 child_of_root->AddChild(grand_child_of_root);
2313 child_of_rs1->AddChild(grand_child_of_rs1);
2314 child_of_rs2->AddChild(grand_child_of_rs2);
2315
2316 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
2317 host->SetRootLayer(parent);
2318
2319 // Make our render surfaces.
2320 render_surface1->SetForceRenderSurface(true);
2321 render_surface2->SetForceRenderSurface(true);
2322
2323 gfx::Transform layer_transform;
2324 layer_transform.Translate(1.0, 1.0);
2325 gfx::Transform sublayer_transform;
2326 sublayer_transform.Scale3d(10.0, 1.0, 1.0);
2327
2328 SetLayerPropertiesForTesting(parent.get(),
2329 layer_transform,
2330 sublayer_transform,
2331 gfx::PointF(0.25f, 0.f),
2332 gfx::PointF(2.5f, 0.f),
2333 gfx::Size(10, 10),
2334 false);
2335 SetLayerPropertiesForTesting(render_surface1.get(),
2336 layer_transform,
2337 sublayer_transform,
2338 gfx::PointF(0.25f, 0.f),
2339 gfx::PointF(2.5f, 0.f),
2340 gfx::Size(10, 10),
2341 false);
2342 SetLayerPropertiesForTesting(render_surface2.get(),
2343 layer_transform,
2344 sublayer_transform,
2345 gfx::PointF(0.25f, 0.f),
2346 gfx::PointF(2.5f, 0.f),
2347 gfx::Size(10, 10),
2348 false);
2349 SetLayerPropertiesForTesting(child_of_root.get(),
2350 layer_transform,
2351 sublayer_transform,
2352 gfx::PointF(0.25f, 0.f),
2353 gfx::PointF(2.5f, 0.f),
2354 gfx::Size(10, 10),
2355 false);
2356 SetLayerPropertiesForTesting(child_of_rs1.get(),
2357 layer_transform,
2358 sublayer_transform,
2359 gfx::PointF(0.25f, 0.f),
2360 gfx::PointF(2.5f, 0.f),
2361 gfx::Size(10, 10),
2362 false);
2363 SetLayerPropertiesForTesting(child_of_rs2.get(),
2364 layer_transform,
2365 sublayer_transform,
2366 gfx::PointF(0.25f, 0.f),
2367 gfx::PointF(2.5f, 0.f),
2368 gfx::Size(10, 10),
2369 false);
2370 SetLayerPropertiesForTesting(grand_child_of_root.get(),
2371 layer_transform,
2372 sublayer_transform,
2373 gfx::PointF(0.25f, 0.f),
2374 gfx::PointF(2.5f, 0.f),
2375 gfx::Size(10, 10),
2376 false);
2377 SetLayerPropertiesForTesting(grand_child_of_rs1.get(),
2378 layer_transform,
2379 sublayer_transform,
2380 gfx::PointF(0.25f, 0.f),
2381 gfx::PointF(2.5f, 0.f),
2382 gfx::Size(10, 10),
2383 false);
2384 SetLayerPropertiesForTesting(grand_child_of_rs2.get(),
2385 layer_transform,
2386 sublayer_transform,
2387 gfx::PointF(0.25f, 0.f),
2388 gfx::PointF(2.5f, 0.f),
2389 gfx::Size(10, 10),
2390 false);
2391
2392 // Put an animated opacity on the render surface.
2393 AddOpacityTransitionToController(
2394 render_surface1->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2395
2396 // Also put an animated opacity on a layer without descendants.
2397 AddOpacityTransitionToController(
2398 grand_child_of_root->layer_animation_controller(), 10.0, 1.f, 0.f, false);
2399
2400 // Put a transform animation on the render surface.
2401 AddAnimatedTransformToController(
2402 render_surface2->layer_animation_controller(), 10.0, 30, 0);
2403
2404 // Also put transform animations on grand_child_of_root, and
2405 // grand_child_of_rs2
2406 AddAnimatedTransformToController(
2407 grand_child_of_root->layer_animation_controller(), 10.0, 30, 0);
2408 AddAnimatedTransformToController(
2409 grand_child_of_rs2->layer_animation_controller(), 10.0, 30, 0);
2410
2411 ExecuteCalculateDrawProperties(parent.get());
2412
2413 // Only layers that are associated with render surfaces should have an actual
2414 // RenderSurface() value.
2415 ASSERT_TRUE(parent->render_surface());
2416 ASSERT_FALSE(child_of_root->render_surface());
2417 ASSERT_FALSE(grand_child_of_root->render_surface());
2418
2419 ASSERT_TRUE(render_surface1->render_surface());
2420 ASSERT_FALSE(child_of_rs1->render_surface());
2421 ASSERT_FALSE(grand_child_of_rs1->render_surface());
2422
2423 ASSERT_TRUE(render_surface2->render_surface());
2424 ASSERT_FALSE(child_of_rs2->render_surface());
2425 ASSERT_FALSE(grand_child_of_rs2->render_surface());
2426
2427 // Verify all render target accessors
2428 EXPECT_EQ(parent, parent->render_target());
2429 EXPECT_EQ(parent, child_of_root->render_target());
2430 EXPECT_EQ(parent, grand_child_of_root->render_target());
2431
2432 EXPECT_EQ(render_surface1, render_surface1->render_target());
2433 EXPECT_EQ(render_surface1, child_of_rs1->render_target());
2434 EXPECT_EQ(render_surface1, grand_child_of_rs1->render_target());
2435
2436 EXPECT_EQ(render_surface2, render_surface2->render_target());
2437 EXPECT_EQ(render_surface2, child_of_rs2->render_target());
2438 EXPECT_EQ(render_surface2, grand_child_of_rs2->render_target());
2439
2440 // Verify draw_opacity_is_animating values
2441 EXPECT_FALSE(parent->draw_opacity_is_animating());
2442 EXPECT_FALSE(child_of_root->draw_opacity_is_animating());
2443 EXPECT_TRUE(grand_child_of_root->draw_opacity_is_animating());
2444 EXPECT_FALSE(render_surface1->draw_opacity_is_animating());
2445 EXPECT_TRUE(render_surface1->render_surface()->draw_opacity_is_animating());
2446 EXPECT_FALSE(child_of_rs1->draw_opacity_is_animating());
2447 EXPECT_FALSE(grand_child_of_rs1->draw_opacity_is_animating());
2448 EXPECT_FALSE(render_surface2->draw_opacity_is_animating());
2449 EXPECT_FALSE(render_surface2->render_surface()->draw_opacity_is_animating());
2450 EXPECT_FALSE(child_of_rs2->draw_opacity_is_animating());
2451 EXPECT_FALSE(grand_child_of_rs2->draw_opacity_is_animating());
2452
2453 // Verify draw_transform_is_animating values
2454 EXPECT_FALSE(parent->draw_transform_is_animating());
2455 EXPECT_FALSE(child_of_root->draw_transform_is_animating());
2456 EXPECT_TRUE(grand_child_of_root->draw_transform_is_animating());
2457 EXPECT_FALSE(render_surface1->draw_transform_is_animating());
2458 EXPECT_FALSE(render_surface1->render_surface()
2459 ->target_surface_transforms_are_animating());
2460 EXPECT_FALSE(child_of_rs1->draw_transform_is_animating());
2461 EXPECT_FALSE(grand_child_of_rs1->draw_transform_is_animating());
2462 EXPECT_FALSE(render_surface2->draw_transform_is_animating());
2463 EXPECT_TRUE(render_surface2->render_surface()
2464 ->target_surface_transforms_are_animating());
2465 EXPECT_FALSE(child_of_rs2->draw_transform_is_animating());
2466 EXPECT_TRUE(grand_child_of_rs2->draw_transform_is_animating());
2467
2468 // Verify screen_space_transform_is_animating values
2469 EXPECT_FALSE(parent->screen_space_transform_is_animating());
2470 EXPECT_FALSE(child_of_root->screen_space_transform_is_animating());
2471 EXPECT_TRUE(grand_child_of_root->screen_space_transform_is_animating());
2472 EXPECT_FALSE(render_surface1->screen_space_transform_is_animating());
2473 EXPECT_FALSE(render_surface1->render_surface()
2474 ->screen_space_transforms_are_animating());
2475 EXPECT_FALSE(child_of_rs1->screen_space_transform_is_animating());
2476 EXPECT_FALSE(grand_child_of_rs1->screen_space_transform_is_animating());
2477 EXPECT_TRUE(render_surface2->screen_space_transform_is_animating());
2478 EXPECT_TRUE(render_surface2->render_surface()
2479 ->screen_space_transforms_are_animating());
2480 EXPECT_TRUE(child_of_rs2->screen_space_transform_is_animating());
2481 EXPECT_TRUE(grand_child_of_rs2->screen_space_transform_is_animating());
2482
2483 // Sanity check. If these fail there is probably a bug in the test itself.
2484 // It is expected that we correctly set up transforms so that the y-component
2485 // of the screen-space transform encodes the "depth" of the layer in the tree.
2486 EXPECT_FLOAT_EQ(1.0, parent->screen_space_transform().matrix().get(1, 3));
2487 EXPECT_FLOAT_EQ(2.0,
2488 child_of_root->screen_space_transform().matrix().get(1, 3));
2489 EXPECT_FLOAT_EQ(
2490 3.0, grand_child_of_root->screen_space_transform().matrix().get(1, 3));
2491
2492 EXPECT_FLOAT_EQ(2.0,
2493 render_surface1->screen_space_transform().matrix().get(1, 3));
2494 EXPECT_FLOAT_EQ(3.0,
2495 child_of_rs1->screen_space_transform().matrix().get(1, 3));
2496 EXPECT_FLOAT_EQ(
2497 4.0, grand_child_of_rs1->screen_space_transform().matrix().get(1, 3));
2498
2499 EXPECT_FLOAT_EQ(3.0,
2500 render_surface2->screen_space_transform().matrix().get(1, 3));
2501 EXPECT_FLOAT_EQ(4.0,
2502 child_of_rs2->screen_space_transform().matrix().get(1, 3));
2503 EXPECT_FLOAT_EQ(
2504 5.0, grand_child_of_rs2->screen_space_transform().matrix().get(1, 3));
2505 }
2506
TEST_F(LayerTreeHostCommonTest,VisibleRectForIdentityTransform)2507 TEST_F(LayerTreeHostCommonTest, VisibleRectForIdentityTransform) {
2508 // Test the calculateVisibleRect() function works correctly for identity
2509 // transforms.
2510
2511 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
2512 gfx::Transform layer_to_surface_transform;
2513
2514 // Case 1: Layer is contained within the surface.
2515 gfx::Rect layer_content_rect = gfx::Rect(10, 10, 30, 30);
2516 gfx::Rect expected = gfx::Rect(10, 10, 30, 30);
2517 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
2518 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2519 EXPECT_RECT_EQ(expected, actual);
2520
2521 // Case 2: Layer is outside the surface rect.
2522 layer_content_rect = gfx::Rect(120, 120, 30, 30);
2523 actual = LayerTreeHostCommon::CalculateVisibleRect(
2524 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2525 EXPECT_TRUE(actual.IsEmpty());
2526
2527 // Case 3: Layer is partially overlapping the surface rect.
2528 layer_content_rect = gfx::Rect(80, 80, 30, 30);
2529 expected = gfx::Rect(80, 80, 20, 20);
2530 actual = LayerTreeHostCommon::CalculateVisibleRect(
2531 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2532 EXPECT_RECT_EQ(expected, actual);
2533 }
2534
TEST_F(LayerTreeHostCommonTest,VisibleRectForTranslations)2535 TEST_F(LayerTreeHostCommonTest, VisibleRectForTranslations) {
2536 // Test the calculateVisibleRect() function works correctly for scaling
2537 // transforms.
2538
2539 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
2540 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30);
2541 gfx::Transform layer_to_surface_transform;
2542
2543 // Case 1: Layer is contained within the surface.
2544 layer_to_surface_transform.MakeIdentity();
2545 layer_to_surface_transform.Translate(10.0, 10.0);
2546 gfx::Rect expected = gfx::Rect(0, 0, 30, 30);
2547 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
2548 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2549 EXPECT_RECT_EQ(expected, actual);
2550
2551 // Case 2: Layer is outside the surface rect.
2552 layer_to_surface_transform.MakeIdentity();
2553 layer_to_surface_transform.Translate(120.0, 120.0);
2554 actual = LayerTreeHostCommon::CalculateVisibleRect(
2555 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2556 EXPECT_TRUE(actual.IsEmpty());
2557
2558 // Case 3: Layer is partially overlapping the surface rect.
2559 layer_to_surface_transform.MakeIdentity();
2560 layer_to_surface_transform.Translate(80.0, 80.0);
2561 expected = gfx::Rect(0, 0, 20, 20);
2562 actual = LayerTreeHostCommon::CalculateVisibleRect(
2563 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2564 EXPECT_RECT_EQ(expected, actual);
2565 }
2566
TEST_F(LayerTreeHostCommonTest,VisibleRectFor2DRotations)2567 TEST_F(LayerTreeHostCommonTest, VisibleRectFor2DRotations) {
2568 // Test the calculateVisibleRect() function works correctly for rotations
2569 // about z-axis (i.e. 2D rotations). Remember that calculateVisibleRect()
2570 // should return the g in the layer's space.
2571
2572 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
2573 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30);
2574 gfx::Transform layer_to_surface_transform;
2575
2576 // Case 1: Layer is contained within the surface.
2577 layer_to_surface_transform.MakeIdentity();
2578 layer_to_surface_transform.Translate(50.0, 50.0);
2579 layer_to_surface_transform.Rotate(45.0);
2580 gfx::Rect expected = gfx::Rect(0, 0, 30, 30);
2581 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
2582 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2583 EXPECT_RECT_EQ(expected, actual);
2584
2585 // Case 2: Layer is outside the surface rect.
2586 layer_to_surface_transform.MakeIdentity();
2587 layer_to_surface_transform.Translate(-50.0, 0.0);
2588 layer_to_surface_transform.Rotate(45.0);
2589 actual = LayerTreeHostCommon::CalculateVisibleRect(
2590 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2591 EXPECT_TRUE(actual.IsEmpty());
2592
2593 // Case 3: The layer is rotated about its top-left corner. In surface space,
2594 // the layer is oriented diagonally, with the left half outside of the render
2595 // surface. In this case, the g should still be the entire layer
2596 // (remember the g is computed in layer space); both the top-left
2597 // and bottom-right corners of the layer are still visible.
2598 layer_to_surface_transform.MakeIdentity();
2599 layer_to_surface_transform.Rotate(45.0);
2600 expected = gfx::Rect(0, 0, 30, 30);
2601 actual = LayerTreeHostCommon::CalculateVisibleRect(
2602 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2603 EXPECT_RECT_EQ(expected, actual);
2604
2605 // Case 4: The layer is rotated about its top-left corner, and translated
2606 // upwards. In surface space, the layer is oriented diagonally, with only the
2607 // top corner of the surface overlapping the layer. In layer space, the render
2608 // surface overlaps the right side of the layer. The g should be
2609 // the layer's right half.
2610 layer_to_surface_transform.MakeIdentity();
2611 layer_to_surface_transform.Translate(0.0, -sqrt(2.0) * 15.0);
2612 layer_to_surface_transform.Rotate(45.0);
2613 expected = gfx::Rect(15, 0, 15, 30); // Right half of layer bounds.
2614 actual = LayerTreeHostCommon::CalculateVisibleRect(
2615 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2616 EXPECT_RECT_EQ(expected, actual);
2617 }
2618
TEST_F(LayerTreeHostCommonTest,VisibleRectFor3dOrthographicTransform)2619 TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dOrthographicTransform) {
2620 // Test that the calculateVisibleRect() function works correctly for 3d
2621 // transforms.
2622
2623 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
2624 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100);
2625 gfx::Transform layer_to_surface_transform;
2626
2627 // Case 1: Orthographic projection of a layer rotated about y-axis by 45
2628 // degrees, should be fully contained in the render surface.
2629 layer_to_surface_transform.MakeIdentity();
2630 layer_to_surface_transform.RotateAboutYAxis(45.0);
2631 gfx::Rect expected = gfx::Rect(0, 0, 100, 100);
2632 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
2633 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2634 EXPECT_RECT_EQ(expected, actual);
2635
2636 // Case 2: Orthographic projection of a layer rotated about y-axis by 45
2637 // degrees, but shifted to the side so only the right-half the layer would be
2638 // visible on the surface.
2639 // 100 is the un-rotated layer width; divided by sqrt(2) is the rotated width.
2640 SkMScalar half_width_of_rotated_layer =
2641 SkDoubleToMScalar((100.0 / sqrt(2.0)) * 0.5);
2642 layer_to_surface_transform.MakeIdentity();
2643 layer_to_surface_transform.Translate(-half_width_of_rotated_layer, 0.0);
2644 layer_to_surface_transform.RotateAboutYAxis(45.0); // Rotates about the left
2645 // edge of the layer.
2646 expected = gfx::Rect(50, 0, 50, 100); // Tight half of the layer.
2647 actual = LayerTreeHostCommon::CalculateVisibleRect(
2648 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2649 EXPECT_RECT_EQ(expected, actual);
2650 }
2651
TEST_F(LayerTreeHostCommonTest,VisibleRectFor3dPerspectiveTransform)2652 TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveTransform) {
2653 // Test the calculateVisibleRect() function works correctly when the layer has
2654 // a perspective projection onto the target surface.
2655
2656 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
2657 gfx::Rect layer_content_rect = gfx::Rect(-50, -50, 200, 200);
2658 gfx::Transform layer_to_surface_transform;
2659
2660 // Case 1: Even though the layer is twice as large as the surface, due to
2661 // perspective foreshortening, the layer will fit fully in the surface when
2662 // its translated more than the perspective amount.
2663 layer_to_surface_transform.MakeIdentity();
2664
2665 // The following sequence of transforms applies the perspective about the
2666 // center of the surface.
2667 layer_to_surface_transform.Translate(50.0, 50.0);
2668 layer_to_surface_transform.ApplyPerspectiveDepth(9.0);
2669 layer_to_surface_transform.Translate(-50.0, -50.0);
2670
2671 // This translate places the layer in front of the surface's projection plane.
2672 layer_to_surface_transform.Translate3d(0.0, 0.0, -27.0);
2673
2674 gfx::Rect expected = gfx::Rect(-50, -50, 200, 200);
2675 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
2676 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2677 EXPECT_RECT_EQ(expected, actual);
2678
2679 // Case 2: same projection as before, except that the layer is also translated
2680 // to the side, so that only the right half of the layer should be visible.
2681 //
2682 // Explanation of expected result: The perspective ratio is (z distance
2683 // between layer and camera origin) / (z distance between projection plane and
2684 // camera origin) == ((-27 - 9) / 9) Then, by similar triangles, if we want to
2685 // move a layer by translating -50 units in projected surface units (so that
2686 // only half of it is visible), then we would need to translate by (-36 / 9) *
2687 // -50 == -200 in the layer's units.
2688 layer_to_surface_transform.Translate3d(-200.0, 0.0, 0.0);
2689 expected = gfx::Rect(gfx::Point(50, -50),
2690 gfx::Size(100, 200)); // The right half of the layer's
2691 // bounding rect.
2692 actual = LayerTreeHostCommon::CalculateVisibleRect(
2693 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2694 EXPECT_RECT_EQ(expected, actual);
2695 }
2696
TEST_F(LayerTreeHostCommonTest,VisibleRectFor3dOrthographicIsNotClippedBehindSurface)2697 TEST_F(LayerTreeHostCommonTest,
2698 VisibleRectFor3dOrthographicIsNotClippedBehindSurface) {
2699 // There is currently no explicit concept of an orthographic projection plane
2700 // in our code (nor in the CSS spec to my knowledge). Therefore, layers that
2701 // are technically behind the surface in an orthographic world should not be
2702 // clipped when they are flattened to the surface.
2703
2704 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
2705 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100);
2706 gfx::Transform layer_to_surface_transform;
2707
2708 // This sequence of transforms effectively rotates the layer about the y-axis
2709 // at the center of the layer.
2710 layer_to_surface_transform.MakeIdentity();
2711 layer_to_surface_transform.Translate(50.0, 0.0);
2712 layer_to_surface_transform.RotateAboutYAxis(45.0);
2713 layer_to_surface_transform.Translate(-50.0, 0.0);
2714
2715 gfx::Rect expected = gfx::Rect(0, 0, 100, 100);
2716 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
2717 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2718 EXPECT_RECT_EQ(expected, actual);
2719 }
2720
TEST_F(LayerTreeHostCommonTest,VisibleRectFor3dPerspectiveWhenClippedByW)2721 TEST_F(LayerTreeHostCommonTest, VisibleRectFor3dPerspectiveWhenClippedByW) {
2722 // Test the calculateVisibleRect() function works correctly when projecting a
2723 // surface onto a layer, but the layer is partially behind the camera (not
2724 // just behind the projection plane). In this case, the cartesian coordinates
2725 // may seem to be valid, but actually they are not. The visible rect needs to
2726 // be properly clipped by the w = 0 plane in homogeneous coordinates before
2727 // converting to cartesian coordinates.
2728
2729 gfx::Rect target_surface_rect = gfx::Rect(-50, -50, 100, 100);
2730 gfx::Rect layer_content_rect = gfx::Rect(-10, -1, 20, 2);
2731 gfx::Transform layer_to_surface_transform;
2732
2733 // The layer is positioned so that the right half of the layer should be in
2734 // front of the camera, while the other half is behind the surface's
2735 // projection plane. The following sequence of transforms applies the
2736 // perspective and rotation about the center of the layer.
2737 layer_to_surface_transform.MakeIdentity();
2738 layer_to_surface_transform.ApplyPerspectiveDepth(1.0);
2739 layer_to_surface_transform.Translate3d(-2.0, 0.0, 1.0);
2740 layer_to_surface_transform.RotateAboutYAxis(45.0);
2741
2742 // Sanity check that this transform does indeed cause w < 0 when applying the
2743 // transform, otherwise this code is not testing the intended scenario.
2744 bool clipped;
2745 MathUtil::MapQuad(layer_to_surface_transform,
2746 gfx::QuadF(gfx::RectF(layer_content_rect)),
2747 &clipped);
2748 ASSERT_TRUE(clipped);
2749
2750 int expected_x_position = 0;
2751 int expected_width = 10;
2752 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
2753 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2754 EXPECT_EQ(expected_x_position, actual.x());
2755 EXPECT_EQ(expected_width, actual.width());
2756 }
2757
TEST_F(LayerTreeHostCommonTest,VisibleRectForPerspectiveUnprojection)2758 TEST_F(LayerTreeHostCommonTest, VisibleRectForPerspectiveUnprojection) {
2759 // To determine visible rect in layer space, there needs to be an
2760 // un-projection from surface space to layer space. When the original
2761 // transform was a perspective projection that was clipped, it returns a rect
2762 // that encloses the clipped bounds. Un-projecting this new rect may require
2763 // clipping again.
2764
2765 // This sequence of transforms causes one corner of the layer to protrude
2766 // across the w = 0 plane, and should be clipped.
2767 gfx::Rect target_surface_rect = gfx::Rect(-50, -50, 100, 100);
2768 gfx::Rect layer_content_rect = gfx::Rect(-10, -10, 20, 20);
2769 gfx::Transform layer_to_surface_transform;
2770 layer_to_surface_transform.MakeIdentity();
2771 layer_to_surface_transform.ApplyPerspectiveDepth(1.0);
2772 layer_to_surface_transform.Translate3d(0.0, 0.0, -5.0);
2773 layer_to_surface_transform.RotateAboutYAxis(45.0);
2774 layer_to_surface_transform.RotateAboutXAxis(80.0);
2775
2776 // Sanity check that un-projection does indeed cause w < 0, otherwise this
2777 // code is not testing the intended scenario.
2778 bool clipped;
2779 gfx::RectF clipped_rect =
2780 MathUtil::MapClippedRect(layer_to_surface_transform, layer_content_rect);
2781 MathUtil::ProjectQuad(
2782 Inverse(layer_to_surface_transform), gfx::QuadF(clipped_rect), &clipped);
2783 ASSERT_TRUE(clipped);
2784
2785 // Only the corner of the layer is not visible on the surface because of being
2786 // clipped. But, the net result of rounding visible region to an axis-aligned
2787 // rect is that the entire layer should still be considered visible.
2788 gfx::Rect expected = gfx::Rect(-10, -10, 20, 20);
2789 gfx::Rect actual = LayerTreeHostCommon::CalculateVisibleRect(
2790 target_surface_rect, layer_content_rect, layer_to_surface_transform);
2791 EXPECT_RECT_EQ(expected, actual);
2792 }
2793
TEST_F(LayerTreeHostCommonTest,DrawableAndVisibleContentRectsForSimpleLayers)2794 TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) {
2795 scoped_refptr<Layer> root = Layer::Create();
2796 scoped_refptr<LayerWithForcedDrawsContent> child1 =
2797 make_scoped_refptr(new LayerWithForcedDrawsContent());
2798 scoped_refptr<LayerWithForcedDrawsContent> child2 =
2799 make_scoped_refptr(new LayerWithForcedDrawsContent());
2800 scoped_refptr<LayerWithForcedDrawsContent> child3 =
2801 make_scoped_refptr(new LayerWithForcedDrawsContent());
2802 root->AddChild(child1);
2803 root->AddChild(child2);
2804 root->AddChild(child3);
2805
2806 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
2807 host->SetRootLayer(root);
2808
2809 gfx::Transform identity_matrix;
2810 SetLayerPropertiesForTesting(root.get(),
2811 identity_matrix,
2812 identity_matrix,
2813 gfx::PointF(),
2814 gfx::PointF(),
2815 gfx::Size(100, 100),
2816 false);
2817 SetLayerPropertiesForTesting(child1.get(),
2818 identity_matrix,
2819 identity_matrix,
2820 gfx::PointF(),
2821 gfx::PointF(),
2822 gfx::Size(50, 50),
2823 false);
2824 SetLayerPropertiesForTesting(child2.get(),
2825 identity_matrix,
2826 identity_matrix,
2827 gfx::PointF(),
2828 gfx::PointF(75.f, 75.f),
2829 gfx::Size(50, 50),
2830 false);
2831 SetLayerPropertiesForTesting(child3.get(),
2832 identity_matrix,
2833 identity_matrix,
2834 gfx::PointF(),
2835 gfx::PointF(125.f, 125.f),
2836 gfx::Size(50, 50),
2837 false);
2838
2839 ExecuteCalculateDrawProperties(root.get());
2840
2841 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2842 root->render_surface()->DrawableContentRect());
2843 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
2844
2845 // Layers that do not draw content should have empty visible_content_rects.
2846 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
2847
2848 // layer visible_content_rects are clipped by their target surface.
2849 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
2850 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_content_rect());
2851 EXPECT_TRUE(child3->visible_content_rect().IsEmpty());
2852
2853 // layer drawable_content_rects are not clipped.
2854 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->drawable_content_rect());
2855 EXPECT_RECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
2856 EXPECT_RECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
2857 }
2858
TEST_F(LayerTreeHostCommonTest,DrawableAndVisibleContentRectsForLayersClippedByLayer)2859 TEST_F(LayerTreeHostCommonTest,
2860 DrawableAndVisibleContentRectsForLayersClippedByLayer) {
2861 scoped_refptr<Layer> root = Layer::Create();
2862 scoped_refptr<Layer> child = Layer::Create();
2863 scoped_refptr<LayerWithForcedDrawsContent> grand_child1 =
2864 make_scoped_refptr(new LayerWithForcedDrawsContent());
2865 scoped_refptr<LayerWithForcedDrawsContent> grand_child2 =
2866 make_scoped_refptr(new LayerWithForcedDrawsContent());
2867 scoped_refptr<LayerWithForcedDrawsContent> grand_child3 =
2868 make_scoped_refptr(new LayerWithForcedDrawsContent());
2869 root->AddChild(child);
2870 child->AddChild(grand_child1);
2871 child->AddChild(grand_child2);
2872 child->AddChild(grand_child3);
2873
2874 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
2875 host->SetRootLayer(root);
2876
2877 gfx::Transform identity_matrix;
2878 SetLayerPropertiesForTesting(root.get(),
2879 identity_matrix,
2880 identity_matrix,
2881 gfx::PointF(),
2882 gfx::PointF(),
2883 gfx::Size(100, 100),
2884 false);
2885 SetLayerPropertiesForTesting(child.get(),
2886 identity_matrix,
2887 identity_matrix,
2888 gfx::PointF(),
2889 gfx::PointF(),
2890 gfx::Size(100, 100),
2891 false);
2892 SetLayerPropertiesForTesting(grand_child1.get(),
2893 identity_matrix,
2894 identity_matrix,
2895 gfx::PointF(),
2896 gfx::PointF(5.f, 5.f),
2897 gfx::Size(50, 50),
2898 false);
2899 SetLayerPropertiesForTesting(grand_child2.get(),
2900 identity_matrix,
2901 identity_matrix,
2902 gfx::PointF(),
2903 gfx::PointF(75.f, 75.f),
2904 gfx::Size(50, 50),
2905 false);
2906 SetLayerPropertiesForTesting(grand_child3.get(),
2907 identity_matrix,
2908 identity_matrix,
2909 gfx::PointF(),
2910 gfx::PointF(125.f, 125.f),
2911 gfx::Size(50, 50),
2912 false);
2913
2914 child->SetMasksToBounds(true);
2915 ExecuteCalculateDrawProperties(root.get());
2916
2917 ASSERT_FALSE(child->render_surface());
2918
2919 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
2920 root->render_surface()->DrawableContentRect());
2921 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
2922
2923 // Layers that do not draw content should have empty visible content rects.
2924 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
2925 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), child->visible_content_rect());
2926
2927 // All grandchild visible content rects should be clipped by child.
2928 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), grand_child1->visible_content_rect());
2929 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), grand_child2->visible_content_rect());
2930 EXPECT_TRUE(grand_child3->visible_content_rect().IsEmpty());
2931
2932 // All grandchild DrawableContentRects should also be clipped by child.
2933 EXPECT_RECT_EQ(gfx::Rect(5, 5, 50, 50),
2934 grand_child1->drawable_content_rect());
2935 EXPECT_RECT_EQ(gfx::Rect(75, 75, 25, 25),
2936 grand_child2->drawable_content_rect());
2937 EXPECT_TRUE(grand_child3->drawable_content_rect().IsEmpty());
2938 }
2939
TEST_F(LayerTreeHostCommonTest,DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface)2940 TEST_F(LayerTreeHostCommonTest,
2941 DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) {
2942 scoped_refptr<Layer> root = Layer::Create();
2943 scoped_refptr<Layer> render_surface1 = Layer::Create();
2944 scoped_refptr<LayerWithForcedDrawsContent> child1 =
2945 make_scoped_refptr(new LayerWithForcedDrawsContent());
2946 scoped_refptr<LayerWithForcedDrawsContent> child2 =
2947 make_scoped_refptr(new LayerWithForcedDrawsContent());
2948 scoped_refptr<LayerWithForcedDrawsContent> child3 =
2949 make_scoped_refptr(new LayerWithForcedDrawsContent());
2950 root->AddChild(render_surface1);
2951 render_surface1->AddChild(child1);
2952 render_surface1->AddChild(child2);
2953 render_surface1->AddChild(child3);
2954
2955 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
2956 host->SetRootLayer(root);
2957
2958 gfx::Transform identity_matrix;
2959 SetLayerPropertiesForTesting(root.get(),
2960 identity_matrix,
2961 identity_matrix,
2962 gfx::PointF(),
2963 gfx::PointF(),
2964 gfx::Size(100, 100),
2965 false);
2966 SetLayerPropertiesForTesting(render_surface1.get(),
2967 identity_matrix,
2968 identity_matrix,
2969 gfx::PointF(),
2970 gfx::PointF(),
2971 gfx::Size(3, 4),
2972 false);
2973 SetLayerPropertiesForTesting(child1.get(),
2974 identity_matrix,
2975 identity_matrix,
2976 gfx::PointF(),
2977 gfx::PointF(5.f, 5.f),
2978 gfx::Size(50, 50),
2979 false);
2980 SetLayerPropertiesForTesting(child2.get(),
2981 identity_matrix,
2982 identity_matrix,
2983 gfx::PointF(),
2984 gfx::PointF(75.f, 75.f),
2985 gfx::Size(50, 50),
2986 false);
2987 SetLayerPropertiesForTesting(child3.get(),
2988 identity_matrix,
2989 identity_matrix,
2990 gfx::PointF(),
2991 gfx::PointF(125.f, 125.f),
2992 gfx::Size(50, 50),
2993 false);
2994
2995 render_surface1->SetForceRenderSurface(true);
2996 ExecuteCalculateDrawProperties(root.get());
2997
2998 ASSERT_TRUE(render_surface1->render_surface());
2999
3000 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3001 root->render_surface()->DrawableContentRect());
3002 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
3003
3004 // Layers that do not draw content should have empty visible content rects.
3005 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
3006 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3007 render_surface1->visible_content_rect());
3008
3009 // An unclipped surface grows its DrawableContentRect to include all drawable
3010 // regions of the subtree.
3011 EXPECT_RECT_EQ(gfx::Rect(5, 5, 170, 170),
3012 render_surface1->render_surface()->DrawableContentRect());
3013
3014 // All layers that draw content into the unclipped surface are also unclipped.
3015 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
3016 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect());
3017 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect());
3018
3019 EXPECT_RECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
3020 EXPECT_RECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
3021 EXPECT_RECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
3022 }
3023
TEST_F(LayerTreeHostCommonTest,DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform)3024 TEST_F(LayerTreeHostCommonTest,
3025 DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) {
3026 scoped_refptr<Layer> root = Layer::Create();
3027 scoped_refptr<LayerWithForcedDrawsContent> child =
3028 make_scoped_refptr(new LayerWithForcedDrawsContent());
3029 root->AddChild(child);
3030
3031 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
3032 host->SetRootLayer(root);
3033
3034 // Case 1: a truly degenerate matrix
3035 gfx::Transform identity_matrix;
3036 gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
3037 ASSERT_FALSE(uninvertible_matrix.IsInvertible());
3038
3039 SetLayerPropertiesForTesting(root.get(),
3040 identity_matrix,
3041 identity_matrix,
3042 gfx::PointF(),
3043 gfx::PointF(),
3044 gfx::Size(100, 100),
3045 false);
3046 SetLayerPropertiesForTesting(child.get(),
3047 uninvertible_matrix,
3048 identity_matrix,
3049 gfx::PointF(),
3050 gfx::PointF(5.f, 5.f),
3051 gfx::Size(50, 50),
3052 false);
3053
3054 ExecuteCalculateDrawProperties(root.get());
3055
3056 EXPECT_TRUE(child->visible_content_rect().IsEmpty());
3057 EXPECT_TRUE(child->drawable_content_rect().IsEmpty());
3058
3059 // Case 2: a matrix with flattened z, technically uninvertible but still
3060 // drawable and visible. In this case, we must assume that the entire layer
3061 // bounds are visible since there is no way to inverse-project the surface
3062 // bounds to intersect.
3063 uninvertible_matrix.MakeIdentity();
3064 uninvertible_matrix.matrix().set(2, 2, 0.0);
3065 ASSERT_FALSE(uninvertible_matrix.IsInvertible());
3066
3067 SetLayerPropertiesForTesting(child.get(),
3068 uninvertible_matrix,
3069 identity_matrix,
3070 gfx::PointF(),
3071 gfx::PointF(5.f, 5.f),
3072 gfx::Size(50, 50),
3073 false);
3074
3075 ExecuteCalculateDrawProperties(root.get());
3076
3077 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child->visible_content_rect());
3078 EXPECT_RECT_EQ(gfx::Rect(5, 5, 50, 50), child->drawable_content_rect());
3079
3080 // Case 3: a matrix with flattened z, technically uninvertible but still
3081 // drawable, but not visible. In this case, we don't need to conservatively
3082 // assume that the whole layer is visible.
3083 uninvertible_matrix.MakeIdentity();
3084 uninvertible_matrix.Translate(500.0, 0.0);
3085 uninvertible_matrix.matrix().set(2, 2, 0.0);
3086 ASSERT_FALSE(uninvertible_matrix.IsInvertible());
3087
3088 SetLayerPropertiesForTesting(child.get(),
3089 uninvertible_matrix,
3090 identity_matrix,
3091 gfx::PointF(),
3092 gfx::PointF(5.f, 5.f),
3093 gfx::Size(50, 50),
3094 false);
3095
3096 ExecuteCalculateDrawProperties(root.get());
3097
3098 EXPECT_TRUE(child->visible_content_rect().IsEmpty());
3099 EXPECT_RECT_EQ(gfx::Rect(505, 5, 50, 50), child->drawable_content_rect());
3100 }
3101
TEST_F(LayerTreeHostCommonTest,DrawableAndVisibleContentRectsForLayersInClippedRenderSurface)3102 TEST_F(LayerTreeHostCommonTest,
3103 DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) {
3104 scoped_refptr<Layer> root = Layer::Create();
3105 scoped_refptr<Layer> render_surface1 = Layer::Create();
3106 scoped_refptr<LayerWithForcedDrawsContent> child1 =
3107 make_scoped_refptr(new LayerWithForcedDrawsContent());
3108 scoped_refptr<LayerWithForcedDrawsContent> child2 =
3109 make_scoped_refptr(new LayerWithForcedDrawsContent());
3110 scoped_refptr<LayerWithForcedDrawsContent> child3 =
3111 make_scoped_refptr(new LayerWithForcedDrawsContent());
3112 root->AddChild(render_surface1);
3113 render_surface1->AddChild(child1);
3114 render_surface1->AddChild(child2);
3115 render_surface1->AddChild(child3);
3116
3117 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
3118 host->SetRootLayer(root);
3119
3120 gfx::Transform identity_matrix;
3121 SetLayerPropertiesForTesting(root.get(),
3122 identity_matrix,
3123 identity_matrix,
3124 gfx::PointF(),
3125 gfx::PointF(),
3126 gfx::Size(100, 100),
3127 false);
3128 SetLayerPropertiesForTesting(render_surface1.get(),
3129 identity_matrix,
3130 identity_matrix,
3131 gfx::PointF(),
3132 gfx::PointF(),
3133 gfx::Size(3, 4),
3134 false);
3135 SetLayerPropertiesForTesting(child1.get(),
3136 identity_matrix,
3137 identity_matrix,
3138 gfx::PointF(),
3139 gfx::PointF(5.f, 5.f),
3140 gfx::Size(50, 50),
3141 false);
3142 SetLayerPropertiesForTesting(child2.get(),
3143 identity_matrix,
3144 identity_matrix,
3145 gfx::PointF(),
3146 gfx::PointF(75.f, 75.f),
3147 gfx::Size(50, 50),
3148 false);
3149 SetLayerPropertiesForTesting(child3.get(),
3150 identity_matrix,
3151 identity_matrix,
3152 gfx::PointF(),
3153 gfx::PointF(125.f, 125.f),
3154 gfx::Size(50, 50),
3155 false);
3156
3157 root->SetMasksToBounds(true);
3158 render_surface1->SetForceRenderSurface(true);
3159 ExecuteCalculateDrawProperties(root.get());
3160
3161 ASSERT_TRUE(render_surface1->render_surface());
3162
3163 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3164 root->render_surface()->DrawableContentRect());
3165 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
3166
3167 // Layers that do not draw content should have empty visible content rects.
3168 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
3169 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3170 render_surface1->visible_content_rect());
3171
3172 // A clipped surface grows its DrawableContentRect to include all drawable
3173 // regions of the subtree, but also gets clamped by the ancestor's clip.
3174 EXPECT_RECT_EQ(gfx::Rect(5, 5, 95, 95),
3175 render_surface1->render_surface()->DrawableContentRect());
3176
3177 // All layers that draw content into the surface have their visible content
3178 // rect clipped by the surface clip rect.
3179 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
3180 EXPECT_RECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_content_rect());
3181 EXPECT_TRUE(child3->visible_content_rect().IsEmpty());
3182
3183 // But the DrawableContentRects are unclipped.
3184 EXPECT_RECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
3185 EXPECT_RECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
3186 EXPECT_RECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
3187 }
3188
TEST_F(LayerTreeHostCommonTest,DrawableAndVisibleContentRectsForSurfaceHierarchy)3189 TEST_F(LayerTreeHostCommonTest,
3190 DrawableAndVisibleContentRectsForSurfaceHierarchy) {
3191 // Check that clipping does not propagate down surfaces.
3192 scoped_refptr<Layer> root = Layer::Create();
3193 scoped_refptr<Layer> render_surface1 = Layer::Create();
3194 scoped_refptr<Layer> render_surface2 = Layer::Create();
3195 scoped_refptr<LayerWithForcedDrawsContent> child1 =
3196 make_scoped_refptr(new LayerWithForcedDrawsContent());
3197 scoped_refptr<LayerWithForcedDrawsContent> child2 =
3198 make_scoped_refptr(new LayerWithForcedDrawsContent());
3199 scoped_refptr<LayerWithForcedDrawsContent> child3 =
3200 make_scoped_refptr(new LayerWithForcedDrawsContent());
3201 root->AddChild(render_surface1);
3202 render_surface1->AddChild(render_surface2);
3203 render_surface2->AddChild(child1);
3204 render_surface2->AddChild(child2);
3205 render_surface2->AddChild(child3);
3206
3207 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
3208 host->SetRootLayer(root);
3209
3210 gfx::Transform identity_matrix;
3211 SetLayerPropertiesForTesting(root.get(),
3212 identity_matrix,
3213 identity_matrix,
3214 gfx::PointF(),
3215 gfx::PointF(),
3216 gfx::Size(100, 100),
3217 false);
3218 SetLayerPropertiesForTesting(render_surface1.get(),
3219 identity_matrix,
3220 identity_matrix,
3221 gfx::PointF(),
3222 gfx::PointF(),
3223 gfx::Size(3, 4),
3224 false);
3225 SetLayerPropertiesForTesting(render_surface2.get(),
3226 identity_matrix,
3227 identity_matrix,
3228 gfx::PointF(),
3229 gfx::PointF(),
3230 gfx::Size(7, 13),
3231 false);
3232 SetLayerPropertiesForTesting(child1.get(),
3233 identity_matrix,
3234 identity_matrix,
3235 gfx::PointF(),
3236 gfx::PointF(5.f, 5.f),
3237 gfx::Size(50, 50),
3238 false);
3239 SetLayerPropertiesForTesting(child2.get(),
3240 identity_matrix,
3241 identity_matrix,
3242 gfx::PointF(),
3243 gfx::PointF(75.f, 75.f),
3244 gfx::Size(50, 50),
3245 false);
3246 SetLayerPropertiesForTesting(child3.get(),
3247 identity_matrix,
3248 identity_matrix,
3249 gfx::PointF(),
3250 gfx::PointF(125.f, 125.f),
3251 gfx::Size(50, 50),
3252 false);
3253
3254 root->SetMasksToBounds(true);
3255 render_surface1->SetForceRenderSurface(true);
3256 render_surface2->SetForceRenderSurface(true);
3257 ExecuteCalculateDrawProperties(root.get());
3258
3259 ASSERT_TRUE(render_surface1->render_surface());
3260 ASSERT_TRUE(render_surface2->render_surface());
3261
3262 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3263 root->render_surface()->DrawableContentRect());
3264 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
3265
3266 // Layers that do not draw content should have empty visible content rects.
3267 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
3268 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3269 render_surface1->visible_content_rect());
3270 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3271 render_surface2->visible_content_rect());
3272
3273 // A clipped surface grows its DrawableContentRect to include all drawable
3274 // regions of the subtree, but also gets clamped by the ancestor's clip.
3275 EXPECT_RECT_EQ(gfx::Rect(5, 5, 95, 95),
3276 render_surface1->render_surface()->DrawableContentRect());
3277
3278 // render_surface1 lives in the "unclipped universe" of render_surface1, and
3279 // is only implicitly clipped by render_surface1's content rect. So,
3280 // render_surface2 grows to enclose all drawable content of its subtree.
3281 EXPECT_RECT_EQ(gfx::Rect(5, 5, 170, 170),
3282 render_surface2->render_surface()->DrawableContentRect());
3283
3284 // All layers that draw content into render_surface2 think they are unclipped.
3285 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
3286 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child2->visible_content_rect());
3287 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child3->visible_content_rect());
3288
3289 // DrawableContentRects are also unclipped.
3290 EXPECT_RECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
3291 EXPECT_RECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
3292 EXPECT_RECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
3293 }
3294
TEST_F(LayerTreeHostCommonTest,DrawableAndVisibleContentRectsWithTransformOnUnclippedSurface)3295 TEST_F(LayerTreeHostCommonTest,
3296 DrawableAndVisibleContentRectsWithTransformOnUnclippedSurface) {
3297 // Layers that have non-axis aligned bounds (due to transforms) have an
3298 // expanded, axis-aligned DrawableContentRect and visible content rect.
3299
3300 scoped_refptr<Layer> root = Layer::Create();
3301 scoped_refptr<Layer> render_surface1 = Layer::Create();
3302 scoped_refptr<LayerWithForcedDrawsContent> child1 =
3303 make_scoped_refptr(new LayerWithForcedDrawsContent());
3304 root->AddChild(render_surface1);
3305 render_surface1->AddChild(child1);
3306
3307 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
3308 host->SetRootLayer(root);
3309
3310 gfx::Transform identity_matrix;
3311 gfx::Transform child_rotation;
3312 child_rotation.Rotate(45.0);
3313 SetLayerPropertiesForTesting(root.get(),
3314 identity_matrix,
3315 identity_matrix,
3316 gfx::PointF(),
3317 gfx::PointF(),
3318 gfx::Size(100, 100),
3319 false);
3320 SetLayerPropertiesForTesting(render_surface1.get(),
3321 identity_matrix,
3322 identity_matrix,
3323 gfx::PointF(),
3324 gfx::PointF(),
3325 gfx::Size(3, 4),
3326 false);
3327 SetLayerPropertiesForTesting(child1.get(),
3328 child_rotation,
3329 identity_matrix,
3330 gfx::PointF(0.5f, 0.5f),
3331 gfx::PointF(25.f, 25.f),
3332 gfx::Size(50, 50),
3333 false);
3334
3335 render_surface1->SetForceRenderSurface(true);
3336 ExecuteCalculateDrawProperties(root.get());
3337
3338 ASSERT_TRUE(render_surface1->render_surface());
3339
3340 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
3341 root->render_surface()->DrawableContentRect());
3342 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), root->drawable_content_rect());
3343
3344 // Layers that do not draw content should have empty visible content rects.
3345 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
3346 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0),
3347 render_surface1->visible_content_rect());
3348
3349 // The unclipped surface grows its DrawableContentRect to include all drawable
3350 // regions of the subtree.
3351 int diagonal_radius = ceil(sqrt(2.0) * 25.0);
3352 gfx::Rect expected_surface_drawable_content =
3353 gfx::Rect(50 - diagonal_radius,
3354 50 - diagonal_radius,
3355 diagonal_radius * 2,
3356 diagonal_radius * 2);
3357 EXPECT_RECT_EQ(expected_surface_drawable_content,
3358 render_surface1->render_surface()->DrawableContentRect());
3359
3360 // All layers that draw content into the unclipped surface are also unclipped.
3361 EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_content_rect());
3362 EXPECT_RECT_EQ(expected_surface_drawable_content,
3363 child1->drawable_content_rect());
3364 }
3365
TEST_F(LayerTreeHostCommonTest,DrawableAndVisibleContentRectsWithTransformOnClippedSurface)3366 TEST_F(LayerTreeHostCommonTest,
3367 DrawableAndVisibleContentRectsWithTransformOnClippedSurface) {
3368 // Layers that have non-axis aligned bounds (due to transforms) have an
3369 // expanded, axis-aligned DrawableContentRect and visible content rect.
3370
3371 scoped_refptr<Layer> root = Layer::Create();
3372 scoped_refptr<Layer> render_surface1 = Layer::Create();
3373 scoped_refptr<LayerWithForcedDrawsContent> child1 =
3374 make_scoped_refptr(new LayerWithForcedDrawsContent());
3375 root->AddChild(render_surface1);
3376 render_surface1->AddChild(child1);
3377
3378 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
3379 host->SetRootLayer(root);
3380
3381 gfx::Transform identity_matrix;
3382 gfx::Transform child_rotation;
3383 child_rotation.Rotate(45.0);
3384 SetLayerPropertiesForTesting(root.get(),
3385 identity_matrix,
3386 identity_matrix,
3387 gfx::PointF(),
3388 gfx::PointF(),
3389 gfx::Size(50, 50),
3390 false);
3391 SetLayerPropertiesForTesting(render_surface1.get(),
3392 identity_matrix,
3393 identity_matrix,
3394 gfx::PointF(),
3395 gfx::PointF(),
3396 gfx::Size(3, 4),
3397 false);
3398 SetLayerPropertiesForTesting(child1.get(),
3399 child_rotation,
3400 identity_matrix,
3401 gfx::PointF(0.5f, 0.5f),
3402 gfx::PointF(25.f, 25.f),
3403 gfx::Size(50, 50),
3404 false);
3405
3406 root->SetMasksToBounds(true);
3407 render_surface1->SetForceRenderSurface(true);
3408 ExecuteCalculateDrawProperties(root.get());
3409
3410 ASSERT_TRUE(render_surface1->render_surface());
3411
3412 // The clipped surface clamps the DrawableContentRect that encloses the
3413 // rotated layer.
3414 int diagonal_radius = ceil(sqrt(2.0) * 25.0);
3415 gfx::Rect unclipped_surface_content = gfx::Rect(50 - diagonal_radius,
3416 50 - diagonal_radius,
3417 diagonal_radius * 2,
3418 diagonal_radius * 2);
3419 gfx::Rect expected_surface_drawable_content =
3420 gfx::IntersectRects(unclipped_surface_content, gfx::Rect(0, 0, 50, 50));
3421 EXPECT_RECT_EQ(expected_surface_drawable_content,
3422 render_surface1->render_surface()->DrawableContentRect());
3423
3424 // On the clipped surface, only a quarter of the child1 is visible, but when
3425 // rotating it back to child1's content space, the actual enclosing rect ends
3426 // up covering the full left half of child1.
3427 //
3428 // Given the floating point math, this number is a little bit fuzzy.
3429 EXPECT_RECT_EQ(gfx::Rect(0, 0, 26, 50), child1->visible_content_rect());
3430
3431 // The child's DrawableContentRect is unclipped.
3432 EXPECT_RECT_EQ(unclipped_surface_content, child1->drawable_content_rect());
3433 }
3434
TEST_F(LayerTreeHostCommonTest,DrawableAndVisibleContentRectsInHighDPI)3435 TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) {
3436 MockContentLayerClient client;
3437
3438 scoped_refptr<Layer> root = Layer::Create();
3439 scoped_refptr<ContentLayer> render_surface1 =
3440 CreateDrawableContentLayer(&client);
3441 scoped_refptr<ContentLayer> render_surface2 =
3442 CreateDrawableContentLayer(&client);
3443 scoped_refptr<ContentLayer> child1 = CreateDrawableContentLayer(&client);
3444 scoped_refptr<ContentLayer> child2 = CreateDrawableContentLayer(&client);
3445 scoped_refptr<ContentLayer> child3 = CreateDrawableContentLayer(&client);
3446 root->AddChild(render_surface1);
3447 render_surface1->AddChild(render_surface2);
3448 render_surface2->AddChild(child1);
3449 render_surface2->AddChild(child2);
3450 render_surface2->AddChild(child3);
3451
3452 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
3453 host->SetRootLayer(root);
3454
3455 gfx::Transform identity_matrix;
3456 SetLayerPropertiesForTesting(root.get(),
3457 identity_matrix,
3458 identity_matrix,
3459 gfx::PointF(),
3460 gfx::PointF(),
3461 gfx::Size(100, 100),
3462 false);
3463 SetLayerPropertiesForTesting(render_surface1.get(),
3464 identity_matrix,
3465 identity_matrix,
3466 gfx::PointF(),
3467 gfx::PointF(5.f, 5.f),
3468 gfx::Size(3, 4),
3469 false);
3470 SetLayerPropertiesForTesting(render_surface2.get(),
3471 identity_matrix,
3472 identity_matrix,
3473 gfx::PointF(),
3474 gfx::PointF(5.f, 5.f),
3475 gfx::Size(7, 13),
3476 false);
3477 SetLayerPropertiesForTesting(child1.get(),
3478 identity_matrix,
3479 identity_matrix,
3480 gfx::PointF(),
3481 gfx::PointF(5.f, 5.f),
3482 gfx::Size(50, 50),
3483 false);
3484 SetLayerPropertiesForTesting(child2.get(),
3485 identity_matrix,
3486 identity_matrix,
3487 gfx::PointF(),
3488 gfx::PointF(75.f, 75.f),
3489 gfx::Size(50, 50),
3490 false);
3491 SetLayerPropertiesForTesting(child3.get(),
3492 identity_matrix,
3493 identity_matrix,
3494 gfx::PointF(),
3495 gfx::PointF(125.f, 125.f),
3496 gfx::Size(50, 50),
3497 false);
3498
3499 float device_scale_factor = 2.f;
3500
3501 root->SetMasksToBounds(true);
3502 render_surface1->SetForceRenderSurface(true);
3503 render_surface2->SetForceRenderSurface(true);
3504 ExecuteCalculateDrawProperties(root.get(), device_scale_factor);
3505
3506 ASSERT_TRUE(render_surface1->render_surface());
3507 ASSERT_TRUE(render_surface2->render_surface());
3508
3509 // drawable_content_rects for all layers and surfaces are scaled by
3510 // device_scale_factor.
3511 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200),
3512 root->render_surface()->DrawableContentRect());
3513 EXPECT_RECT_EQ(gfx::Rect(0, 0, 200, 200), root->drawable_content_rect());
3514 EXPECT_RECT_EQ(gfx::Rect(10, 10, 190, 190),
3515 render_surface1->render_surface()->DrawableContentRect());
3516
3517 // render_surface2 lives in the "unclipped universe" of render_surface1, and
3518 // is only implicitly clipped by render_surface1.
3519 EXPECT_RECT_EQ(gfx::Rect(10, 10, 350, 350),
3520 render_surface2->render_surface()->DrawableContentRect());
3521
3522 EXPECT_RECT_EQ(gfx::Rect(10, 10, 100, 100), child1->drawable_content_rect());
3523 EXPECT_RECT_EQ(gfx::Rect(150, 150, 100, 100),
3524 child2->drawable_content_rect());
3525 EXPECT_RECT_EQ(gfx::Rect(250, 250, 100, 100),
3526 child3->drawable_content_rect());
3527
3528 // The root layer does not actually draw content of its own.
3529 EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_content_rect());
3530
3531 // All layer visible content rects are expressed in content space of each
3532 // layer, so they are also scaled by the device_scale_factor.
3533 EXPECT_RECT_EQ(gfx::Rect(0, 0, 6, 8),
3534 render_surface1->visible_content_rect());
3535 EXPECT_RECT_EQ(gfx::Rect(0, 0, 14, 26),
3536 render_surface2->visible_content_rect());
3537 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), child1->visible_content_rect());
3538 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), child2->visible_content_rect());
3539 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), child3->visible_content_rect());
3540 }
3541
TEST_F(LayerTreeHostCommonTest,BackFaceCullingWithoutPreserves3d)3542 TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) {
3543 // Verify the behavior of back-face culling when there are no preserve-3d
3544 // layers. Note that 3d transforms still apply in this case, but they are
3545 // "flattened" to each parent layer according to current W3C spec.
3546
3547 const gfx::Transform identity_matrix;
3548 scoped_refptr<Layer> parent = Layer::Create();
3549 scoped_refptr<LayerWithForcedDrawsContent> front_facing_child =
3550 make_scoped_refptr(new LayerWithForcedDrawsContent());
3551 scoped_refptr<LayerWithForcedDrawsContent> back_facing_child =
3552 make_scoped_refptr(new LayerWithForcedDrawsContent());
3553 scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface =
3554 make_scoped_refptr(new LayerWithForcedDrawsContent());
3555 scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface =
3556 make_scoped_refptr(new LayerWithForcedDrawsContent());
3557 scoped_refptr<LayerWithForcedDrawsContent>
3558 front_facing_child_of_front_facing_surface =
3559 make_scoped_refptr(new LayerWithForcedDrawsContent());
3560 scoped_refptr<LayerWithForcedDrawsContent>
3561 back_facing_child_of_front_facing_surface =
3562 make_scoped_refptr(new LayerWithForcedDrawsContent());
3563 scoped_refptr<LayerWithForcedDrawsContent>
3564 front_facing_child_of_back_facing_surface =
3565 make_scoped_refptr(new LayerWithForcedDrawsContent());
3566 scoped_refptr<LayerWithForcedDrawsContent>
3567 back_facing_child_of_back_facing_surface =
3568 make_scoped_refptr(new LayerWithForcedDrawsContent());
3569
3570 parent->AddChild(front_facing_child);
3571 parent->AddChild(back_facing_child);
3572 parent->AddChild(front_facing_surface);
3573 parent->AddChild(back_facing_surface);
3574 front_facing_surface->AddChild(front_facing_child_of_front_facing_surface);
3575 front_facing_surface->AddChild(back_facing_child_of_front_facing_surface);
3576 back_facing_surface->AddChild(front_facing_child_of_back_facing_surface);
3577 back_facing_surface->AddChild(back_facing_child_of_back_facing_surface);
3578
3579 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
3580 host->SetRootLayer(parent);
3581
3582 // Nothing is double-sided
3583 front_facing_child->SetDoubleSided(false);
3584 back_facing_child->SetDoubleSided(false);
3585 front_facing_surface->SetDoubleSided(false);
3586 back_facing_surface->SetDoubleSided(false);
3587 front_facing_child_of_front_facing_surface->SetDoubleSided(false);
3588 back_facing_child_of_front_facing_surface->SetDoubleSided(false);
3589 front_facing_child_of_back_facing_surface->SetDoubleSided(false);
3590 back_facing_child_of_back_facing_surface->SetDoubleSided(false);
3591
3592 gfx::Transform backface_matrix;
3593 backface_matrix.Translate(50.0, 50.0);
3594 backface_matrix.RotateAboutYAxis(180.0);
3595 backface_matrix.Translate(-50.0, -50.0);
3596
3597 // Having a descendant and opacity will force these to have render surfaces.
3598 front_facing_surface->SetOpacity(0.5f);
3599 back_facing_surface->SetOpacity(0.5f);
3600
3601 // Nothing preserves 3d. According to current W3C CSS gfx::Transforms spec,
3602 // these layers should blindly use their own local transforms to determine
3603 // back-face culling.
3604 SetLayerPropertiesForTesting(parent.get(),
3605 identity_matrix,
3606 identity_matrix,
3607 gfx::PointF(),
3608 gfx::PointF(),
3609 gfx::Size(100, 100),
3610 false);
3611 SetLayerPropertiesForTesting(front_facing_child.get(),
3612 identity_matrix,
3613 identity_matrix,
3614 gfx::PointF(),
3615 gfx::PointF(),
3616 gfx::Size(100, 100),
3617 false);
3618 SetLayerPropertiesForTesting(back_facing_child.get(),
3619 backface_matrix,
3620 identity_matrix,
3621 gfx::PointF(),
3622 gfx::PointF(),
3623 gfx::Size(100, 100),
3624 false);
3625 SetLayerPropertiesForTesting(front_facing_surface.get(),
3626 identity_matrix,
3627 identity_matrix,
3628 gfx::PointF(),
3629 gfx::PointF(),
3630 gfx::Size(100, 100),
3631 false);
3632 SetLayerPropertiesForTesting(back_facing_surface.get(),
3633 backface_matrix,
3634 identity_matrix,
3635 gfx::PointF(),
3636 gfx::PointF(),
3637 gfx::Size(100, 100),
3638 false);
3639 SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface.get(),
3640 identity_matrix,
3641 identity_matrix,
3642 gfx::PointF(),
3643 gfx::PointF(),
3644 gfx::Size(100, 100),
3645 false);
3646 SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface.get(),
3647 backface_matrix,
3648 identity_matrix,
3649 gfx::PointF(),
3650 gfx::PointF(),
3651 gfx::Size(100, 100),
3652 false);
3653 SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface.get(),
3654 identity_matrix,
3655 identity_matrix,
3656 gfx::PointF(),
3657 gfx::PointF(),
3658 gfx::Size(100, 100),
3659 false);
3660 SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface.get(),
3661 backface_matrix,
3662 identity_matrix,
3663 gfx::PointF(),
3664 gfx::PointF(),
3665 gfx::Size(100, 100),
3666 false);
3667
3668 RenderSurfaceLayerList render_surface_layer_list;
3669 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
3670 parent.get(), parent->bounds(), &render_surface_layer_list);
3671 inputs.can_adjust_raster_scales = true;
3672 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
3673
3674 // Verify which render surfaces were created.
3675 EXPECT_FALSE(front_facing_child->render_surface());
3676 EXPECT_FALSE(back_facing_child->render_surface());
3677 EXPECT_TRUE(front_facing_surface->render_surface());
3678 EXPECT_TRUE(back_facing_surface->render_surface());
3679 EXPECT_FALSE(front_facing_child_of_front_facing_surface->render_surface());
3680 EXPECT_FALSE(back_facing_child_of_front_facing_surface->render_surface());
3681 EXPECT_FALSE(front_facing_child_of_back_facing_surface->render_surface());
3682 EXPECT_FALSE(back_facing_child_of_back_facing_surface->render_surface());
3683
3684 // Verify the render_surface_layer_list.
3685 ASSERT_EQ(3u, render_surface_layer_list.size());
3686 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
3687 EXPECT_EQ(front_facing_surface->id(), render_surface_layer_list.at(1)->id());
3688 // Even though the back facing surface LAYER gets culled, the other
3689 // descendants should still be added, so the SURFACE should not be culled.
3690 EXPECT_EQ(back_facing_surface->id(), render_surface_layer_list.at(2)->id());
3691
3692 // Verify root surface's layer list.
3693 ASSERT_EQ(
3694 3u,
3695 render_surface_layer_list.at(0)->render_surface()->layer_list().size());
3696 EXPECT_EQ(front_facing_child->id(),
3697 render_surface_layer_list.at(0)
3698 ->render_surface()->layer_list().at(0)->id());
3699 EXPECT_EQ(front_facing_surface->id(),
3700 render_surface_layer_list.at(0)
3701 ->render_surface()->layer_list().at(1)->id());
3702 EXPECT_EQ(back_facing_surface->id(),
3703 render_surface_layer_list.at(0)
3704 ->render_surface()->layer_list().at(2)->id());
3705
3706 // Verify front_facing_surface's layer list.
3707 ASSERT_EQ(
3708 2u,
3709 render_surface_layer_list.at(1)->render_surface()->layer_list().size());
3710 EXPECT_EQ(front_facing_surface->id(),
3711 render_surface_layer_list.at(1)
3712 ->render_surface()->layer_list().at(0)->id());
3713 EXPECT_EQ(front_facing_child_of_front_facing_surface->id(),
3714 render_surface_layer_list.at(1)
3715 ->render_surface()->layer_list().at(1)->id());
3716
3717 // Verify back_facing_surface's layer list; its own layer should be culled
3718 // from the surface list.
3719 ASSERT_EQ(
3720 1u,
3721 render_surface_layer_list.at(2)->render_surface()->layer_list().size());
3722 EXPECT_EQ(front_facing_child_of_back_facing_surface->id(),
3723 render_surface_layer_list.at(2)
3724 ->render_surface()->layer_list().at(0)->id());
3725 }
3726
TEST_F(LayerTreeHostCommonTest,BackFaceCullingWithPreserves3d)3727 TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) {
3728 // Verify the behavior of back-face culling when preserves-3d transform style
3729 // is used.
3730
3731 const gfx::Transform identity_matrix;
3732 scoped_refptr<Layer> parent = Layer::Create();
3733 scoped_refptr<LayerWithForcedDrawsContent> front_facing_child =
3734 make_scoped_refptr(new LayerWithForcedDrawsContent());
3735 scoped_refptr<LayerWithForcedDrawsContent> back_facing_child =
3736 make_scoped_refptr(new LayerWithForcedDrawsContent());
3737 scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface =
3738 make_scoped_refptr(new LayerWithForcedDrawsContent());
3739 scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface =
3740 make_scoped_refptr(new LayerWithForcedDrawsContent());
3741 scoped_refptr<LayerWithForcedDrawsContent>
3742 front_facing_child_of_front_facing_surface =
3743 make_scoped_refptr(new LayerWithForcedDrawsContent());
3744 scoped_refptr<LayerWithForcedDrawsContent>
3745 back_facing_child_of_front_facing_surface =
3746 make_scoped_refptr(new LayerWithForcedDrawsContent());
3747 scoped_refptr<LayerWithForcedDrawsContent>
3748 front_facing_child_of_back_facing_surface =
3749 make_scoped_refptr(new LayerWithForcedDrawsContent());
3750 scoped_refptr<LayerWithForcedDrawsContent>
3751 back_facing_child_of_back_facing_surface =
3752 make_scoped_refptr(new LayerWithForcedDrawsContent());
3753 scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer1 =
3754 make_scoped_refptr(new LayerWithForcedDrawsContent());
3755 scoped_refptr<LayerWithForcedDrawsContent> dummy_replica_layer2 =
3756 make_scoped_refptr(new LayerWithForcedDrawsContent());
3757
3758 parent->AddChild(front_facing_child);
3759 parent->AddChild(back_facing_child);
3760 parent->AddChild(front_facing_surface);
3761 parent->AddChild(back_facing_surface);
3762 front_facing_surface->AddChild(front_facing_child_of_front_facing_surface);
3763 front_facing_surface->AddChild(back_facing_child_of_front_facing_surface);
3764 back_facing_surface->AddChild(front_facing_child_of_back_facing_surface);
3765 back_facing_surface->AddChild(back_facing_child_of_back_facing_surface);
3766
3767 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
3768 host->SetRootLayer(parent);
3769
3770 // Nothing is double-sided
3771 front_facing_child->SetDoubleSided(false);
3772 back_facing_child->SetDoubleSided(false);
3773 front_facing_surface->SetDoubleSided(false);
3774 back_facing_surface->SetDoubleSided(false);
3775 front_facing_child_of_front_facing_surface->SetDoubleSided(false);
3776 back_facing_child_of_front_facing_surface->SetDoubleSided(false);
3777 front_facing_child_of_back_facing_surface->SetDoubleSided(false);
3778 back_facing_child_of_back_facing_surface->SetDoubleSided(false);
3779
3780 gfx::Transform backface_matrix;
3781 backface_matrix.Translate(50.0, 50.0);
3782 backface_matrix.RotateAboutYAxis(180.0);
3783 backface_matrix.Translate(-50.0, -50.0);
3784
3785 // Opacity will not force creation of render surfaces in this case because of
3786 // the preserve-3d transform style. Instead, an example of when a surface
3787 // would be created with preserve-3d is when there is a replica layer.
3788 front_facing_surface->SetReplicaLayer(dummy_replica_layer1.get());
3789 back_facing_surface->SetReplicaLayer(dummy_replica_layer2.get());
3790
3791 // Each surface creates its own new 3d rendering context (as defined by W3C
3792 // spec). According to current W3C CSS gfx::Transforms spec, layers in a 3d
3793 // rendering context should use the transform with respect to that context.
3794 // This 3d rendering context occurs when (a) parent's transform style is flat
3795 // and (b) the layer's transform style is preserve-3d.
3796 SetLayerPropertiesForTesting(parent.get(),
3797 identity_matrix,
3798 identity_matrix,
3799 gfx::PointF(),
3800 gfx::PointF(),
3801 gfx::Size(100, 100),
3802 false); // parent transform style is flat.
3803 SetLayerPropertiesForTesting(front_facing_child.get(),
3804 identity_matrix,
3805 identity_matrix,
3806 gfx::PointF(),
3807 gfx::PointF(),
3808 gfx::Size(100, 100),
3809 false);
3810 SetLayerPropertiesForTesting(back_facing_child.get(),
3811 backface_matrix,
3812 identity_matrix,
3813 gfx::PointF(),
3814 gfx::PointF(),
3815 gfx::Size(100, 100),
3816 false);
3817 SetLayerPropertiesForTesting(
3818 front_facing_surface.get(),
3819 identity_matrix,
3820 identity_matrix,
3821 gfx::PointF(),
3822 gfx::PointF(),
3823 gfx::Size(100, 100),
3824 true); // surface transform style is preserve-3d.
3825 SetLayerPropertiesForTesting(
3826 back_facing_surface.get(),
3827 backface_matrix,
3828 identity_matrix,
3829 gfx::PointF(),
3830 gfx::PointF(),
3831 gfx::Size(100, 100),
3832 true); // surface transform style is preserve-3d.
3833 SetLayerPropertiesForTesting(front_facing_child_of_front_facing_surface.get(),
3834 identity_matrix,
3835 identity_matrix,
3836 gfx::PointF(),
3837 gfx::PointF(),
3838 gfx::Size(100, 100),
3839 false);
3840 SetLayerPropertiesForTesting(back_facing_child_of_front_facing_surface.get(),
3841 backface_matrix,
3842 identity_matrix,
3843 gfx::PointF(),
3844 gfx::PointF(),
3845 gfx::Size(100, 100),
3846 false);
3847 SetLayerPropertiesForTesting(front_facing_child_of_back_facing_surface.get(),
3848 identity_matrix,
3849 identity_matrix,
3850 gfx::PointF(),
3851 gfx::PointF(),
3852 gfx::Size(100, 100),
3853 false);
3854 SetLayerPropertiesForTesting(back_facing_child_of_back_facing_surface.get(),
3855 backface_matrix,
3856 identity_matrix,
3857 gfx::PointF(),
3858 gfx::PointF(),
3859 gfx::Size(100, 100),
3860 false);
3861
3862 RenderSurfaceLayerList render_surface_layer_list;
3863 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
3864 parent.get(), parent->bounds(), &render_surface_layer_list);
3865 inputs.can_adjust_raster_scales = true;
3866 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
3867
3868 // Verify which render surfaces were created.
3869 EXPECT_FALSE(front_facing_child->render_surface());
3870 EXPECT_FALSE(back_facing_child->render_surface());
3871 EXPECT_TRUE(front_facing_surface->render_surface());
3872 EXPECT_FALSE(back_facing_surface->render_surface());
3873 EXPECT_FALSE(front_facing_child_of_front_facing_surface->render_surface());
3874 EXPECT_FALSE(back_facing_child_of_front_facing_surface->render_surface());
3875 EXPECT_FALSE(front_facing_child_of_back_facing_surface->render_surface());
3876 EXPECT_FALSE(back_facing_child_of_back_facing_surface->render_surface());
3877
3878 // Verify the render_surface_layer_list. The back-facing surface should be
3879 // culled.
3880 ASSERT_EQ(2u, render_surface_layer_list.size());
3881 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
3882 EXPECT_EQ(front_facing_surface->id(), render_surface_layer_list.at(1)->id());
3883
3884 // Verify root surface's layer list.
3885 ASSERT_EQ(
3886 2u,
3887 render_surface_layer_list.at(0)->render_surface()->layer_list().size());
3888 EXPECT_EQ(front_facing_child->id(),
3889 render_surface_layer_list.at(0)
3890 ->render_surface()->layer_list().at(0)->id());
3891 EXPECT_EQ(front_facing_surface->id(),
3892 render_surface_layer_list.at(0)
3893 ->render_surface()->layer_list().at(1)->id());
3894
3895 // Verify front_facing_surface's layer list.
3896 ASSERT_EQ(
3897 2u,
3898 render_surface_layer_list.at(1)->render_surface()->layer_list().size());
3899 EXPECT_EQ(front_facing_surface->id(),
3900 render_surface_layer_list.at(1)
3901 ->render_surface()->layer_list().at(0)->id());
3902 EXPECT_EQ(front_facing_child_of_front_facing_surface->id(),
3903 render_surface_layer_list.at(1)
3904 ->render_surface()->layer_list().at(1)->id());
3905 }
3906
TEST_F(LayerTreeHostCommonTest,BackFaceCullingWithAnimatingTransforms)3907 TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithAnimatingTransforms) {
3908 // Verify that layers are appropriately culled when their back face is showing
3909 // and they are not double sided, while animations are going on.
3910 //
3911 // Layers that are animating do not get culled on the main thread, as their
3912 // transforms should be treated as "unknown" so we can not be sure that their
3913 // back face is really showing.
3914 const gfx::Transform identity_matrix;
3915 scoped_refptr<Layer> parent = Layer::Create();
3916 scoped_refptr<LayerWithForcedDrawsContent> child =
3917 make_scoped_refptr(new LayerWithForcedDrawsContent());
3918 scoped_refptr<LayerWithForcedDrawsContent> animating_surface =
3919 make_scoped_refptr(new LayerWithForcedDrawsContent());
3920 scoped_refptr<LayerWithForcedDrawsContent> child_of_animating_surface =
3921 make_scoped_refptr(new LayerWithForcedDrawsContent());
3922 scoped_refptr<LayerWithForcedDrawsContent> animating_child =
3923 make_scoped_refptr(new LayerWithForcedDrawsContent());
3924 scoped_refptr<LayerWithForcedDrawsContent> child2 =
3925 make_scoped_refptr(new LayerWithForcedDrawsContent());
3926
3927 parent->AddChild(child);
3928 parent->AddChild(animating_surface);
3929 animating_surface->AddChild(child_of_animating_surface);
3930 parent->AddChild(animating_child);
3931 parent->AddChild(child2);
3932
3933 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
3934 host->SetRootLayer(parent);
3935
3936 // Nothing is double-sided
3937 child->SetDoubleSided(false);
3938 child2->SetDoubleSided(false);
3939 animating_surface->SetDoubleSided(false);
3940 child_of_animating_surface->SetDoubleSided(false);
3941 animating_child->SetDoubleSided(false);
3942
3943 gfx::Transform backface_matrix;
3944 backface_matrix.Translate(50.0, 50.0);
3945 backface_matrix.RotateAboutYAxis(180.0);
3946 backface_matrix.Translate(-50.0, -50.0);
3947
3948 // Make our render surface.
3949 animating_surface->SetForceRenderSurface(true);
3950
3951 // Animate the transform on the render surface.
3952 AddAnimatedTransformToController(
3953 animating_surface->layer_animation_controller(), 10.0, 30, 0);
3954 // This is just an animating layer, not a surface.
3955 AddAnimatedTransformToController(
3956 animating_child->layer_animation_controller(), 10.0, 30, 0);
3957
3958 SetLayerPropertiesForTesting(parent.get(),
3959 identity_matrix,
3960 identity_matrix,
3961 gfx::PointF(),
3962 gfx::PointF(),
3963 gfx::Size(100, 100),
3964 false);
3965 SetLayerPropertiesForTesting(child.get(),
3966 backface_matrix,
3967 identity_matrix,
3968 gfx::PointF(),
3969 gfx::PointF(),
3970 gfx::Size(100, 100),
3971 false);
3972 SetLayerPropertiesForTesting(animating_surface.get(),
3973 backface_matrix,
3974 identity_matrix,
3975 gfx::PointF(),
3976 gfx::PointF(),
3977 gfx::Size(100, 100),
3978 false);
3979 SetLayerPropertiesForTesting(child_of_animating_surface.get(),
3980 backface_matrix,
3981 identity_matrix,
3982 gfx::PointF(),
3983 gfx::PointF(),
3984 gfx::Size(100, 100),
3985 false);
3986 SetLayerPropertiesForTesting(animating_child.get(),
3987 backface_matrix,
3988 identity_matrix,
3989 gfx::PointF(),
3990 gfx::PointF(),
3991 gfx::Size(100, 100),
3992 false);
3993 SetLayerPropertiesForTesting(child2.get(),
3994 identity_matrix,
3995 identity_matrix,
3996 gfx::PointF(),
3997 gfx::PointF(),
3998 gfx::Size(100, 100),
3999 false);
4000
4001 RenderSurfaceLayerList render_surface_layer_list;
4002 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
4003 parent.get(), parent->bounds(), &render_surface_layer_list);
4004 inputs.can_adjust_raster_scales = true;
4005 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4006
4007 EXPECT_FALSE(child->render_surface());
4008 EXPECT_TRUE(animating_surface->render_surface());
4009 EXPECT_FALSE(child_of_animating_surface->render_surface());
4010 EXPECT_FALSE(animating_child->render_surface());
4011 EXPECT_FALSE(child2->render_surface());
4012
4013 // Verify that the animating_child and child_of_animating_surface were not
4014 // culled, but that child was.
4015 ASSERT_EQ(2u, render_surface_layer_list.size());
4016 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
4017 EXPECT_EQ(animating_surface->id(), render_surface_layer_list.at(1)->id());
4018
4019 // The non-animating child be culled from the layer list for the parent render
4020 // surface.
4021 ASSERT_EQ(
4022 3u,
4023 render_surface_layer_list.at(0)->render_surface()->layer_list().size());
4024 EXPECT_EQ(animating_surface->id(),
4025 render_surface_layer_list.at(0)
4026 ->render_surface()->layer_list().at(0)->id());
4027 EXPECT_EQ(animating_child->id(),
4028 render_surface_layer_list.at(0)
4029 ->render_surface()->layer_list().at(1)->id());
4030 EXPECT_EQ(child2->id(),
4031 render_surface_layer_list.at(0)
4032 ->render_surface()->layer_list().at(2)->id());
4033
4034 ASSERT_EQ(
4035 2u,
4036 render_surface_layer_list.at(1)->render_surface()->layer_list().size());
4037 EXPECT_EQ(animating_surface->id(),
4038 render_surface_layer_list.at(1)
4039 ->render_surface()->layer_list().at(0)->id());
4040 EXPECT_EQ(child_of_animating_surface->id(),
4041 render_surface_layer_list.at(1)
4042 ->render_surface()->layer_list().at(1)->id());
4043
4044 EXPECT_FALSE(child2->visible_content_rect().IsEmpty());
4045
4046 // The animating layers should have a visible content rect that represents the
4047 // area of the front face that is within the viewport.
4048 EXPECT_EQ(animating_child->visible_content_rect(),
4049 gfx::Rect(animating_child->content_bounds()));
4050 EXPECT_EQ(animating_surface->visible_content_rect(),
4051 gfx::Rect(animating_surface->content_bounds()));
4052 // And layers in the subtree of the animating layer should have valid visible
4053 // content rects also.
4054 EXPECT_EQ(child_of_animating_surface->visible_content_rect(),
4055 gfx::Rect(child_of_animating_surface->content_bounds()));
4056 }
4057
TEST_F(LayerTreeHostCommonTest,BackFaceCullingWithPreserves3dForFlatteningSurface)4058 TEST_F(LayerTreeHostCommonTest,
4059 BackFaceCullingWithPreserves3dForFlatteningSurface) {
4060 // Verify the behavior of back-face culling for a render surface that is
4061 // created when it flattens its subtree, and its parent has preserves-3d.
4062
4063 const gfx::Transform identity_matrix;
4064 scoped_refptr<Layer> parent = Layer::Create();
4065 scoped_refptr<LayerWithForcedDrawsContent> front_facing_surface =
4066 make_scoped_refptr(new LayerWithForcedDrawsContent());
4067 scoped_refptr<LayerWithForcedDrawsContent> back_facing_surface =
4068 make_scoped_refptr(new LayerWithForcedDrawsContent());
4069 scoped_refptr<LayerWithForcedDrawsContent> child1 =
4070 make_scoped_refptr(new LayerWithForcedDrawsContent());
4071 scoped_refptr<LayerWithForcedDrawsContent> child2 =
4072 make_scoped_refptr(new LayerWithForcedDrawsContent());
4073
4074 parent->AddChild(front_facing_surface);
4075 parent->AddChild(back_facing_surface);
4076 front_facing_surface->AddChild(child1);
4077 back_facing_surface->AddChild(child2);
4078
4079 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
4080 host->SetRootLayer(parent);
4081
4082 // RenderSurfaces are not double-sided
4083 front_facing_surface->SetDoubleSided(false);
4084 back_facing_surface->SetDoubleSided(false);
4085
4086 gfx::Transform backface_matrix;
4087 backface_matrix.Translate(50.0, 50.0);
4088 backface_matrix.RotateAboutYAxis(180.0);
4089 backface_matrix.Translate(-50.0, -50.0);
4090
4091 SetLayerPropertiesForTesting(parent.get(),
4092 identity_matrix,
4093 identity_matrix,
4094 gfx::PointF(),
4095 gfx::PointF(),
4096 gfx::Size(100, 100),
4097 true); // parent transform style is preserve3d.
4098 SetLayerPropertiesForTesting(front_facing_surface.get(),
4099 identity_matrix,
4100 identity_matrix,
4101 gfx::PointF(),
4102 gfx::PointF(),
4103 gfx::Size(100, 100),
4104 false); // surface transform style is flat.
4105 SetLayerPropertiesForTesting(back_facing_surface.get(),
4106 backface_matrix,
4107 identity_matrix,
4108 gfx::PointF(),
4109 gfx::PointF(),
4110 gfx::Size(100, 100),
4111 false); // surface transform style is flat.
4112 SetLayerPropertiesForTesting(child1.get(),
4113 identity_matrix,
4114 identity_matrix,
4115 gfx::PointF(),
4116 gfx::PointF(),
4117 gfx::Size(100, 100),
4118 false);
4119 SetLayerPropertiesForTesting(child2.get(),
4120 identity_matrix,
4121 identity_matrix,
4122 gfx::PointF(),
4123 gfx::PointF(),
4124 gfx::Size(100, 100),
4125 false);
4126
4127 RenderSurfaceLayerList render_surface_layer_list;
4128 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
4129 parent.get(), parent->bounds(), &render_surface_layer_list);
4130 inputs.can_adjust_raster_scales = true;
4131 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4132
4133 // Verify which render surfaces were created.
4134 EXPECT_TRUE(front_facing_surface->render_surface());
4135 EXPECT_FALSE(
4136 back_facing_surface->render_surface()); // because it should be culled
4137 EXPECT_FALSE(child1->render_surface());
4138 EXPECT_FALSE(child2->render_surface());
4139
4140 // Verify the render_surface_layer_list. The back-facing surface should be
4141 // culled.
4142 ASSERT_EQ(2u, render_surface_layer_list.size());
4143 EXPECT_EQ(parent->id(), render_surface_layer_list.at(0)->id());
4144 EXPECT_EQ(front_facing_surface->id(), render_surface_layer_list.at(1)->id());
4145
4146 // Verify root surface's layer list.
4147 ASSERT_EQ(
4148 1u,
4149 render_surface_layer_list.at(0)->render_surface()->layer_list().size());
4150 EXPECT_EQ(front_facing_surface->id(),
4151 render_surface_layer_list.at(0)
4152 ->render_surface()->layer_list().at(0)->id());
4153
4154 // Verify front_facing_surface's layer list.
4155 ASSERT_EQ(
4156 2u,
4157 render_surface_layer_list.at(1)->render_surface()->layer_list().size());
4158 EXPECT_EQ(front_facing_surface->id(),
4159 render_surface_layer_list.at(1)
4160 ->render_surface()->layer_list().at(0)->id());
4161 EXPECT_EQ(child1->id(),
4162 render_surface_layer_list.at(1)
4163 ->render_surface()->layer_list().at(1)->id());
4164 }
4165
4166
TEST_F(LayerTreeHostCommonTest,HitTestingForEmptyLayerList)4167 TEST_F(LayerTreeHostCommonTest, HitTestingForEmptyLayerList) {
4168 // Hit testing on an empty render_surface_layer_list should return a null
4169 // pointer.
4170 LayerImplList render_surface_layer_list;
4171
4172 gfx::Point test_point(0, 0);
4173 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4174 test_point, render_surface_layer_list);
4175 EXPECT_FALSE(result_layer);
4176
4177 test_point = gfx::Point(10, 20);
4178 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4179 test_point, render_surface_layer_list);
4180 EXPECT_FALSE(result_layer);
4181 }
4182
TEST_F(LayerTreeHostCommonTest,HitTestingForSingleLayer)4183 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleLayer) {
4184 FakeImplProxy proxy;
4185 FakeLayerTreeHostImpl host_impl(&proxy);
4186 scoped_ptr<LayerImpl> root =
4187 LayerImpl::Create(host_impl.active_tree(), 12345);
4188
4189 gfx::Transform identity_matrix;
4190 gfx::PointF anchor;
4191 gfx::PointF position;
4192 gfx::Size bounds(100, 100);
4193 SetLayerPropertiesForTesting(root.get(),
4194 identity_matrix,
4195 identity_matrix,
4196 anchor,
4197 position,
4198 bounds,
4199 false);
4200 root->SetDrawsContent(true);
4201
4202 LayerImplList render_surface_layer_list;
4203 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4204 root.get(), root->bounds(), &render_surface_layer_list);
4205 inputs.can_adjust_raster_scales = true;
4206 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4207
4208 // Sanity check the scenario we just created.
4209 ASSERT_EQ(1u, render_surface_layer_list.size());
4210 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4211
4212 // Hit testing for a point outside the layer should return a null pointer.
4213 gfx::Point test_point(101, 101);
4214 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4215 test_point, render_surface_layer_list);
4216 EXPECT_FALSE(result_layer);
4217
4218 test_point = gfx::Point(-1, -1);
4219 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4220 test_point, render_surface_layer_list);
4221 EXPECT_FALSE(result_layer);
4222
4223 // Hit testing for a point inside should return the root layer.
4224 test_point = gfx::Point(1, 1);
4225 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4226 test_point, render_surface_layer_list);
4227 ASSERT_TRUE(result_layer);
4228 EXPECT_EQ(12345, result_layer->id());
4229
4230 test_point = gfx::Point(99, 99);
4231 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4232 test_point, render_surface_layer_list);
4233 ASSERT_TRUE(result_layer);
4234 EXPECT_EQ(12345, result_layer->id());
4235 }
4236
TEST_F(LayerTreeHostCommonTest,HitTestingForSingleLayerAndHud)4237 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleLayerAndHud) {
4238 FakeImplProxy proxy;
4239 FakeLayerTreeHostImpl host_impl(&proxy);
4240 scoped_ptr<LayerImpl> root =
4241 LayerImpl::Create(host_impl.active_tree(), 12345);
4242 scoped_ptr<HeadsUpDisplayLayerImpl> hud =
4243 HeadsUpDisplayLayerImpl::Create(host_impl.active_tree(), 11111);
4244
4245 gfx::Transform identity_matrix;
4246 gfx::PointF anchor;
4247 gfx::PointF position;
4248 gfx::Size bounds(100, 100);
4249 SetLayerPropertiesForTesting(root.get(),
4250 identity_matrix,
4251 identity_matrix,
4252 anchor,
4253 position,
4254 bounds,
4255 false);
4256 root->SetDrawsContent(true);
4257
4258 // Create hud and add it as a child of root.
4259 gfx::Size hud_bounds(200, 200);
4260 SetLayerPropertiesForTesting(hud.get(),
4261 identity_matrix,
4262 identity_matrix,
4263 anchor,
4264 position,
4265 hud_bounds,
4266 false);
4267 hud->SetDrawsContent(true);
4268
4269 host_impl.active_tree()->set_hud_layer(hud.get());
4270 root->AddChild(hud.PassAs<LayerImpl>());
4271
4272 LayerImplList render_surface_layer_list;
4273 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4274 root.get(), hud_bounds, &render_surface_layer_list);
4275 inputs.can_adjust_raster_scales = true;
4276 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4277
4278 // Sanity check the scenario we just created.
4279 ASSERT_EQ(1u, render_surface_layer_list.size());
4280 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
4281
4282 // Hit testing for a point inside HUD, but outside root should return null
4283 gfx::Point test_point(101, 101);
4284 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4285 test_point, render_surface_layer_list);
4286 EXPECT_FALSE(result_layer);
4287
4288 test_point = gfx::Point(-1, -1);
4289 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4290 test_point, render_surface_layer_list);
4291 EXPECT_FALSE(result_layer);
4292
4293 // Hit testing for a point inside should return the root layer, never the HUD
4294 // layer.
4295 test_point = gfx::Point(1, 1);
4296 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4297 test_point, render_surface_layer_list);
4298 ASSERT_TRUE(result_layer);
4299 EXPECT_EQ(12345, result_layer->id());
4300
4301 test_point = gfx::Point(99, 99);
4302 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4303 test_point, render_surface_layer_list);
4304 ASSERT_TRUE(result_layer);
4305 EXPECT_EQ(12345, result_layer->id());
4306 }
4307
TEST_F(LayerTreeHostCommonTest,HitTestingForUninvertibleTransform)4308 TEST_F(LayerTreeHostCommonTest, HitTestingForUninvertibleTransform) {
4309 FakeImplProxy proxy;
4310 FakeLayerTreeHostImpl host_impl(&proxy);
4311 scoped_ptr<LayerImpl> root =
4312 LayerImpl::Create(host_impl.active_tree(), 12345);
4313
4314 gfx::Transform uninvertible_transform;
4315 uninvertible_transform.matrix().set(0, 0, 0.0);
4316 uninvertible_transform.matrix().set(1, 1, 0.0);
4317 uninvertible_transform.matrix().set(2, 2, 0.0);
4318 uninvertible_transform.matrix().set(3, 3, 0.0);
4319 ASSERT_FALSE(uninvertible_transform.IsInvertible());
4320
4321 gfx::Transform identity_matrix;
4322 gfx::PointF anchor;
4323 gfx::PointF position;
4324 gfx::Size bounds(100, 100);
4325 SetLayerPropertiesForTesting(root.get(),
4326 uninvertible_transform,
4327 identity_matrix,
4328 anchor,
4329 position,
4330 bounds,
4331 false);
4332 root->SetDrawsContent(true);
4333
4334 LayerImplList render_surface_layer_list;
4335 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4336 root.get(), root->bounds(), &render_surface_layer_list);
4337 inputs.can_adjust_raster_scales = true;
4338 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4339
4340 // Sanity check the scenario we just created.
4341 ASSERT_EQ(1u, render_surface_layer_list.size());
4342 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4343 ASSERT_FALSE(root->screen_space_transform().IsInvertible());
4344
4345 // Hit testing any point should not hit the layer. If the invertible matrix is
4346 // accidentally ignored and treated like an identity, then the hit testing
4347 // will incorrectly hit the layer when it shouldn't.
4348 gfx::Point test_point(1, 1);
4349 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4350 test_point, render_surface_layer_list);
4351 EXPECT_FALSE(result_layer);
4352
4353 test_point = gfx::Point(10, 10);
4354 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4355 test_point, render_surface_layer_list);
4356 EXPECT_FALSE(result_layer);
4357
4358 test_point = gfx::Point(10, 30);
4359 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4360 test_point, render_surface_layer_list);
4361 EXPECT_FALSE(result_layer);
4362
4363 test_point = gfx::Point(50, 50);
4364 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4365 test_point, render_surface_layer_list);
4366 EXPECT_FALSE(result_layer);
4367
4368 test_point = gfx::Point(67, 48);
4369 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4370 test_point, render_surface_layer_list);
4371 EXPECT_FALSE(result_layer);
4372
4373 test_point = gfx::Point(99, 99);
4374 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4375 test_point, render_surface_layer_list);
4376 EXPECT_FALSE(result_layer);
4377
4378 test_point = gfx::Point(-1, -1);
4379 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4380 test_point, render_surface_layer_list);
4381 EXPECT_FALSE(result_layer);
4382 }
4383
TEST_F(LayerTreeHostCommonTest,HitTestingForSinglePositionedLayer)4384 TEST_F(LayerTreeHostCommonTest, HitTestingForSinglePositionedLayer) {
4385 FakeImplProxy proxy;
4386 FakeLayerTreeHostImpl host_impl(&proxy);
4387 scoped_ptr<LayerImpl> root =
4388 LayerImpl::Create(host_impl.active_tree(), 12345);
4389
4390 gfx::Transform identity_matrix;
4391 gfx::PointF anchor;
4392 // this layer is positioned, and hit testing should correctly know where the
4393 // layer is located.
4394 gfx::PointF position(50.f, 50.f);
4395 gfx::Size bounds(100, 100);
4396 SetLayerPropertiesForTesting(root.get(),
4397 identity_matrix,
4398 identity_matrix,
4399 anchor,
4400 position,
4401 bounds,
4402 false);
4403 root->SetDrawsContent(true);
4404
4405 LayerImplList render_surface_layer_list;
4406 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4407 root.get(), root->bounds(), &render_surface_layer_list);
4408 inputs.can_adjust_raster_scales = true;
4409 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4410
4411 // Sanity check the scenario we just created.
4412 ASSERT_EQ(1u, render_surface_layer_list.size());
4413 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4414
4415 // Hit testing for a point outside the layer should return a null pointer.
4416 gfx::Point test_point(49, 49);
4417 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4418 test_point, render_surface_layer_list);
4419 EXPECT_FALSE(result_layer);
4420
4421 // Even though the layer exists at (101, 101), it should not be visible there
4422 // since the root render surface would clamp it.
4423 test_point = gfx::Point(101, 101);
4424 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4425 test_point, render_surface_layer_list);
4426 EXPECT_FALSE(result_layer);
4427
4428 // Hit testing for a point inside should return the root layer.
4429 test_point = gfx::Point(51, 51);
4430 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4431 test_point, render_surface_layer_list);
4432 ASSERT_TRUE(result_layer);
4433 EXPECT_EQ(12345, result_layer->id());
4434
4435 test_point = gfx::Point(99, 99);
4436 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4437 test_point, render_surface_layer_list);
4438 ASSERT_TRUE(result_layer);
4439 EXPECT_EQ(12345, result_layer->id());
4440 }
4441
TEST_F(LayerTreeHostCommonTest,HitTestingForSingleRotatedLayer)4442 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleRotatedLayer) {
4443 FakeImplProxy proxy;
4444 FakeLayerTreeHostImpl host_impl(&proxy);
4445 scoped_ptr<LayerImpl> root =
4446 LayerImpl::Create(host_impl.active_tree(), 12345);
4447
4448 gfx::Transform identity_matrix;
4449 gfx::Transform rotation45_degrees_about_center;
4450 rotation45_degrees_about_center.Translate(50.0, 50.0);
4451 rotation45_degrees_about_center.RotateAboutZAxis(45.0);
4452 rotation45_degrees_about_center.Translate(-50.0, -50.0);
4453 gfx::PointF anchor;
4454 gfx::PointF position;
4455 gfx::Size bounds(100, 100);
4456 SetLayerPropertiesForTesting(root.get(),
4457 rotation45_degrees_about_center,
4458 identity_matrix,
4459 anchor,
4460 position,
4461 bounds,
4462 false);
4463 root->SetDrawsContent(true);
4464
4465 LayerImplList render_surface_layer_list;
4466 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4467 root.get(), root->bounds(), &render_surface_layer_list);
4468 inputs.can_adjust_raster_scales = true;
4469 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4470
4471 // Sanity check the scenario we just created.
4472 ASSERT_EQ(1u, render_surface_layer_list.size());
4473 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4474
4475 // Hit testing for points outside the layer.
4476 // These corners would have been inside the un-transformed layer, but they
4477 // should not hit the correctly transformed layer.
4478 gfx::Point test_point(99, 99);
4479 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4480 test_point, render_surface_layer_list);
4481 EXPECT_FALSE(result_layer);
4482
4483 test_point = gfx::Point(1, 1);
4484 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4485 test_point, render_surface_layer_list);
4486 EXPECT_FALSE(result_layer);
4487
4488 // Hit testing for a point inside should return the root layer.
4489 test_point = gfx::Point(1, 50);
4490 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4491 test_point, render_surface_layer_list);
4492 ASSERT_TRUE(result_layer);
4493 EXPECT_EQ(12345, result_layer->id());
4494
4495 // Hit testing the corners that would overlap the unclipped layer, but are
4496 // outside the clipped region.
4497 test_point = gfx::Point(50, -1);
4498 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4499 test_point, render_surface_layer_list);
4500 ASSERT_FALSE(result_layer);
4501
4502 test_point = gfx::Point(-1, 50);
4503 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4504 test_point, render_surface_layer_list);
4505 ASSERT_FALSE(result_layer);
4506 }
4507
TEST_F(LayerTreeHostCommonTest,HitTestingForSinglePerspectiveLayer)4508 TEST_F(LayerTreeHostCommonTest, HitTestingForSinglePerspectiveLayer) {
4509 FakeImplProxy proxy;
4510 FakeLayerTreeHostImpl host_impl(&proxy);
4511 scoped_ptr<LayerImpl> root =
4512 LayerImpl::Create(host_impl.active_tree(), 12345);
4513
4514 gfx::Transform identity_matrix;
4515
4516 // perspective_projection_about_center * translation_by_z is designed so that
4517 // the 100 x 100 layer becomes 50 x 50, and remains centered at (50, 50).
4518 gfx::Transform perspective_projection_about_center;
4519 perspective_projection_about_center.Translate(50.0, 50.0);
4520 perspective_projection_about_center.ApplyPerspectiveDepth(1.0);
4521 perspective_projection_about_center.Translate(-50.0, -50.0);
4522 gfx::Transform translation_by_z;
4523 translation_by_z.Translate3d(0.0, 0.0, -1.0);
4524
4525 gfx::PointF anchor;
4526 gfx::PointF position;
4527 gfx::Size bounds(100, 100);
4528 SetLayerPropertiesForTesting(
4529 root.get(),
4530 perspective_projection_about_center * translation_by_z,
4531 identity_matrix,
4532 anchor,
4533 position,
4534 bounds,
4535 false);
4536 root->SetDrawsContent(true);
4537
4538 LayerImplList render_surface_layer_list;
4539 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4540 root.get(), root->bounds(), &render_surface_layer_list);
4541 inputs.can_adjust_raster_scales = true;
4542 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4543
4544 // Sanity check the scenario we just created.
4545 ASSERT_EQ(1u, render_surface_layer_list.size());
4546 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4547
4548 // Hit testing for points outside the layer.
4549 // These corners would have been inside the un-transformed layer, but they
4550 // should not hit the correctly transformed layer.
4551 gfx::Point test_point(24, 24);
4552 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4553 test_point, render_surface_layer_list);
4554 EXPECT_FALSE(result_layer);
4555
4556 test_point = gfx::Point(76, 76);
4557 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4558 test_point, render_surface_layer_list);
4559 EXPECT_FALSE(result_layer);
4560
4561 // Hit testing for a point inside should return the root layer.
4562 test_point = gfx::Point(26, 26);
4563 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4564 test_point, render_surface_layer_list);
4565 ASSERT_TRUE(result_layer);
4566 EXPECT_EQ(12345, result_layer->id());
4567
4568 test_point = gfx::Point(74, 74);
4569 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4570 test_point, render_surface_layer_list);
4571 ASSERT_TRUE(result_layer);
4572 EXPECT_EQ(12345, result_layer->id());
4573 }
4574
TEST_F(LayerTreeHostCommonTest,HitTestingForSingleLayerWithScaledContents)4575 TEST_F(LayerTreeHostCommonTest, HitTestingForSingleLayerWithScaledContents) {
4576 // A layer's visible content rect is actually in the layer's content space.
4577 // The screen space transform converts from the layer's origin space to screen
4578 // space. This test makes sure that hit testing works correctly accounts for
4579 // the contents scale. A contents scale that is not 1 effectively forces a
4580 // non-identity transform between layer's content space and layer's origin
4581 // space. The hit testing code must take this into account.
4582 //
4583 // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
4584 // contents scale is ignored, then hit testing will mis-interpret the visible
4585 // content rect as being larger than the actual bounds of the layer.
4586 //
4587 FakeImplProxy proxy;
4588 FakeLayerTreeHostImpl host_impl(&proxy);
4589 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
4590
4591 gfx::Transform identity_matrix;
4592 gfx::PointF anchor;
4593
4594 SetLayerPropertiesForTesting(root.get(),
4595 identity_matrix,
4596 identity_matrix,
4597 anchor,
4598 gfx::PointF(),
4599 gfx::Size(100, 100),
4600 false);
4601 {
4602 gfx::PointF position(25.f, 25.f);
4603 gfx::Size bounds(50, 50);
4604 scoped_ptr<LayerImpl> test_layer =
4605 LayerImpl::Create(host_impl.active_tree(), 12345);
4606 SetLayerPropertiesForTesting(test_layer.get(),
4607 identity_matrix,
4608 identity_matrix,
4609 anchor,
4610 position,
4611 bounds,
4612 false);
4613
4614 // override content bounds and contents scale
4615 test_layer->SetContentBounds(gfx::Size(100, 100));
4616 test_layer->SetContentsScale(2, 2);
4617
4618 test_layer->SetDrawsContent(true);
4619 root->AddChild(test_layer.Pass());
4620 }
4621
4622 LayerImplList render_surface_layer_list;
4623 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4624 root.get(), root->bounds(), &render_surface_layer_list);
4625 inputs.can_adjust_raster_scales = true;
4626 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4627
4628 // Sanity check the scenario we just created.
4629 // The visible content rect for test_layer is actually 100x100, even though
4630 // its layout size is 50x50, positioned at 25x25.
4631 LayerImpl* test_layer = root->children()[0];
4632 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100),
4633 test_layer->visible_content_rect());
4634 ASSERT_EQ(1u, render_surface_layer_list.size());
4635 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4636
4637 // Hit testing for a point outside the layer should return a null pointer (the
4638 // root layer does not draw content, so it will not be hit tested either).
4639 gfx::Point test_point(101, 101);
4640 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4641 test_point, render_surface_layer_list);
4642 EXPECT_FALSE(result_layer);
4643
4644 test_point = gfx::Point(24, 24);
4645 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4646 test_point, render_surface_layer_list);
4647 EXPECT_FALSE(result_layer);
4648
4649 test_point = gfx::Point(76, 76);
4650 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4651 test_point, render_surface_layer_list);
4652 EXPECT_FALSE(result_layer);
4653
4654 // Hit testing for a point inside should return the test layer.
4655 test_point = gfx::Point(26, 26);
4656 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4657 test_point, render_surface_layer_list);
4658 ASSERT_TRUE(result_layer);
4659 EXPECT_EQ(12345, result_layer->id());
4660
4661 test_point = gfx::Point(74, 74);
4662 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4663 test_point, render_surface_layer_list);
4664 ASSERT_TRUE(result_layer);
4665 EXPECT_EQ(12345, result_layer->id());
4666 }
4667
TEST_F(LayerTreeHostCommonTest,HitTestingForSimpleClippedLayer)4668 TEST_F(LayerTreeHostCommonTest, HitTestingForSimpleClippedLayer) {
4669 // Test that hit-testing will only work for the visible portion of a layer,
4670 // and not the entire layer bounds. Here we just test the simple axis-aligned
4671 // case.
4672 gfx::Transform identity_matrix;
4673 gfx::PointF anchor;
4674
4675 FakeImplProxy proxy;
4676 FakeLayerTreeHostImpl host_impl(&proxy);
4677 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
4678 SetLayerPropertiesForTesting(root.get(),
4679 identity_matrix,
4680 identity_matrix,
4681 anchor,
4682 gfx::PointF(),
4683 gfx::Size(100, 100),
4684 false);
4685 {
4686 scoped_ptr<LayerImpl> clipping_layer =
4687 LayerImpl::Create(host_impl.active_tree(), 123);
4688 // this layer is positioned, and hit testing should correctly know where the
4689 // layer is located.
4690 gfx::PointF position(25.f, 25.f);
4691 gfx::Size bounds(50, 50);
4692 SetLayerPropertiesForTesting(clipping_layer.get(),
4693 identity_matrix,
4694 identity_matrix,
4695 anchor,
4696 position,
4697 bounds,
4698 false);
4699 clipping_layer->SetMasksToBounds(true);
4700
4701 scoped_ptr<LayerImpl> child =
4702 LayerImpl::Create(host_impl.active_tree(), 456);
4703 position = gfx::PointF(-50.f, -50.f);
4704 bounds = gfx::Size(300, 300);
4705 SetLayerPropertiesForTesting(child.get(),
4706 identity_matrix,
4707 identity_matrix,
4708 anchor,
4709 position,
4710 bounds,
4711 false);
4712 child->SetDrawsContent(true);
4713 clipping_layer->AddChild(child.Pass());
4714 root->AddChild(clipping_layer.Pass());
4715 }
4716
4717 LayerImplList render_surface_layer_list;
4718 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4719 root.get(), root->bounds(), &render_surface_layer_list);
4720 inputs.can_adjust_raster_scales = true;
4721 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4722
4723 // Sanity check the scenario we just created.
4724 ASSERT_EQ(1u, render_surface_layer_list.size());
4725 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4726 ASSERT_EQ(456, root->render_surface()->layer_list().at(0)->id());
4727
4728 // Hit testing for a point outside the layer should return a null pointer.
4729 // Despite the child layer being very large, it should be clipped to the root
4730 // layer's bounds.
4731 gfx::Point test_point(24, 24);
4732 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4733 test_point, render_surface_layer_list);
4734 EXPECT_FALSE(result_layer);
4735
4736 // Even though the layer exists at (101, 101), it should not be visible there
4737 // since the clipping_layer would clamp it.
4738 test_point = gfx::Point(76, 76);
4739 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4740 test_point, render_surface_layer_list);
4741 EXPECT_FALSE(result_layer);
4742
4743 // Hit testing for a point inside should return the child layer.
4744 test_point = gfx::Point(26, 26);
4745 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4746 test_point, render_surface_layer_list);
4747 ASSERT_TRUE(result_layer);
4748 EXPECT_EQ(456, result_layer->id());
4749
4750 test_point = gfx::Point(74, 74);
4751 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4752 test_point, render_surface_layer_list);
4753 ASSERT_TRUE(result_layer);
4754 EXPECT_EQ(456, result_layer->id());
4755 }
4756
TEST_F(LayerTreeHostCommonTest,HitTestingForMultiClippedRotatedLayer)4757 TEST_F(LayerTreeHostCommonTest, HitTestingForMultiClippedRotatedLayer) {
4758 // This test checks whether hit testing correctly avoids hit testing with
4759 // multiple ancestors that clip in non axis-aligned ways. To pass this test,
4760 // the hit testing algorithm needs to recognize that multiple parent layers
4761 // may clip the layer, and should not actually hit those clipped areas.
4762 //
4763 // The child and grand_child layers are both initialized to clip the
4764 // rotated_leaf. The child layer is rotated about the top-left corner, so that
4765 // the root + child clips combined create a triangle. The rotated_leaf will
4766 // only be visible where it overlaps this triangle.
4767 //
4768 FakeImplProxy proxy;
4769 FakeLayerTreeHostImpl host_impl(&proxy);
4770 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 123);
4771
4772 gfx::Transform identity_matrix;
4773 gfx::PointF anchor;
4774 gfx::PointF position;
4775 gfx::Size bounds(100, 100);
4776 SetLayerPropertiesForTesting(root.get(),
4777 identity_matrix,
4778 identity_matrix,
4779 anchor,
4780 position,
4781 bounds,
4782 false);
4783 root->SetMasksToBounds(true);
4784 {
4785 scoped_ptr<LayerImpl> child =
4786 LayerImpl::Create(host_impl.active_tree(), 456);
4787 scoped_ptr<LayerImpl> grand_child =
4788 LayerImpl::Create(host_impl.active_tree(), 789);
4789 scoped_ptr<LayerImpl> rotated_leaf =
4790 LayerImpl::Create(host_impl.active_tree(), 2468);
4791
4792 position = gfx::PointF(10.f, 10.f);
4793 bounds = gfx::Size(80, 80);
4794 SetLayerPropertiesForTesting(child.get(),
4795 identity_matrix,
4796 identity_matrix,
4797 anchor,
4798 position,
4799 bounds,
4800 false);
4801 child->SetMasksToBounds(true);
4802
4803 gfx::Transform rotation45_degrees_about_corner;
4804 rotation45_degrees_about_corner.RotateAboutZAxis(45.0);
4805
4806 // remember, positioned with respect to its parent which is already at 10,
4807 // 10
4808 position = gfx::PointF();
4809 bounds =
4810 gfx::Size(200, 200); // to ensure it covers at least sqrt(2) * 100.
4811 SetLayerPropertiesForTesting(grand_child.get(),
4812 rotation45_degrees_about_corner,
4813 identity_matrix,
4814 anchor,
4815 position,
4816 bounds,
4817 false);
4818 grand_child->SetMasksToBounds(true);
4819
4820 // Rotates about the center of the layer
4821 gfx::Transform rotated_leaf_transform;
4822 rotated_leaf_transform.Translate(
4823 -10.0, -10.0); // cancel out the grand_parent's position
4824 rotated_leaf_transform.RotateAboutZAxis(
4825 -45.0); // cancel out the corner 45-degree rotation of the parent.
4826 rotated_leaf_transform.Translate(50.0, 50.0);
4827 rotated_leaf_transform.RotateAboutZAxis(45.0);
4828 rotated_leaf_transform.Translate(-50.0, -50.0);
4829 position = gfx::PointF();
4830 bounds = gfx::Size(100, 100);
4831 SetLayerPropertiesForTesting(rotated_leaf.get(),
4832 rotated_leaf_transform,
4833 identity_matrix,
4834 anchor,
4835 position,
4836 bounds,
4837 false);
4838 rotated_leaf->SetDrawsContent(true);
4839
4840 grand_child->AddChild(rotated_leaf.Pass());
4841 child->AddChild(grand_child.Pass());
4842 root->AddChild(child.Pass());
4843 }
4844
4845 LayerImplList render_surface_layer_list;
4846 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4847 root.get(), root->bounds(), &render_surface_layer_list);
4848 inputs.can_adjust_raster_scales = true;
4849 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4850
4851 // Sanity check the scenario we just created.
4852 // The grand_child is expected to create a render surface because it
4853 // MasksToBounds and is not axis aligned.
4854 ASSERT_EQ(2u, render_surface_layer_list.size());
4855 ASSERT_EQ(
4856 1u,
4857 render_surface_layer_list.at(0)->render_surface()->layer_list().size());
4858 ASSERT_EQ(789,
4859 render_surface_layer_list.at(0)->render_surface()->layer_list().at(
4860 0)->id()); // grand_child's surface.
4861 ASSERT_EQ(
4862 1u,
4863 render_surface_layer_list.at(1)->render_surface()->layer_list().size());
4864 ASSERT_EQ(
4865 2468,
4866 render_surface_layer_list[1]->render_surface()->layer_list().at(0)->id());
4867
4868 // (11, 89) is close to the the bottom left corner within the clip, but it is
4869 // not inside the layer.
4870 gfx::Point test_point(11, 89);
4871 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4872 test_point, render_surface_layer_list);
4873 EXPECT_FALSE(result_layer);
4874
4875 // Closer inwards from the bottom left will overlap the layer.
4876 test_point = gfx::Point(25, 75);
4877 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4878 test_point, render_surface_layer_list);
4879 ASSERT_TRUE(result_layer);
4880 EXPECT_EQ(2468, result_layer->id());
4881
4882 // (4, 50) is inside the unclipped layer, but that corner of the layer should
4883 // be clipped away by the grandparent and should not get hit. If hit testing
4884 // blindly uses visible content rect without considering how parent may clip
4885 // the layer, then hit testing would accidentally think that the point
4886 // successfully hits the layer.
4887 test_point = gfx::Point(4, 50);
4888 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4889 test_point, render_surface_layer_list);
4890 EXPECT_FALSE(result_layer);
4891
4892 // (11, 50) is inside the layer and within the clipped area.
4893 test_point = gfx::Point(11, 50);
4894 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4895 test_point, render_surface_layer_list);
4896 ASSERT_TRUE(result_layer);
4897 EXPECT_EQ(2468, result_layer->id());
4898
4899 // Around the middle, just to the right and up, would have hit the layer
4900 // except that that area should be clipped away by the parent.
4901 test_point = gfx::Point(51, 49);
4902 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4903 test_point, render_surface_layer_list);
4904 EXPECT_FALSE(result_layer);
4905
4906 // Around the middle, just to the left and down, should successfully hit the
4907 // layer.
4908 test_point = gfx::Point(49, 51);
4909 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4910 test_point, render_surface_layer_list);
4911 ASSERT_TRUE(result_layer);
4912 EXPECT_EQ(2468, result_layer->id());
4913 }
4914
TEST_F(LayerTreeHostCommonTest,HitTestingForNonClippingIntermediateLayer)4915 TEST_F(LayerTreeHostCommonTest, HitTestingForNonClippingIntermediateLayer) {
4916 // This test checks that hit testing code does not accidentally clip to layer
4917 // bounds for a layer that actually does not clip.
4918 gfx::Transform identity_matrix;
4919 gfx::PointF anchor;
4920
4921 FakeImplProxy proxy;
4922 FakeLayerTreeHostImpl host_impl(&proxy);
4923 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
4924 SetLayerPropertiesForTesting(root.get(),
4925 identity_matrix,
4926 identity_matrix,
4927 anchor,
4928 gfx::PointF(),
4929 gfx::Size(100, 100),
4930 false);
4931 {
4932 scoped_ptr<LayerImpl> intermediate_layer =
4933 LayerImpl::Create(host_impl.active_tree(), 123);
4934 // this layer is positioned, and hit testing should correctly know where the
4935 // layer is located.
4936 gfx::PointF position(10.f, 10.f);
4937 gfx::Size bounds(50, 50);
4938 SetLayerPropertiesForTesting(intermediate_layer.get(),
4939 identity_matrix,
4940 identity_matrix,
4941 anchor,
4942 position,
4943 bounds,
4944 false);
4945 // Sanity check the intermediate layer should not clip.
4946 ASSERT_FALSE(intermediate_layer->masks_to_bounds());
4947 ASSERT_FALSE(intermediate_layer->mask_layer());
4948
4949 // The child of the intermediate_layer is translated so that it does not
4950 // overlap intermediate_layer at all. If child is incorrectly clipped, we
4951 // would not be able to hit it successfully.
4952 scoped_ptr<LayerImpl> child =
4953 LayerImpl::Create(host_impl.active_tree(), 456);
4954 position = gfx::PointF(60.f, 60.f); // 70, 70 in screen space
4955 bounds = gfx::Size(20, 20);
4956 SetLayerPropertiesForTesting(child.get(),
4957 identity_matrix,
4958 identity_matrix,
4959 anchor,
4960 position,
4961 bounds,
4962 false);
4963 child->SetDrawsContent(true);
4964 intermediate_layer->AddChild(child.Pass());
4965 root->AddChild(intermediate_layer.Pass());
4966 }
4967
4968 LayerImplList render_surface_layer_list;
4969 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
4970 root.get(), root->bounds(), &render_surface_layer_list);
4971 inputs.can_adjust_raster_scales = true;
4972 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
4973
4974 // Sanity check the scenario we just created.
4975 ASSERT_EQ(1u, render_surface_layer_list.size());
4976 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
4977 ASSERT_EQ(456, root->render_surface()->layer_list().at(0)->id());
4978
4979 // Hit testing for a point outside the layer should return a null pointer.
4980 gfx::Point test_point(69, 69);
4981 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4982 test_point, render_surface_layer_list);
4983 EXPECT_FALSE(result_layer);
4984
4985 test_point = gfx::Point(91, 91);
4986 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4987 test_point, render_surface_layer_list);
4988 EXPECT_FALSE(result_layer);
4989
4990 // Hit testing for a point inside should return the child layer.
4991 test_point = gfx::Point(71, 71);
4992 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4993 test_point, render_surface_layer_list);
4994 ASSERT_TRUE(result_layer);
4995 EXPECT_EQ(456, result_layer->id());
4996
4997 test_point = gfx::Point(89, 89);
4998 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
4999 test_point, render_surface_layer_list);
5000 ASSERT_TRUE(result_layer);
5001 EXPECT_EQ(456, result_layer->id());
5002 }
5003
TEST_F(LayerTreeHostCommonTest,HitTestingForMultipleLayers)5004 TEST_F(LayerTreeHostCommonTest, HitTestingForMultipleLayers) {
5005 FakeImplProxy proxy;
5006 FakeLayerTreeHostImpl host_impl(&proxy);
5007 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5008
5009 gfx::Transform identity_matrix;
5010 gfx::PointF anchor;
5011 gfx::PointF position;
5012 gfx::Size bounds(100, 100);
5013 SetLayerPropertiesForTesting(root.get(),
5014 identity_matrix,
5015 identity_matrix,
5016 anchor,
5017 position,
5018 bounds,
5019 false);
5020 root->SetDrawsContent(true);
5021 {
5022 // child 1 and child2 are initialized to overlap between x=50 and x=60.
5023 // grand_child is set to overlap both child1 and child2 between y=50 and
5024 // y=60. The expected stacking order is: (front) child2, (second)
5025 // grand_child, (third) child1, and (back) the root layer behind all other
5026 // layers.
5027
5028 scoped_ptr<LayerImpl> child1 =
5029 LayerImpl::Create(host_impl.active_tree(), 2);
5030 scoped_ptr<LayerImpl> child2 =
5031 LayerImpl::Create(host_impl.active_tree(), 3);
5032 scoped_ptr<LayerImpl> grand_child1 =
5033 LayerImpl::Create(host_impl.active_tree(), 4);
5034
5035 position = gfx::PointF(10.f, 10.f);
5036 bounds = gfx::Size(50, 50);
5037 SetLayerPropertiesForTesting(child1.get(),
5038 identity_matrix,
5039 identity_matrix,
5040 anchor,
5041 position,
5042 bounds,
5043 false);
5044 child1->SetDrawsContent(true);
5045
5046 position = gfx::PointF(50.f, 10.f);
5047 bounds = gfx::Size(50, 50);
5048 SetLayerPropertiesForTesting(child2.get(),
5049 identity_matrix,
5050 identity_matrix,
5051 anchor,
5052 position,
5053 bounds,
5054 false);
5055 child2->SetDrawsContent(true);
5056
5057 // Remember that grand_child is positioned with respect to its parent (i.e.
5058 // child1). In screen space, the intended position is (10, 50), with size
5059 // 100 x 50.
5060 position = gfx::PointF(0.f, 40.f);
5061 bounds = gfx::Size(100, 50);
5062 SetLayerPropertiesForTesting(grand_child1.get(),
5063 identity_matrix,
5064 identity_matrix,
5065 anchor,
5066 position,
5067 bounds,
5068 false);
5069 grand_child1->SetDrawsContent(true);
5070
5071 child1->AddChild(grand_child1.Pass());
5072 root->AddChild(child1.Pass());
5073 root->AddChild(child2.Pass());
5074 }
5075
5076 LayerImpl* child1 = root->children()[0];
5077 LayerImpl* child2 = root->children()[1];
5078 LayerImpl* grand_child1 = child1->children()[0];
5079
5080 LayerImplList render_surface_layer_list;
5081 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5082 root.get(), root->bounds(), &render_surface_layer_list);
5083 inputs.can_adjust_raster_scales = true;
5084 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5085
5086 // Sanity check the scenario we just created.
5087 ASSERT_TRUE(child1);
5088 ASSERT_TRUE(child2);
5089 ASSERT_TRUE(grand_child1);
5090 ASSERT_EQ(1u, render_surface_layer_list.size());
5091
5092 RenderSurfaceImpl* root_render_surface = root->render_surface();
5093 ASSERT_EQ(4u, root_render_surface->layer_list().size());
5094 ASSERT_EQ(1, root_render_surface->layer_list().at(0)->id()); // root layer
5095 ASSERT_EQ(2, root_render_surface->layer_list().at(1)->id()); // child1
5096 ASSERT_EQ(4, root_render_surface->layer_list().at(2)->id()); // grand_child1
5097 ASSERT_EQ(3, root_render_surface->layer_list().at(3)->id()); // child2
5098
5099 // Nothing overlaps the root_layer at (1, 1), so hit testing there should find
5100 // the root layer.
5101 gfx::Point test_point = gfx::Point(1, 1);
5102 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5103 test_point, render_surface_layer_list);
5104 ASSERT_TRUE(result_layer);
5105 EXPECT_EQ(1, result_layer->id());
5106
5107 // At (15, 15), child1 and root are the only layers. child1 is expected to be
5108 // on top.
5109 test_point = gfx::Point(15, 15);
5110 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5111 test_point, render_surface_layer_list);
5112 ASSERT_TRUE(result_layer);
5113 EXPECT_EQ(2, result_layer->id());
5114
5115 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
5116 test_point = gfx::Point(51, 20);
5117 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5118 test_point, render_surface_layer_list);
5119 ASSERT_TRUE(result_layer);
5120 EXPECT_EQ(3, result_layer->id());
5121
5122 // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
5123 // top.
5124 test_point = gfx::Point(80, 51);
5125 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5126 test_point, render_surface_layer_list);
5127 ASSERT_TRUE(result_layer);
5128 EXPECT_EQ(3, result_layer->id());
5129
5130 // At (51, 51), all layers overlap each other. child2 is expected to be on top
5131 // of all other layers.
5132 test_point = gfx::Point(51, 51);
5133 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5134 test_point, render_surface_layer_list);
5135 ASSERT_TRUE(result_layer);
5136 EXPECT_EQ(3, result_layer->id());
5137
5138 // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
5139 // be on top.
5140 test_point = gfx::Point(20, 51);
5141 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5142 test_point, render_surface_layer_list);
5143 ASSERT_TRUE(result_layer);
5144 EXPECT_EQ(4, result_layer->id());
5145 }
5146
TEST_F(LayerTreeHostCommonTest,HitTestingForMultipleLayerLists)5147 TEST_F(LayerTreeHostCommonTest, HitTestingForMultipleLayerLists) {
5148 //
5149 // The geometry is set up similarly to the previous case, but
5150 // all layers are forced to be render surfaces now.
5151 //
5152 FakeImplProxy proxy;
5153 FakeLayerTreeHostImpl host_impl(&proxy);
5154 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5155
5156 gfx::Transform identity_matrix;
5157 gfx::PointF anchor;
5158 gfx::PointF position;
5159 gfx::Size bounds(100, 100);
5160 SetLayerPropertiesForTesting(root.get(),
5161 identity_matrix,
5162 identity_matrix,
5163 anchor,
5164 position,
5165 bounds,
5166 false);
5167 root->SetDrawsContent(true);
5168 {
5169 // child 1 and child2 are initialized to overlap between x=50 and x=60.
5170 // grand_child is set to overlap both child1 and child2 between y=50 and
5171 // y=60. The expected stacking order is: (front) child2, (second)
5172 // grand_child, (third) child1, and (back) the root layer behind all other
5173 // layers.
5174
5175 scoped_ptr<LayerImpl> child1 =
5176 LayerImpl::Create(host_impl.active_tree(), 2);
5177 scoped_ptr<LayerImpl> child2 =
5178 LayerImpl::Create(host_impl.active_tree(), 3);
5179 scoped_ptr<LayerImpl> grand_child1 =
5180 LayerImpl::Create(host_impl.active_tree(), 4);
5181
5182 position = gfx::PointF(10.f, 10.f);
5183 bounds = gfx::Size(50, 50);
5184 SetLayerPropertiesForTesting(child1.get(),
5185 identity_matrix,
5186 identity_matrix,
5187 anchor,
5188 position,
5189 bounds,
5190 false);
5191 child1->SetDrawsContent(true);
5192 child1->SetForceRenderSurface(true);
5193
5194 position = gfx::PointF(50.f, 10.f);
5195 bounds = gfx::Size(50, 50);
5196 SetLayerPropertiesForTesting(child2.get(),
5197 identity_matrix,
5198 identity_matrix,
5199 anchor,
5200 position,
5201 bounds,
5202 false);
5203 child2->SetDrawsContent(true);
5204 child2->SetForceRenderSurface(true);
5205
5206 // Remember that grand_child is positioned with respect to its parent (i.e.
5207 // child1). In screen space, the intended position is (10, 50), with size
5208 // 100 x 50.
5209 position = gfx::PointF(0.f, 40.f);
5210 bounds = gfx::Size(100, 50);
5211 SetLayerPropertiesForTesting(grand_child1.get(),
5212 identity_matrix,
5213 identity_matrix,
5214 anchor,
5215 position,
5216 bounds,
5217 false);
5218 grand_child1->SetDrawsContent(true);
5219 grand_child1->SetForceRenderSurface(true);
5220
5221 child1->AddChild(grand_child1.Pass());
5222 root->AddChild(child1.Pass());
5223 root->AddChild(child2.Pass());
5224 }
5225
5226 LayerImpl* child1 = root->children()[0];
5227 LayerImpl* child2 = root->children()[1];
5228 LayerImpl* grand_child1 = child1->children()[0];
5229
5230 LayerImplList render_surface_layer_list;
5231 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5232 root.get(), root->bounds(), &render_surface_layer_list);
5233 inputs.can_adjust_raster_scales = true;
5234 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5235
5236 // Sanity check the scenario we just created.
5237 ASSERT_TRUE(child1);
5238 ASSERT_TRUE(child2);
5239 ASSERT_TRUE(grand_child1);
5240 ASSERT_TRUE(child1->render_surface());
5241 ASSERT_TRUE(child2->render_surface());
5242 ASSERT_TRUE(grand_child1->render_surface());
5243 ASSERT_EQ(4u, render_surface_layer_list.size());
5244 // The root surface has the root layer, and child1's and child2's render
5245 // surfaces.
5246 ASSERT_EQ(3u, root->render_surface()->layer_list().size());
5247 // The child1 surface has the child1 layer and grand_child1's render surface.
5248 ASSERT_EQ(2u, child1->render_surface()->layer_list().size());
5249 ASSERT_EQ(1u, child2->render_surface()->layer_list().size());
5250 ASSERT_EQ(1u, grand_child1->render_surface()->layer_list().size());
5251 ASSERT_EQ(1, render_surface_layer_list.at(0)->id()); // root layer
5252 ASSERT_EQ(2, render_surface_layer_list[1]->id()); // child1
5253 ASSERT_EQ(4, render_surface_layer_list.at(2)->id()); // grand_child1
5254 ASSERT_EQ(3, render_surface_layer_list[3]->id()); // child2
5255
5256 // Nothing overlaps the root_layer at (1, 1), so hit testing there should find
5257 // the root layer.
5258 gfx::Point test_point = gfx::Point(1, 1);
5259 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5260 test_point, render_surface_layer_list);
5261 ASSERT_TRUE(result_layer);
5262 EXPECT_EQ(1, result_layer->id());
5263
5264 // At (15, 15), child1 and root are the only layers. child1 is expected to be
5265 // on top.
5266 test_point = gfx::Point(15, 15);
5267 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5268 test_point, render_surface_layer_list);
5269 ASSERT_TRUE(result_layer);
5270 EXPECT_EQ(2, result_layer->id());
5271
5272 // At (51, 20), child1 and child2 overlap. child2 is expected to be on top.
5273 test_point = gfx::Point(51, 20);
5274 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5275 test_point, render_surface_layer_list);
5276 ASSERT_TRUE(result_layer);
5277 EXPECT_EQ(3, result_layer->id());
5278
5279 // At (80, 51), child2 and grand_child1 overlap. child2 is expected to be on
5280 // top.
5281 test_point = gfx::Point(80, 51);
5282 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5283 test_point, render_surface_layer_list);
5284 ASSERT_TRUE(result_layer);
5285 EXPECT_EQ(3, result_layer->id());
5286
5287 // At (51, 51), all layers overlap each other. child2 is expected to be on top
5288 // of all other layers.
5289 test_point = gfx::Point(51, 51);
5290 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5291 test_point, render_surface_layer_list);
5292 ASSERT_TRUE(result_layer);
5293 EXPECT_EQ(3, result_layer->id());
5294
5295 // At (20, 51), child1 and grand_child1 overlap. grand_child1 is expected to
5296 // be on top.
5297 test_point = gfx::Point(20, 51);
5298 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5299 test_point, render_surface_layer_list);
5300 ASSERT_TRUE(result_layer);
5301 EXPECT_EQ(4, result_layer->id());
5302 }
5303
TEST_F(LayerTreeHostCommonTest,HitTestingForEmptyLayers)5304 TEST_F(LayerTreeHostCommonTest, HitTestingForEmptyLayers) {
5305 FakeImplProxy proxy;
5306 FakeLayerTreeHostImpl host_impl(&proxy);
5307
5308 // Layer 1 - root
5309 scoped_ptr<LayerImpl> root =
5310 LayerImpl::Create(host_impl.active_tree(), 1);
5311 gfx::Transform identity_matrix;
5312 gfx::PointF anchor;
5313 gfx::PointF position;
5314 gfx::Size bounds(100, 100);
5315 SetLayerPropertiesForTesting(root.get(),
5316 identity_matrix,
5317 identity_matrix,
5318 anchor,
5319 position,
5320 bounds,
5321 false);
5322 root->SetDrawsContent(true);
5323
5324 {
5325 // Layer 2 - empty: drawsContent=false
5326 gfx::PointF position(10.f, 10.f);
5327 gfx::Size bounds(30, 30);
5328 scoped_ptr<LayerImpl> empty_layer =
5329 LayerImpl::Create(host_impl.active_tree(), 2);
5330 SetLayerPropertiesForTesting(empty_layer.get(),
5331 identity_matrix,
5332 identity_matrix,
5333 anchor,
5334 position,
5335 bounds,
5336 false);
5337
5338 empty_layer->SetDrawsContent(false);
5339 root->AddChild(empty_layer.Pass());
5340 }
5341
5342 {
5343 // Layer 3 - empty, but has touch handler
5344 gfx::PointF position(10.f, 60.f);
5345 gfx::Size bounds(30, 30);
5346 scoped_ptr<LayerImpl> test_layer =
5347 LayerImpl::Create(host_impl.active_tree(), 3);
5348 SetLayerPropertiesForTesting(test_layer.get(),
5349 identity_matrix,
5350 identity_matrix,
5351 anchor,
5352 position,
5353 bounds,
5354 false);
5355
5356 test_layer->SetDrawsContent(false);
5357 Region touch_handler_region(gfx::Rect(10, 10, 10, 10));
5358 test_layer->SetTouchEventHandlerRegion(touch_handler_region);
5359 root->AddChild(test_layer.Pass());
5360 }
5361
5362 {
5363 // Layer 4 - empty, but has mousewheel handler
5364 gfx::PointF position(60.f, 60.f);
5365 gfx::Size bounds(30, 30);
5366 scoped_ptr<LayerImpl> test_layer =
5367 LayerImpl::Create(host_impl.active_tree(), 4);
5368 SetLayerPropertiesForTesting(test_layer.get(),
5369 identity_matrix,
5370 identity_matrix,
5371 anchor,
5372 position,
5373 bounds,
5374 false);
5375
5376 test_layer->SetDrawsContent(false);
5377 test_layer->SetHaveWheelEventHandlers(true);
5378 root->AddChild(test_layer.Pass());
5379 }
5380
5381 LayerImplList render_surface_layer_list;
5382 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5383 root.get(), root->bounds(), &render_surface_layer_list);
5384 inputs.can_adjust_raster_scales = true;
5385 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5386
5387 // Verify that the root layer and empty layers with touch/wheel handlers
5388 // (but not the empty layer without a touch handler) are in the RSSL.
5389 ASSERT_EQ(1u, render_surface_layer_list.size());
5390 EXPECT_EQ(1, render_surface_layer_list[0]->id());
5391 ASSERT_EQ(3u, root->render_surface()->layer_list().size());
5392 EXPECT_EQ(1, root->render_surface()->layer_list().at(0)->id());
5393 EXPECT_EQ(3, root->render_surface()->layer_list().at(1)->id());
5394 EXPECT_EQ(4, root->render_surface()->layer_list().at(2)->id());
5395
5396 // Hit testing for a point inside the empty no-handlers layer should return
5397 // the root layer.
5398 gfx::Point test_point = gfx::Point(15, 15);
5399 LayerImpl* result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5400 test_point, render_surface_layer_list);
5401 ASSERT_TRUE(result_layer);
5402 EXPECT_EQ(1, result_layer->id());
5403
5404 // Hit testing for a point inside the touch handler layer should return it.
5405 test_point = gfx::Point(15, 75);
5406 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5407 test_point, render_surface_layer_list);
5408 ASSERT_TRUE(result_layer);
5409 EXPECT_EQ(3, result_layer->id());
5410
5411 // Hit testing for a point inside the mousewheel layer should return it.
5412 test_point = gfx::Point(75, 75);
5413 result_layer = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
5414 test_point, render_surface_layer_list);
5415 ASSERT_TRUE(result_layer);
5416 EXPECT_EQ(4, result_layer->id());
5417 }
5418
TEST_F(LayerTreeHostCommonTest,HitCheckingTouchHandlerRegionsForEmptyLayerList)5419 TEST_F(LayerTreeHostCommonTest,
5420 HitCheckingTouchHandlerRegionsForEmptyLayerList) {
5421 // Hit checking on an empty render_surface_layer_list should return a null
5422 // pointer.
5423 LayerImplList render_surface_layer_list;
5424
5425 gfx::Point test_point(0, 0);
5426 LayerImpl* result_layer =
5427 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5428 test_point, render_surface_layer_list);
5429 EXPECT_FALSE(result_layer);
5430
5431 test_point = gfx::Point(10, 20);
5432 result_layer =
5433 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5434 test_point, render_surface_layer_list);
5435 EXPECT_FALSE(result_layer);
5436 }
5437
TEST_F(LayerTreeHostCommonTest,HitCheckingTouchHandlerRegionsForSingleLayer)5438 TEST_F(LayerTreeHostCommonTest, HitCheckingTouchHandlerRegionsForSingleLayer) {
5439 FakeImplProxy proxy;
5440 FakeLayerTreeHostImpl host_impl(&proxy);
5441 scoped_ptr<LayerImpl> root =
5442 LayerImpl::Create(host_impl.active_tree(), 12345);
5443
5444 gfx::Transform identity_matrix;
5445 Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
5446 gfx::PointF anchor;
5447 gfx::PointF position;
5448 gfx::Size bounds(100, 100);
5449 SetLayerPropertiesForTesting(root.get(),
5450 identity_matrix,
5451 identity_matrix,
5452 anchor,
5453 position,
5454 bounds,
5455 false);
5456 root->SetDrawsContent(true);
5457
5458 LayerImplList render_surface_layer_list;
5459 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5460 root.get(), root->bounds(), &render_surface_layer_list);
5461 inputs.can_adjust_raster_scales = true;
5462 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5463
5464 // Sanity check the scenario we just created.
5465 ASSERT_EQ(1u, render_surface_layer_list.size());
5466 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5467
5468 // Hit checking for any point should return a null pointer for a layer without
5469 // any touch event handler regions.
5470 gfx::Point test_point(11, 11);
5471 LayerImpl* result_layer =
5472 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5473 test_point, render_surface_layer_list);
5474 EXPECT_FALSE(result_layer);
5475
5476 root->SetTouchEventHandlerRegion(touch_handler_region);
5477 // Hit checking for a point outside the layer should return a null pointer.
5478 test_point = gfx::Point(101, 101);
5479 result_layer =
5480 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5481 test_point, render_surface_layer_list);
5482 EXPECT_FALSE(result_layer);
5483
5484 test_point = gfx::Point(-1, -1);
5485 result_layer =
5486 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5487 test_point, render_surface_layer_list);
5488 EXPECT_FALSE(result_layer);
5489
5490 // Hit checking for a point inside the layer, but outside the touch handler
5491 // region should return a null pointer.
5492 test_point = gfx::Point(1, 1);
5493 result_layer =
5494 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5495 test_point, render_surface_layer_list);
5496 EXPECT_FALSE(result_layer);
5497
5498 test_point = gfx::Point(99, 99);
5499 result_layer =
5500 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5501 test_point, render_surface_layer_list);
5502 EXPECT_FALSE(result_layer);
5503
5504 // Hit checking for a point inside the touch event handler region should
5505 // return the root layer.
5506 test_point = gfx::Point(11, 11);
5507 result_layer =
5508 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5509 test_point, render_surface_layer_list);
5510 ASSERT_TRUE(result_layer);
5511 EXPECT_EQ(12345, result_layer->id());
5512
5513 test_point = gfx::Point(59, 59);
5514 result_layer =
5515 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5516 test_point, render_surface_layer_list);
5517 ASSERT_TRUE(result_layer);
5518 EXPECT_EQ(12345, result_layer->id());
5519 }
5520
TEST_F(LayerTreeHostCommonTest,HitCheckingTouchHandlerRegionsForUninvertibleTransform)5521 TEST_F(LayerTreeHostCommonTest,
5522 HitCheckingTouchHandlerRegionsForUninvertibleTransform) {
5523 FakeImplProxy proxy;
5524 FakeLayerTreeHostImpl host_impl(&proxy);
5525 scoped_ptr<LayerImpl> root =
5526 LayerImpl::Create(host_impl.active_tree(), 12345);
5527
5528 gfx::Transform uninvertible_transform;
5529 uninvertible_transform.matrix().set(0, 0, 0.0);
5530 uninvertible_transform.matrix().set(1, 1, 0.0);
5531 uninvertible_transform.matrix().set(2, 2, 0.0);
5532 uninvertible_transform.matrix().set(3, 3, 0.0);
5533 ASSERT_FALSE(uninvertible_transform.IsInvertible());
5534
5535 gfx::Transform identity_matrix;
5536 Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
5537 gfx::PointF anchor;
5538 gfx::PointF position;
5539 gfx::Size bounds(100, 100);
5540 SetLayerPropertiesForTesting(root.get(),
5541 uninvertible_transform,
5542 identity_matrix,
5543 anchor,
5544 position,
5545 bounds,
5546 false);
5547 root->SetDrawsContent(true);
5548 root->SetTouchEventHandlerRegion(touch_handler_region);
5549
5550 LayerImplList render_surface_layer_list;
5551 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5552 root.get(), root->bounds(), &render_surface_layer_list);
5553 inputs.can_adjust_raster_scales = true;
5554 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5555
5556 // Sanity check the scenario we just created.
5557 ASSERT_EQ(1u, render_surface_layer_list.size());
5558 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5559 ASSERT_FALSE(root->screen_space_transform().IsInvertible());
5560
5561 // Hit checking any point should not hit the touch handler region on the
5562 // layer. If the invertible matrix is accidentally ignored and treated like an
5563 // identity, then the hit testing will incorrectly hit the layer when it
5564 // shouldn't.
5565 gfx::Point test_point(1, 1);
5566 LayerImpl* result_layer =
5567 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5568 test_point, render_surface_layer_list);
5569 EXPECT_FALSE(result_layer);
5570
5571 test_point = gfx::Point(10, 10);
5572 result_layer =
5573 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5574 test_point, render_surface_layer_list);
5575 EXPECT_FALSE(result_layer);
5576
5577 test_point = gfx::Point(10, 30);
5578 result_layer =
5579 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5580 test_point, render_surface_layer_list);
5581 EXPECT_FALSE(result_layer);
5582
5583 test_point = gfx::Point(50, 50);
5584 result_layer =
5585 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5586 test_point, render_surface_layer_list);
5587 EXPECT_FALSE(result_layer);
5588
5589 test_point = gfx::Point(67, 48);
5590 result_layer =
5591 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5592 test_point, render_surface_layer_list);
5593 EXPECT_FALSE(result_layer);
5594
5595 test_point = gfx::Point(99, 99);
5596 result_layer =
5597 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5598 test_point, render_surface_layer_list);
5599 EXPECT_FALSE(result_layer);
5600
5601 test_point = gfx::Point(-1, -1);
5602 result_layer =
5603 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5604 test_point, render_surface_layer_list);
5605 EXPECT_FALSE(result_layer);
5606 }
5607
TEST_F(LayerTreeHostCommonTest,HitCheckingTouchHandlerRegionsForSinglePositionedLayer)5608 TEST_F(LayerTreeHostCommonTest,
5609 HitCheckingTouchHandlerRegionsForSinglePositionedLayer) {
5610 FakeImplProxy proxy;
5611 FakeLayerTreeHostImpl host_impl(&proxy);
5612 scoped_ptr<LayerImpl> root =
5613 LayerImpl::Create(host_impl.active_tree(), 12345);
5614
5615 gfx::Transform identity_matrix;
5616 Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
5617 gfx::PointF anchor;
5618 // this layer is positioned, and hit testing should correctly know where the
5619 // layer is located.
5620 gfx::PointF position(50.f, 50.f);
5621 gfx::Size bounds(100, 100);
5622 SetLayerPropertiesForTesting(root.get(),
5623 identity_matrix,
5624 identity_matrix,
5625 anchor,
5626 position,
5627 bounds,
5628 false);
5629 root->SetDrawsContent(true);
5630 root->SetTouchEventHandlerRegion(touch_handler_region);
5631
5632 LayerImplList render_surface_layer_list;
5633 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5634 root.get(), root->bounds(), &render_surface_layer_list);
5635 inputs.can_adjust_raster_scales = true;
5636 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5637
5638 // Sanity check the scenario we just created.
5639 ASSERT_EQ(1u, render_surface_layer_list.size());
5640 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5641
5642 // Hit checking for a point outside the layer should return a null pointer.
5643 gfx::Point test_point(49, 49);
5644 LayerImpl* result_layer =
5645 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5646 test_point, render_surface_layer_list);
5647 EXPECT_FALSE(result_layer);
5648
5649 // Even though the layer has a touch handler region containing (101, 101), it
5650 // should not be visible there since the root render surface would clamp it.
5651 test_point = gfx::Point(101, 101);
5652 result_layer =
5653 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5654 test_point, render_surface_layer_list);
5655 EXPECT_FALSE(result_layer);
5656
5657 // Hit checking for a point inside the layer, but outside the touch handler
5658 // region should return a null pointer.
5659 test_point = gfx::Point(51, 51);
5660 result_layer =
5661 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5662 test_point, render_surface_layer_list);
5663 EXPECT_FALSE(result_layer);
5664
5665 // Hit checking for a point inside the touch event handler region should
5666 // return the root layer.
5667 test_point = gfx::Point(61, 61);
5668 result_layer =
5669 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5670 test_point, render_surface_layer_list);
5671 ASSERT_TRUE(result_layer);
5672 EXPECT_EQ(12345, result_layer->id());
5673
5674 test_point = gfx::Point(99, 99);
5675 result_layer =
5676 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5677 test_point, render_surface_layer_list);
5678 ASSERT_TRUE(result_layer);
5679 EXPECT_EQ(12345, result_layer->id());
5680 }
5681
TEST_F(LayerTreeHostCommonTest,HitCheckingTouchHandlerRegionsForSingleLayerWithScaledContents)5682 TEST_F(LayerTreeHostCommonTest,
5683 HitCheckingTouchHandlerRegionsForSingleLayerWithScaledContents) {
5684 // A layer's visible content rect is actually in the layer's content space.
5685 // The screen space transform converts from the layer's origin space to screen
5686 // space. This test makes sure that hit testing works correctly accounts for
5687 // the contents scale. A contents scale that is not 1 effectively forces a
5688 // non-identity transform between layer's content space and layer's origin
5689 // space. The hit testing code must take this into account.
5690 //
5691 // To test this, the layer is positioned at (25, 25), and is size (50, 50). If
5692 // contents scale is ignored, then hit checking will mis-interpret the visible
5693 // content rect as being larger than the actual bounds of the layer.
5694 //
5695 FakeImplProxy proxy;
5696 FakeLayerTreeHostImpl host_impl(&proxy);
5697 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5698
5699 gfx::Transform identity_matrix;
5700 gfx::PointF anchor;
5701
5702 SetLayerPropertiesForTesting(root.get(),
5703 identity_matrix,
5704 identity_matrix,
5705 anchor,
5706 gfx::PointF(),
5707 gfx::Size(100, 100),
5708 false);
5709 {
5710 Region touch_handler_region(gfx::Rect(10, 10, 30, 30));
5711 gfx::PointF position(25.f, 25.f);
5712 gfx::Size bounds(50, 50);
5713 scoped_ptr<LayerImpl> test_layer =
5714 LayerImpl::Create(host_impl.active_tree(), 12345);
5715 SetLayerPropertiesForTesting(test_layer.get(),
5716 identity_matrix,
5717 identity_matrix,
5718 anchor,
5719 position,
5720 bounds,
5721 false);
5722
5723 // override content bounds and contents scale
5724 test_layer->SetContentBounds(gfx::Size(100, 100));
5725 test_layer->SetContentsScale(2, 2);
5726
5727 test_layer->SetDrawsContent(true);
5728 test_layer->SetTouchEventHandlerRegion(touch_handler_region);
5729 root->AddChild(test_layer.Pass());
5730 }
5731
5732 LayerImplList render_surface_layer_list;
5733 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5734 root.get(), root->bounds(), &render_surface_layer_list);
5735 inputs.can_adjust_raster_scales = true;
5736 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5737
5738 // Sanity check the scenario we just created.
5739 // The visible content rect for test_layer is actually 100x100, even though
5740 // its layout size is 50x50, positioned at 25x25.
5741 LayerImpl* test_layer = root->children()[0];
5742 EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), test_layer->visible_content_rect());
5743 ASSERT_EQ(1u, render_surface_layer_list.size());
5744 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5745
5746 // Hit checking for a point outside the layer should return a null pointer
5747 // (the root layer does not draw content, so it will not be tested either).
5748 gfx::Point test_point(76, 76);
5749 LayerImpl* result_layer =
5750 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5751 test_point, render_surface_layer_list);
5752 EXPECT_FALSE(result_layer);
5753
5754 // Hit checking for a point inside the layer, but outside the touch handler
5755 // region should return a null pointer.
5756 test_point = gfx::Point(26, 26);
5757 result_layer =
5758 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5759 test_point, render_surface_layer_list);
5760 EXPECT_FALSE(result_layer);
5761
5762 test_point = gfx::Point(34, 34);
5763 result_layer =
5764 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5765 test_point, render_surface_layer_list);
5766 EXPECT_FALSE(result_layer);
5767
5768 test_point = gfx::Point(65, 65);
5769 result_layer =
5770 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5771 test_point, render_surface_layer_list);
5772 EXPECT_FALSE(result_layer);
5773
5774 test_point = gfx::Point(74, 74);
5775 result_layer =
5776 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5777 test_point, render_surface_layer_list);
5778 EXPECT_FALSE(result_layer);
5779
5780 // Hit checking for a point inside the touch event handler region should
5781 // return the root layer.
5782 test_point = gfx::Point(35, 35);
5783 result_layer =
5784 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5785 test_point, render_surface_layer_list);
5786 ASSERT_TRUE(result_layer);
5787 EXPECT_EQ(12345, result_layer->id());
5788
5789 test_point = gfx::Point(64, 64);
5790 result_layer =
5791 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5792 test_point, render_surface_layer_list);
5793 ASSERT_TRUE(result_layer);
5794 EXPECT_EQ(12345, result_layer->id());
5795 }
5796
TEST_F(LayerTreeHostCommonTest,HitCheckingTouchHandlerRegionsForSingleLayerWithDeviceScale)5797 TEST_F(LayerTreeHostCommonTest,
5798 HitCheckingTouchHandlerRegionsForSingleLayerWithDeviceScale) {
5799 // The layer's device_scale_factor and page_scale_factor should scale the
5800 // content rect and we should be able to hit the touch handler region by
5801 // scaling the points accordingly.
5802 FakeImplProxy proxy;
5803 FakeLayerTreeHostImpl host_impl(&proxy);
5804 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5805
5806 gfx::Transform identity_matrix;
5807 gfx::PointF anchor;
5808 // Set the bounds of the root layer big enough to fit the child when scaled.
5809 SetLayerPropertiesForTesting(root.get(),
5810 identity_matrix,
5811 identity_matrix,
5812 anchor,
5813 gfx::PointF(),
5814 gfx::Size(100, 100),
5815 false);
5816 {
5817 Region touch_handler_region(gfx::Rect(10, 10, 30, 30));
5818 gfx::PointF position(25.f, 25.f);
5819 gfx::Size bounds(50, 50);
5820 scoped_ptr<LayerImpl> test_layer =
5821 LayerImpl::Create(host_impl.active_tree(), 12345);
5822 SetLayerPropertiesForTesting(test_layer.get(),
5823 identity_matrix,
5824 identity_matrix,
5825 anchor,
5826 position,
5827 bounds,
5828 false);
5829
5830 test_layer->SetDrawsContent(true);
5831 test_layer->SetTouchEventHandlerRegion(touch_handler_region);
5832 root->AddChild(test_layer.Pass());
5833 }
5834
5835 LayerImplList render_surface_layer_list;
5836 float device_scale_factor = 3.f;
5837 float page_scale_factor = 5.f;
5838 gfx::Size scaled_bounds_for_root = gfx::ToCeiledSize(
5839 gfx::ScaleSize(root->bounds(), device_scale_factor * page_scale_factor));
5840
5841 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5842 root.get(), scaled_bounds_for_root, &render_surface_layer_list);
5843 inputs.device_scale_factor = device_scale_factor;
5844 inputs.page_scale_factor = page_scale_factor;
5845 inputs.page_scale_application_layer = root.get();
5846 inputs.can_adjust_raster_scales = true;
5847 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5848
5849 // Sanity check the scenario we just created.
5850 // The visible content rect for test_layer is actually 100x100, even though
5851 // its layout size is 50x50, positioned at 25x25.
5852 LayerImpl* test_layer = root->children()[0];
5853 ASSERT_EQ(1u, render_surface_layer_list.size());
5854 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5855
5856 // Check whether the child layer fits into the root after scaled.
5857 EXPECT_RECT_EQ(gfx::Rect(test_layer->content_bounds()),
5858 test_layer->visible_content_rect());
5859
5860 // Hit checking for a point outside the layer should return a null pointer
5861 // (the root layer does not draw content, so it will not be tested either).
5862 gfx::PointF test_point(76.f, 76.f);
5863 test_point =
5864 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5865 LayerImpl* result_layer =
5866 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5867 test_point, render_surface_layer_list);
5868 EXPECT_FALSE(result_layer);
5869
5870 // Hit checking for a point inside the layer, but outside the touch handler
5871 // region should return a null pointer.
5872 test_point = gfx::Point(26, 26);
5873 test_point =
5874 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5875 result_layer =
5876 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5877 test_point, render_surface_layer_list);
5878 EXPECT_FALSE(result_layer);
5879
5880 test_point = gfx::Point(34, 34);
5881 test_point =
5882 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5883 result_layer =
5884 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5885 test_point, render_surface_layer_list);
5886 EXPECT_FALSE(result_layer);
5887
5888 test_point = gfx::Point(65, 65);
5889 test_point =
5890 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5891 result_layer =
5892 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5893 test_point, render_surface_layer_list);
5894 EXPECT_FALSE(result_layer);
5895
5896 test_point = gfx::Point(74, 74);
5897 test_point =
5898 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5899 result_layer =
5900 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5901 test_point, render_surface_layer_list);
5902 EXPECT_FALSE(result_layer);
5903
5904 // Hit checking for a point inside the touch event handler region should
5905 // return the root layer.
5906 test_point = gfx::Point(35, 35);
5907 test_point =
5908 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5909 result_layer =
5910 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5911 test_point, render_surface_layer_list);
5912 ASSERT_TRUE(result_layer);
5913 EXPECT_EQ(12345, result_layer->id());
5914
5915 test_point = gfx::Point(64, 64);
5916 test_point =
5917 gfx::ScalePoint(test_point, device_scale_factor * page_scale_factor);
5918 result_layer =
5919 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5920 test_point, render_surface_layer_list);
5921 ASSERT_TRUE(result_layer);
5922 EXPECT_EQ(12345, result_layer->id());
5923 }
5924
TEST_F(LayerTreeHostCommonTest,HitCheckingTouchHandlerRegionsForSimpleClippedLayer)5925 TEST_F(LayerTreeHostCommonTest,
5926 HitCheckingTouchHandlerRegionsForSimpleClippedLayer) {
5927 // Test that hit-checking will only work for the visible portion of a layer,
5928 // and not the entire layer bounds. Here we just test the simple axis-aligned
5929 // case.
5930 gfx::Transform identity_matrix;
5931 gfx::PointF anchor;
5932
5933 FakeImplProxy proxy;
5934 FakeLayerTreeHostImpl host_impl(&proxy);
5935 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
5936 SetLayerPropertiesForTesting(root.get(),
5937 identity_matrix,
5938 identity_matrix,
5939 anchor,
5940 gfx::PointF(),
5941 gfx::Size(100, 100),
5942 false);
5943 {
5944 scoped_ptr<LayerImpl> clipping_layer =
5945 LayerImpl::Create(host_impl.active_tree(), 123);
5946 // this layer is positioned, and hit testing should correctly know where the
5947 // layer is located.
5948 gfx::PointF position(25.f, 25.f);
5949 gfx::Size bounds(50, 50);
5950 SetLayerPropertiesForTesting(clipping_layer.get(),
5951 identity_matrix,
5952 identity_matrix,
5953 anchor,
5954 position,
5955 bounds,
5956 false);
5957 clipping_layer->SetMasksToBounds(true);
5958
5959 scoped_ptr<LayerImpl> child =
5960 LayerImpl::Create(host_impl.active_tree(), 456);
5961 Region touch_handler_region(gfx::Rect(10, 10, 50, 50));
5962 position = gfx::PointF(-50.f, -50.f);
5963 bounds = gfx::Size(300, 300);
5964 SetLayerPropertiesForTesting(child.get(),
5965 identity_matrix,
5966 identity_matrix,
5967 anchor,
5968 position,
5969 bounds,
5970 false);
5971 child->SetDrawsContent(true);
5972 child->SetTouchEventHandlerRegion(touch_handler_region);
5973 clipping_layer->AddChild(child.Pass());
5974 root->AddChild(clipping_layer.Pass());
5975 }
5976
5977 LayerImplList render_surface_layer_list;
5978 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
5979 root.get(), root->bounds(), &render_surface_layer_list);
5980 inputs.can_adjust_raster_scales = true;
5981 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
5982
5983 // Sanity check the scenario we just created.
5984 ASSERT_EQ(1u, render_surface_layer_list.size());
5985 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
5986 ASSERT_EQ(456, root->render_surface()->layer_list().at(0)->id());
5987
5988 // Hit checking for a point outside the layer should return a null pointer.
5989 // Despite the child layer being very large, it should be clipped to the root
5990 // layer's bounds.
5991 gfx::Point test_point(24, 24);
5992 LayerImpl* result_layer =
5993 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
5994 test_point, render_surface_layer_list);
5995 EXPECT_FALSE(result_layer);
5996
5997 // Hit checking for a point inside the layer, but outside the touch handler
5998 // region should return a null pointer.
5999 test_point = gfx::Point(35, 35);
6000 result_layer =
6001 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6002 test_point, render_surface_layer_list);
6003 EXPECT_FALSE(result_layer);
6004
6005 test_point = gfx::Point(74, 74);
6006 result_layer =
6007 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6008 test_point, render_surface_layer_list);
6009 EXPECT_FALSE(result_layer);
6010
6011 // Hit checking for a point inside the touch event handler region should
6012 // return the root layer.
6013 test_point = gfx::Point(25, 25);
6014 result_layer =
6015 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6016 test_point, render_surface_layer_list);
6017 ASSERT_TRUE(result_layer);
6018 EXPECT_EQ(456, result_layer->id());
6019
6020 test_point = gfx::Point(34, 34);
6021 result_layer =
6022 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6023 test_point, render_surface_layer_list);
6024 ASSERT_TRUE(result_layer);
6025 EXPECT_EQ(456, result_layer->id());
6026 }
6027
TEST_F(LayerTreeHostCommonTest,HitCheckingTouchHandlerOverlappingRegions)6028 TEST_F(LayerTreeHostCommonTest,
6029 HitCheckingTouchHandlerOverlappingRegions) {
6030 gfx::Transform identity_matrix;
6031 gfx::PointF anchor;
6032
6033 FakeImplProxy proxy;
6034 FakeLayerTreeHostImpl host_impl(&proxy);
6035 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
6036 SetLayerPropertiesForTesting(root.get(),
6037 identity_matrix,
6038 identity_matrix,
6039 anchor,
6040 gfx::PointF(),
6041 gfx::Size(100, 100),
6042 false);
6043 {
6044 scoped_ptr<LayerImpl> touch_layer =
6045 LayerImpl::Create(host_impl.active_tree(), 123);
6046 // this layer is positioned, and hit testing should correctly know where the
6047 // layer is located.
6048 gfx::PointF position;
6049 gfx::Size bounds(50, 50);
6050 SetLayerPropertiesForTesting(touch_layer.get(),
6051 identity_matrix,
6052 identity_matrix,
6053 anchor,
6054 position,
6055 bounds,
6056 false);
6057 touch_layer->SetDrawsContent(true);
6058 touch_layer->SetTouchEventHandlerRegion(gfx::Rect(0, 0, 50, 50));
6059 root->AddChild(touch_layer.Pass());
6060 }
6061
6062 {
6063 scoped_ptr<LayerImpl> notouch_layer =
6064 LayerImpl::Create(host_impl.active_tree(), 1234);
6065 // this layer is positioned, and hit testing should correctly know where the
6066 // layer is located.
6067 gfx::PointF position(0, 25);
6068 gfx::Size bounds(50, 50);
6069 SetLayerPropertiesForTesting(notouch_layer.get(),
6070 identity_matrix,
6071 identity_matrix,
6072 anchor,
6073 position,
6074 bounds,
6075 false);
6076 notouch_layer->SetDrawsContent(true);
6077 root->AddChild(notouch_layer.Pass());
6078 }
6079
6080 LayerImplList render_surface_layer_list;
6081 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
6082 root.get(), root->bounds(), &render_surface_layer_list);
6083 inputs.can_adjust_raster_scales = true;
6084 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6085
6086 // Sanity check the scenario we just created.
6087 ASSERT_EQ(1u, render_surface_layer_list.size());
6088 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
6089 ASSERT_EQ(123, root->render_surface()->layer_list().at(0)->id());
6090 ASSERT_EQ(1234, root->render_surface()->layer_list().at(1)->id());
6091
6092 gfx::Point test_point(35, 35);
6093 LayerImpl* result_layer =
6094 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6095 test_point, render_surface_layer_list);
6096 EXPECT_FALSE(result_layer);
6097
6098 test_point = gfx::Point(35, 15);
6099 result_layer =
6100 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6101 test_point, render_surface_layer_list);
6102 ASSERT_TRUE(result_layer);
6103 EXPECT_EQ(123, result_layer->id());
6104
6105 test_point = gfx::Point(35, 65);
6106 result_layer =
6107 LayerTreeHostCommon::FindLayerThatIsHitByPointInTouchHandlerRegion(
6108 test_point, render_surface_layer_list);
6109 EXPECT_FALSE(result_layer);
6110 }
6111
6112 class NoScaleContentLayer : public ContentLayer {
6113 public:
Create(ContentLayerClient * client)6114 static scoped_refptr<NoScaleContentLayer> Create(ContentLayerClient* client) {
6115 return make_scoped_refptr(new NoScaleContentLayer(client));
6116 }
6117
CalculateContentsScale(float ideal_contents_scale,float device_scale_factor,float page_scale_factor,bool animating_transform_to_screen,float * contents_scale_x,float * contents_scale_y,gfx::Size * content_bounds)6118 virtual void CalculateContentsScale(float ideal_contents_scale,
6119 float device_scale_factor,
6120 float page_scale_factor,
6121 bool animating_transform_to_screen,
6122 float* contents_scale_x,
6123 float* contents_scale_y,
6124 gfx::Size* content_bounds) OVERRIDE {
6125 // Skip over the ContentLayer to the base Layer class.
6126 Layer::CalculateContentsScale(ideal_contents_scale,
6127 device_scale_factor,
6128 page_scale_factor,
6129 animating_transform_to_screen,
6130 contents_scale_x,
6131 contents_scale_y,
6132 content_bounds);
6133 }
6134
6135 protected:
NoScaleContentLayer(ContentLayerClient * client)6136 explicit NoScaleContentLayer(ContentLayerClient* client)
6137 : ContentLayer(client) {}
~NoScaleContentLayer()6138 virtual ~NoScaleContentLayer() {}
6139 };
6140
CreateNoScaleDrawableContentLayer(ContentLayerClient * delegate)6141 scoped_refptr<NoScaleContentLayer> CreateNoScaleDrawableContentLayer(
6142 ContentLayerClient* delegate) {
6143 scoped_refptr<NoScaleContentLayer> to_return =
6144 NoScaleContentLayer::Create(delegate);
6145 to_return->SetIsDrawable(true);
6146 return to_return;
6147 }
6148
TEST_F(LayerTreeHostCommonTest,LayerTransformsInHighDPI)6149 TEST_F(LayerTreeHostCommonTest, LayerTransformsInHighDPI) {
6150 // Verify draw and screen space transforms of layers not in a surface.
6151 MockContentLayerClient delegate;
6152 gfx::Transform identity_matrix;
6153
6154 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
6155 SetLayerPropertiesForTesting(parent.get(),
6156 identity_matrix,
6157 identity_matrix,
6158 gfx::PointF(),
6159 gfx::PointF(),
6160 gfx::Size(100, 100),
6161 true);
6162
6163 scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate);
6164 SetLayerPropertiesForTesting(child.get(),
6165 identity_matrix,
6166 identity_matrix,
6167 gfx::PointF(),
6168 gfx::PointF(2.f, 2.f),
6169 gfx::Size(10, 10),
6170 true);
6171
6172 scoped_refptr<ContentLayer> child_empty =
6173 CreateDrawableContentLayer(&delegate);
6174 SetLayerPropertiesForTesting(child_empty.get(),
6175 identity_matrix,
6176 identity_matrix,
6177 gfx::PointF(),
6178 gfx::PointF(2.f, 2.f),
6179 gfx::Size(),
6180 true);
6181
6182 scoped_refptr<NoScaleContentLayer> child_no_scale =
6183 CreateNoScaleDrawableContentLayer(&delegate);
6184 SetLayerPropertiesForTesting(child_no_scale.get(),
6185 identity_matrix,
6186 identity_matrix,
6187 gfx::PointF(),
6188 gfx::PointF(2.f, 2.f),
6189 gfx::Size(10, 10),
6190 true);
6191
6192 parent->AddChild(child);
6193 parent->AddChild(child_empty);
6194 parent->AddChild(child_no_scale);
6195
6196 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
6197 host->SetRootLayer(parent);
6198
6199 float device_scale_factor = 2.5f;
6200 float page_scale_factor = 1.f;
6201
6202 RenderSurfaceLayerList render_surface_layer_list;
6203 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6204 parent.get(), parent->bounds(), &render_surface_layer_list);
6205 inputs.device_scale_factor = device_scale_factor;
6206 inputs.page_scale_factor = page_scale_factor;
6207 inputs.can_adjust_raster_scales = true;
6208 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6209
6210 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
6211 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, child);
6212 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
6213 child_empty);
6214 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
6215
6216 EXPECT_EQ(1u, render_surface_layer_list.size());
6217
6218 // Verify parent transforms
6219 gfx::Transform expected_parent_transform;
6220 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
6221 parent->screen_space_transform());
6222 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
6223 parent->draw_transform());
6224
6225 // Verify results of transformed parent rects
6226 gfx::RectF parent_content_bounds(parent->content_bounds());
6227
6228 gfx::RectF parent_draw_rect =
6229 MathUtil::MapClippedRect(parent->draw_transform(), parent_content_bounds);
6230 gfx::RectF parent_screen_space_rect = MathUtil::MapClippedRect(
6231 parent->screen_space_transform(), parent_content_bounds);
6232
6233 gfx::RectF expected_parent_draw_rect(parent->bounds());
6234 expected_parent_draw_rect.Scale(device_scale_factor);
6235 EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_draw_rect);
6236 EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_screen_space_rect);
6237
6238 // Verify child and child_empty transforms. They should match.
6239 gfx::Transform expected_child_transform;
6240 expected_child_transform.Translate(
6241 device_scale_factor * child->position().x(),
6242 device_scale_factor * child->position().y());
6243 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
6244 child->draw_transform());
6245 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
6246 child->screen_space_transform());
6247 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
6248 child_empty->draw_transform());
6249 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
6250 child_empty->screen_space_transform());
6251
6252 // Verify results of transformed child and child_empty rects. They should
6253 // match.
6254 gfx::RectF child_content_bounds(child->content_bounds());
6255
6256 gfx::RectF child_draw_rect =
6257 MathUtil::MapClippedRect(child->draw_transform(), child_content_bounds);
6258 gfx::RectF child_screen_space_rect = MathUtil::MapClippedRect(
6259 child->screen_space_transform(), child_content_bounds);
6260
6261 gfx::RectF child_empty_draw_rect = MathUtil::MapClippedRect(
6262 child_empty->draw_transform(), child_content_bounds);
6263 gfx::RectF child_empty_screen_space_rect = MathUtil::MapClippedRect(
6264 child_empty->screen_space_transform(), child_content_bounds);
6265
6266 gfx::RectF expected_child_draw_rect(child->position(), child->bounds());
6267 expected_child_draw_rect.Scale(device_scale_factor);
6268 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect);
6269 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect);
6270 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_empty_draw_rect);
6271 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_empty_screen_space_rect);
6272
6273 // Verify child_no_scale transforms
6274 gfx::Transform expected_child_no_scale_transform = child->draw_transform();
6275 // All transforms operate on content rects. The child's content rect
6276 // incorporates device scale, but the child_no_scale does not; add it here.
6277 expected_child_no_scale_transform.Scale(device_scale_factor,
6278 device_scale_factor);
6279 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform,
6280 child_no_scale->draw_transform());
6281 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform,
6282 child_no_scale->screen_space_transform());
6283 }
6284
TEST_F(LayerTreeHostCommonTest,SurfaceLayerTransformsInHighDPI)6285 TEST_F(LayerTreeHostCommonTest, SurfaceLayerTransformsInHighDPI) {
6286 // Verify draw and screen space transforms of layers in a surface.
6287 MockContentLayerClient delegate;
6288 gfx::Transform identity_matrix;
6289
6290 gfx::Transform perspective_matrix;
6291 perspective_matrix.ApplyPerspectiveDepth(2.0);
6292
6293 gfx::Transform scale_small_matrix;
6294 scale_small_matrix.Scale(SK_MScalar1 / 10.f, SK_MScalar1 / 12.f);
6295
6296 scoped_refptr<Layer> root = Layer::Create();
6297
6298 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
6299 SetLayerPropertiesForTesting(parent.get(),
6300 identity_matrix,
6301 identity_matrix,
6302 gfx::PointF(),
6303 gfx::PointF(),
6304 gfx::Size(100, 100),
6305 true);
6306
6307 scoped_refptr<ContentLayer> perspective_surface =
6308 CreateDrawableContentLayer(&delegate);
6309 SetLayerPropertiesForTesting(perspective_surface.get(),
6310 perspective_matrix * scale_small_matrix,
6311 identity_matrix,
6312 gfx::PointF(),
6313 gfx::PointF(2.f, 2.f),
6314 gfx::Size(10, 10),
6315 true);
6316
6317 scoped_refptr<ContentLayer> scale_surface =
6318 CreateDrawableContentLayer(&delegate);
6319 SetLayerPropertiesForTesting(scale_surface.get(),
6320 scale_small_matrix,
6321 identity_matrix,
6322 gfx::PointF(),
6323 gfx::PointF(2.f, 2.f),
6324 gfx::Size(10, 10),
6325 true);
6326
6327 perspective_surface->SetForceRenderSurface(true);
6328 scale_surface->SetForceRenderSurface(true);
6329
6330 parent->AddChild(perspective_surface);
6331 parent->AddChild(scale_surface);
6332 root->AddChild(parent);
6333
6334 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
6335 host->SetRootLayer(root);
6336
6337 float device_scale_factor = 2.5f;
6338 float page_scale_factor = 3.f;
6339
6340 RenderSurfaceLayerList render_surface_layer_list;
6341 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6342 root.get(), parent->bounds(), &render_surface_layer_list);
6343 inputs.device_scale_factor = device_scale_factor;
6344 inputs.page_scale_factor = page_scale_factor;
6345 inputs.page_scale_application_layer = root;
6346 inputs.can_adjust_raster_scales = true;
6347 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6348
6349 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
6350 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
6351 perspective_surface);
6352 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
6353 scale_surface);
6354
6355 EXPECT_EQ(3u, render_surface_layer_list.size());
6356
6357 gfx::Transform expected_parent_draw_transform;
6358 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_draw_transform,
6359 parent->draw_transform());
6360
6361 // The scaled surface is rendered at its appropriate scale, and drawn 1:1
6362 // into its target.
6363 gfx::Transform expected_scale_surface_draw_transform;
6364 expected_scale_surface_draw_transform.Translate(
6365 device_scale_factor * page_scale_factor * scale_surface->position().x(),
6366 device_scale_factor * page_scale_factor * scale_surface->position().y());
6367 EXPECT_TRANSFORMATION_MATRIX_EQ(
6368 expected_scale_surface_draw_transform,
6369 scale_surface->render_surface()->draw_transform());
6370 gfx::Transform expected_scale_surface_layer_draw_transform =
6371 scale_small_matrix;
6372 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scale_surface_layer_draw_transform,
6373 scale_surface->draw_transform());
6374
6375 // The scale for the perspective surface is not known, so it is rendered 1:1
6376 // with the screen, and then scaled during drawing.
6377 gfx::Transform expected_perspective_surface_draw_transform;
6378 expected_perspective_surface_draw_transform.Translate(
6379 device_scale_factor * page_scale_factor *
6380 perspective_surface->position().x(),
6381 device_scale_factor * page_scale_factor *
6382 perspective_surface->position().y());
6383 expected_perspective_surface_draw_transform.PreconcatTransform(
6384 perspective_matrix);
6385 expected_perspective_surface_draw_transform.PreconcatTransform(
6386 scale_small_matrix);
6387 gfx::Transform expected_perspective_surface_layer_draw_transform;
6388 EXPECT_TRANSFORMATION_MATRIX_EQ(
6389 expected_perspective_surface_draw_transform,
6390 perspective_surface->render_surface()->draw_transform());
6391 EXPECT_TRANSFORMATION_MATRIX_EQ(
6392 expected_perspective_surface_layer_draw_transform,
6393 perspective_surface->draw_transform());
6394 }
6395
TEST_F(LayerTreeHostCommonTest,LayerTransformsInHighDPIAccurateScaleZeroChildPosition)6396 TEST_F(LayerTreeHostCommonTest,
6397 LayerTransformsInHighDPIAccurateScaleZeroChildPosition) {
6398 // Verify draw and screen space transforms of layers not in a surface.
6399 MockContentLayerClient delegate;
6400 gfx::Transform identity_matrix;
6401
6402 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
6403 SetLayerPropertiesForTesting(parent.get(),
6404 identity_matrix,
6405 identity_matrix,
6406 gfx::PointF(),
6407 gfx::PointF(),
6408 gfx::Size(133, 133),
6409 true);
6410
6411 scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate);
6412 SetLayerPropertiesForTesting(child.get(),
6413 identity_matrix,
6414 identity_matrix,
6415 gfx::PointF(),
6416 gfx::PointF(),
6417 gfx::Size(13, 13),
6418 true);
6419
6420 scoped_refptr<NoScaleContentLayer> child_no_scale =
6421 CreateNoScaleDrawableContentLayer(&delegate);
6422 SetLayerPropertiesForTesting(child_no_scale.get(),
6423 identity_matrix,
6424 identity_matrix,
6425 gfx::PointF(),
6426 gfx::PointF(),
6427 gfx::Size(13, 13),
6428 true);
6429
6430 parent->AddChild(child);
6431 parent->AddChild(child_no_scale);
6432
6433 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
6434 host->SetRootLayer(parent);
6435
6436 float device_scale_factor = 1.7f;
6437 float page_scale_factor = 1.f;
6438
6439 RenderSurfaceLayerList render_surface_layer_list;
6440 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6441 parent.get(), parent->bounds(), &render_surface_layer_list);
6442 inputs.device_scale_factor = device_scale_factor;
6443 inputs.page_scale_factor = page_scale_factor;
6444 inputs.page_scale_application_layer = parent.get();
6445 inputs.can_adjust_raster_scales = true;
6446 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6447
6448 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
6449 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, child);
6450 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
6451
6452 EXPECT_EQ(1u, render_surface_layer_list.size());
6453
6454 // Verify parent transforms
6455 gfx::Transform expected_parent_transform;
6456 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
6457 parent->screen_space_transform());
6458 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
6459 parent->draw_transform());
6460
6461 // Verify results of transformed parent rects
6462 gfx::RectF parent_content_bounds(parent->content_bounds());
6463
6464 gfx::RectF parent_draw_rect =
6465 MathUtil::MapClippedRect(parent->draw_transform(), parent_content_bounds);
6466 gfx::RectF parent_screen_space_rect = MathUtil::MapClippedRect(
6467 parent->screen_space_transform(), parent_content_bounds);
6468
6469 gfx::RectF expected_parent_draw_rect(parent->bounds());
6470 expected_parent_draw_rect.Scale(device_scale_factor);
6471 expected_parent_draw_rect.set_width(ceil(expected_parent_draw_rect.width()));
6472 expected_parent_draw_rect.set_height(
6473 ceil(expected_parent_draw_rect.height()));
6474 EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_draw_rect);
6475 EXPECT_FLOAT_RECT_EQ(expected_parent_draw_rect, parent_screen_space_rect);
6476
6477 // Verify child transforms
6478 gfx::Transform expected_child_transform;
6479 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
6480 child->draw_transform());
6481 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
6482 child->screen_space_transform());
6483
6484 // Verify results of transformed child rects
6485 gfx::RectF child_content_bounds(child->content_bounds());
6486
6487 gfx::RectF child_draw_rect =
6488 MathUtil::MapClippedRect(child->draw_transform(), child_content_bounds);
6489 gfx::RectF child_screen_space_rect = MathUtil::MapClippedRect(
6490 child->screen_space_transform(), child_content_bounds);
6491
6492 gfx::RectF expected_child_draw_rect(child->bounds());
6493 expected_child_draw_rect.Scale(device_scale_factor);
6494 expected_child_draw_rect.set_width(ceil(expected_child_draw_rect.width()));
6495 expected_child_draw_rect.set_height(ceil(expected_child_draw_rect.height()));
6496 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect);
6497 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect);
6498
6499 // Verify child_no_scale transforms
6500 gfx::Transform expected_child_no_scale_transform = child->draw_transform();
6501 // All transforms operate on content rects. The child's content rect
6502 // incorporates device scale, but the child_no_scale does not; add it here.
6503 expected_child_no_scale_transform.Scale(device_scale_factor,
6504 device_scale_factor);
6505 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform,
6506 child_no_scale->draw_transform());
6507 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_no_scale_transform,
6508 child_no_scale->screen_space_transform());
6509 }
6510
TEST_F(LayerTreeHostCommonTest,ContentsScale)6511 TEST_F(LayerTreeHostCommonTest, ContentsScale) {
6512 MockContentLayerClient delegate;
6513 gfx::Transform identity_matrix;
6514
6515 gfx::Transform parent_scale_matrix;
6516 SkMScalar initial_parent_scale = 1.75;
6517 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
6518
6519 gfx::Transform child_scale_matrix;
6520 SkMScalar initial_child_scale = 1.25;
6521 child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
6522
6523 scoped_refptr<Layer> root = Layer::Create();
6524 root->SetBounds(gfx::Size(100, 100));
6525
6526 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
6527 SetLayerPropertiesForTesting(parent.get(),
6528 parent_scale_matrix,
6529 identity_matrix,
6530 gfx::PointF(),
6531 gfx::PointF(),
6532 gfx::Size(100, 100),
6533 true);
6534
6535 scoped_refptr<ContentLayer> child_scale =
6536 CreateDrawableContentLayer(&delegate);
6537 SetLayerPropertiesForTesting(child_scale.get(),
6538 child_scale_matrix,
6539 identity_matrix,
6540 gfx::PointF(),
6541 gfx::PointF(2.f, 2.f),
6542 gfx::Size(10, 10),
6543 true);
6544
6545 scoped_refptr<ContentLayer> child_empty =
6546 CreateDrawableContentLayer(&delegate);
6547 SetLayerPropertiesForTesting(child_empty.get(),
6548 child_scale_matrix,
6549 identity_matrix,
6550 gfx::PointF(),
6551 gfx::PointF(2.f, 2.f),
6552 gfx::Size(),
6553 true);
6554
6555 scoped_refptr<NoScaleContentLayer> child_no_scale =
6556 CreateNoScaleDrawableContentLayer(&delegate);
6557 SetLayerPropertiesForTesting(child_no_scale.get(),
6558 child_scale_matrix,
6559 identity_matrix,
6560 gfx::PointF(),
6561 gfx::PointF(12.f, 12.f),
6562 gfx::Size(10, 10),
6563 true);
6564
6565 root->AddChild(parent);
6566
6567 parent->AddChild(child_scale);
6568 parent->AddChild(child_empty);
6569 parent->AddChild(child_no_scale);
6570
6571 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
6572 host->SetRootLayer(root);
6573
6574 float device_scale_factor = 2.5f;
6575 float page_scale_factor = 1.f;
6576
6577 {
6578 RenderSurfaceLayerList render_surface_layer_list;
6579 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6580 root.get(), root->bounds(), &render_surface_layer_list);
6581 inputs.device_scale_factor = device_scale_factor;
6582 inputs.page_scale_factor = page_scale_factor;
6583 inputs.page_scale_application_layer = root.get();
6584 inputs.can_adjust_raster_scales = true;
6585 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6586
6587 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6588 initial_parent_scale, parent);
6589 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6590 initial_parent_scale * initial_child_scale,
6591 child_scale);
6592 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6593 initial_parent_scale * initial_child_scale,
6594 child_empty);
6595 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
6596
6597 // The parent is scaled up and shouldn't need to scale during draw. The
6598 // child that can scale its contents should also not need to scale during
6599 // draw. This shouldn't change if the child has empty bounds. The other
6600 // children should.
6601 EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(0, 0));
6602 EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(1, 1));
6603 EXPECT_FLOAT_EQ(1.0, child_scale->draw_transform().matrix().get(0, 0));
6604 EXPECT_FLOAT_EQ(1.0, child_scale->draw_transform().matrix().get(1, 1));
6605 EXPECT_FLOAT_EQ(1.0, child_empty->draw_transform().matrix().get(0, 0));
6606 EXPECT_FLOAT_EQ(1.0, child_empty->draw_transform().matrix().get(1, 1));
6607 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
6608 initial_parent_scale * initial_child_scale,
6609 child_no_scale->draw_transform().matrix().get(0, 0));
6610 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
6611 initial_parent_scale * initial_child_scale,
6612 child_no_scale->draw_transform().matrix().get(1, 1));
6613 }
6614
6615 // If the device_scale_factor or page_scale_factor changes, then it should be
6616 // updated using the initial transform as the raster scale.
6617 device_scale_factor = 2.25f;
6618 page_scale_factor = 1.25f;
6619
6620 {
6621 RenderSurfaceLayerList render_surface_layer_list;
6622 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6623 root.get(), root->bounds(), &render_surface_layer_list);
6624 inputs.device_scale_factor = device_scale_factor;
6625 inputs.page_scale_factor = page_scale_factor;
6626 inputs.page_scale_application_layer = root.get();
6627 inputs.can_adjust_raster_scales = true;
6628 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6629
6630 EXPECT_CONTENTS_SCALE_EQ(
6631 device_scale_factor * page_scale_factor * initial_parent_scale, parent);
6632 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6633 initial_parent_scale * initial_child_scale,
6634 child_scale);
6635 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6636 initial_parent_scale * initial_child_scale,
6637 child_empty);
6638 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
6639 }
6640
6641 // If the transform changes, we expect the raster scale to be reset to 1.0.
6642 SkMScalar second_child_scale = 1.75;
6643 child_scale_matrix.Scale(second_child_scale / initial_child_scale,
6644 second_child_scale / initial_child_scale);
6645 child_scale->SetTransform(child_scale_matrix);
6646 child_empty->SetTransform(child_scale_matrix);
6647
6648 {
6649 RenderSurfaceLayerList render_surface_layer_list;
6650 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6651 root.get(), root->bounds(), &render_surface_layer_list);
6652 inputs.device_scale_factor = device_scale_factor;
6653 inputs.page_scale_factor = page_scale_factor;
6654 inputs.page_scale_application_layer = root.get();
6655 inputs.can_adjust_raster_scales = true;
6656 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6657
6658 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6659 initial_parent_scale,
6660 parent);
6661 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
6662 child_scale);
6663 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
6664 child_empty);
6665 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
6666 }
6667
6668 // If the device_scale_factor or page_scale_factor changes, then it should be
6669 // updated, but still using 1.0 as the raster scale.
6670 device_scale_factor = 2.75f;
6671 page_scale_factor = 1.75f;
6672
6673 {
6674 RenderSurfaceLayerList render_surface_layer_list;
6675 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6676 root.get(), root->bounds(), &render_surface_layer_list);
6677 inputs.device_scale_factor = device_scale_factor;
6678 inputs.page_scale_factor = page_scale_factor;
6679 inputs.page_scale_application_layer = root.get();
6680 inputs.can_adjust_raster_scales = true;
6681 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6682
6683 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6684 initial_parent_scale,
6685 parent);
6686 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
6687 child_scale);
6688 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
6689 child_empty);
6690 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
6691 }
6692 }
6693
TEST_F(LayerTreeHostCommonTest,ContentsScale_LayerTransformsDontAffectContentsScale)6694 TEST_F(LayerTreeHostCommonTest,
6695 ContentsScale_LayerTransformsDontAffectContentsScale) {
6696 MockContentLayerClient delegate;
6697 gfx::Transform identity_matrix;
6698
6699 gfx::Transform parent_scale_matrix;
6700 SkMScalar initial_parent_scale = 1.75;
6701 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
6702
6703 gfx::Transform child_scale_matrix;
6704 SkMScalar initial_child_scale = 1.25;
6705 child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
6706
6707 scoped_refptr<Layer> root = Layer::Create();
6708 root->SetBounds(gfx::Size(100, 100));
6709
6710 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
6711 SetLayerPropertiesForTesting(parent.get(),
6712 parent_scale_matrix,
6713 identity_matrix,
6714 gfx::PointF(),
6715 gfx::PointF(),
6716 gfx::Size(100, 100),
6717 true);
6718
6719 scoped_refptr<ContentLayer> child_scale =
6720 CreateDrawableContentLayer(&delegate);
6721 SetLayerPropertiesForTesting(child_scale.get(),
6722 child_scale_matrix,
6723 identity_matrix,
6724 gfx::PointF(),
6725 gfx::PointF(2.f, 2.f),
6726 gfx::Size(10, 10),
6727 true);
6728
6729 scoped_refptr<ContentLayer> child_empty =
6730 CreateDrawableContentLayer(&delegate);
6731 SetLayerPropertiesForTesting(child_empty.get(),
6732 child_scale_matrix,
6733 identity_matrix,
6734 gfx::PointF(),
6735 gfx::PointF(2.f, 2.f),
6736 gfx::Size(),
6737 true);
6738
6739 scoped_refptr<NoScaleContentLayer> child_no_scale =
6740 CreateNoScaleDrawableContentLayer(&delegate);
6741 SetLayerPropertiesForTesting(child_no_scale.get(),
6742 child_scale_matrix,
6743 identity_matrix,
6744 gfx::PointF(),
6745 gfx::PointF(12.f, 12.f),
6746 gfx::Size(10, 10),
6747 true);
6748
6749 root->AddChild(parent);
6750
6751 parent->AddChild(child_scale);
6752 parent->AddChild(child_empty);
6753 parent->AddChild(child_no_scale);
6754
6755 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
6756 host->SetRootLayer(root);
6757
6758 RenderSurfaceLayerList render_surface_layer_list;
6759
6760 float device_scale_factor = 2.5f;
6761 float page_scale_factor = 1.f;
6762
6763 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6764 root.get(), root->bounds(), &render_surface_layer_list);
6765 inputs.device_scale_factor = device_scale_factor;
6766 inputs.page_scale_factor = page_scale_factor;
6767 inputs.page_scale_application_layer = root.get(),
6768 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6769
6770 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor, parent);
6771 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
6772 child_scale);
6773 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
6774 child_empty);
6775 EXPECT_CONTENTS_SCALE_EQ(1, child_no_scale);
6776
6777 // Since the transform scale does not affect contents scale, it should affect
6778 // the draw transform instead.
6779 EXPECT_FLOAT_EQ(initial_parent_scale,
6780 parent->draw_transform().matrix().get(0, 0));
6781 EXPECT_FLOAT_EQ(initial_parent_scale,
6782 parent->draw_transform().matrix().get(1, 1));
6783 EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
6784 child_scale->draw_transform().matrix().get(0, 0));
6785 EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
6786 child_scale->draw_transform().matrix().get(1, 1));
6787 EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
6788 child_empty->draw_transform().matrix().get(0, 0));
6789 EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale,
6790 child_empty->draw_transform().matrix().get(1, 1));
6791 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
6792 initial_parent_scale * initial_child_scale,
6793 child_no_scale->draw_transform().matrix().get(0, 0));
6794 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
6795 initial_parent_scale * initial_child_scale,
6796 child_no_scale->draw_transform().matrix().get(1, 1));
6797 }
6798
TEST_F(LayerTreeHostCommonTest,SmallContentsScale)6799 TEST_F(LayerTreeHostCommonTest, SmallContentsScale) {
6800 MockContentLayerClient delegate;
6801 gfx::Transform identity_matrix;
6802
6803 gfx::Transform parent_scale_matrix;
6804 SkMScalar initial_parent_scale = 1.75;
6805 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
6806
6807 gfx::Transform child_scale_matrix;
6808 SkMScalar initial_child_scale = 0.25;
6809 child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
6810
6811 scoped_refptr<Layer> root = Layer::Create();
6812 root->SetBounds(gfx::Size(100, 100));
6813
6814 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
6815 SetLayerPropertiesForTesting(parent.get(),
6816 parent_scale_matrix,
6817 identity_matrix,
6818 gfx::PointF(),
6819 gfx::PointF(),
6820 gfx::Size(100, 100),
6821 true);
6822
6823 scoped_refptr<ContentLayer> child_scale =
6824 CreateDrawableContentLayer(&delegate);
6825 SetLayerPropertiesForTesting(child_scale.get(),
6826 child_scale_matrix,
6827 identity_matrix,
6828 gfx::PointF(),
6829 gfx::PointF(2.f, 2.f),
6830 gfx::Size(10, 10),
6831 true);
6832
6833 root->AddChild(parent);
6834
6835 parent->AddChild(child_scale);
6836
6837 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
6838 host->SetRootLayer(root);
6839
6840 float device_scale_factor = 2.5f;
6841 float page_scale_factor = 0.01f;
6842
6843 {
6844 RenderSurfaceLayerList render_surface_layer_list;
6845 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6846 root.get(), root->bounds(), &render_surface_layer_list);
6847 inputs.device_scale_factor = device_scale_factor;
6848 inputs.page_scale_factor = page_scale_factor;
6849 inputs.page_scale_application_layer = root.get();
6850 inputs.can_adjust_raster_scales = true;
6851 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6852
6853 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6854 initial_parent_scale,
6855 parent);
6856 // The child's scale is < 1, so we should not save and use that scale
6857 // factor.
6858 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor * 1,
6859 child_scale);
6860 }
6861
6862 // When chilld's total scale becomes >= 1, we should save and use that scale
6863 // factor.
6864 child_scale_matrix.MakeIdentity();
6865 SkMScalar final_child_scale = 0.75;
6866 child_scale_matrix.Scale(final_child_scale, final_child_scale);
6867 child_scale->SetTransform(child_scale_matrix);
6868
6869 {
6870 RenderSurfaceLayerList render_surface_layer_list;
6871 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6872 root.get(), root->bounds(), &render_surface_layer_list);
6873 inputs.device_scale_factor = device_scale_factor;
6874 inputs.page_scale_factor = page_scale_factor;
6875 inputs.page_scale_application_layer = root.get();
6876 inputs.can_adjust_raster_scales = true;
6877 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6878
6879 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6880 initial_parent_scale,
6881 parent);
6882 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
6883 initial_parent_scale * final_child_scale,
6884 child_scale);
6885 }
6886 }
6887
TEST_F(LayerTreeHostCommonTest,ContentsScaleForSurfaces)6888 TEST_F(LayerTreeHostCommonTest, ContentsScaleForSurfaces) {
6889 MockContentLayerClient delegate;
6890 gfx::Transform identity_matrix;
6891
6892 gfx::Transform parent_scale_matrix;
6893 SkMScalar initial_parent_scale = 2.0;
6894 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
6895
6896 gfx::Transform child_scale_matrix;
6897 SkMScalar initial_child_scale = 3.0;
6898 child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
6899
6900 scoped_refptr<Layer> root = Layer::Create();
6901 root->SetBounds(gfx::Size(100, 100));
6902
6903 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
6904 SetLayerPropertiesForTesting(parent.get(),
6905 parent_scale_matrix,
6906 identity_matrix,
6907 gfx::PointF(),
6908 gfx::PointF(),
6909 gfx::Size(100, 100),
6910 true);
6911
6912 scoped_refptr<ContentLayer> surface_scale =
6913 CreateDrawableContentLayer(&delegate);
6914 SetLayerPropertiesForTesting(surface_scale.get(),
6915 child_scale_matrix,
6916 identity_matrix,
6917 gfx::PointF(),
6918 gfx::PointF(2.f, 2.f),
6919 gfx::Size(10, 10),
6920 true);
6921
6922 scoped_refptr<ContentLayer> surface_scale_child_scale =
6923 CreateDrawableContentLayer(&delegate);
6924 SetLayerPropertiesForTesting(surface_scale_child_scale.get(),
6925 child_scale_matrix,
6926 identity_matrix,
6927 gfx::PointF(),
6928 gfx::PointF(),
6929 gfx::Size(10, 10),
6930 true);
6931
6932 scoped_refptr<NoScaleContentLayer> surface_scale_child_no_scale =
6933 CreateNoScaleDrawableContentLayer(&delegate);
6934 SetLayerPropertiesForTesting(surface_scale_child_no_scale.get(),
6935 child_scale_matrix,
6936 identity_matrix,
6937 gfx::PointF(),
6938 gfx::PointF(),
6939 gfx::Size(10, 10),
6940 true);
6941
6942 scoped_refptr<NoScaleContentLayer> surface_no_scale =
6943 CreateNoScaleDrawableContentLayer(&delegate);
6944 SetLayerPropertiesForTesting(surface_no_scale.get(),
6945 child_scale_matrix,
6946 identity_matrix,
6947 gfx::PointF(),
6948 gfx::PointF(12.f, 12.f),
6949 gfx::Size(10, 10),
6950 true);
6951
6952 scoped_refptr<ContentLayer> surface_no_scale_child_scale =
6953 CreateDrawableContentLayer(&delegate);
6954 SetLayerPropertiesForTesting(surface_no_scale_child_scale.get(),
6955 child_scale_matrix,
6956 identity_matrix,
6957 gfx::PointF(),
6958 gfx::PointF(),
6959 gfx::Size(10, 10),
6960 true);
6961
6962 scoped_refptr<NoScaleContentLayer> surface_no_scale_child_no_scale =
6963 CreateNoScaleDrawableContentLayer(&delegate);
6964 SetLayerPropertiesForTesting(surface_no_scale_child_no_scale.get(),
6965 child_scale_matrix,
6966 identity_matrix,
6967 gfx::PointF(),
6968 gfx::PointF(),
6969 gfx::Size(10, 10),
6970 true);
6971
6972 root->AddChild(parent);
6973
6974 parent->AddChild(surface_scale);
6975 parent->AddChild(surface_no_scale);
6976
6977 surface_scale->SetForceRenderSurface(true);
6978 surface_scale->AddChild(surface_scale_child_scale);
6979 surface_scale->AddChild(surface_scale_child_no_scale);
6980
6981 surface_no_scale->SetForceRenderSurface(true);
6982 surface_no_scale->AddChild(surface_no_scale_child_scale);
6983 surface_no_scale->AddChild(surface_no_scale_child_no_scale);
6984
6985 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
6986 host->SetRootLayer(root);
6987
6988 SkMScalar device_scale_factor = 5;
6989 SkMScalar page_scale_factor = 7;
6990
6991 RenderSurfaceLayerList render_surface_layer_list;
6992 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
6993 root.get(), root->bounds(), &render_surface_layer_list);
6994 inputs.device_scale_factor = device_scale_factor;
6995 inputs.page_scale_factor = page_scale_factor;
6996 inputs.page_scale_application_layer = root.get();
6997 inputs.can_adjust_raster_scales = true;
6998 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
6999
7000 EXPECT_CONTENTS_SCALE_EQ(
7001 device_scale_factor * page_scale_factor * initial_parent_scale, parent);
7002 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor *
7003 initial_parent_scale * initial_child_scale,
7004 surface_scale);
7005 EXPECT_CONTENTS_SCALE_EQ(1, surface_no_scale);
7006 EXPECT_CONTENTS_SCALE_EQ(
7007 device_scale_factor * page_scale_factor * initial_parent_scale *
7008 initial_child_scale * initial_child_scale,
7009 surface_scale_child_scale);
7010 EXPECT_CONTENTS_SCALE_EQ(1, surface_scale_child_no_scale);
7011 EXPECT_CONTENTS_SCALE_EQ(
7012 device_scale_factor * page_scale_factor * initial_parent_scale *
7013 initial_child_scale * initial_child_scale,
7014 surface_no_scale_child_scale);
7015 EXPECT_CONTENTS_SCALE_EQ(1, surface_no_scale_child_no_scale);
7016
7017 // The parent is scaled up and shouldn't need to scale during draw.
7018 EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(0, 0));
7019 EXPECT_FLOAT_EQ(1.0, parent->draw_transform().matrix().get(1, 1));
7020
7021 // RenderSurfaces should always be 1:1 with their target.
7022 EXPECT_FLOAT_EQ(
7023 1.0,
7024 surface_scale->render_surface()->draw_transform().matrix().get(0, 0));
7025 EXPECT_FLOAT_EQ(
7026 1.0,
7027 surface_scale->render_surface()->draw_transform().matrix().get(1, 1));
7028
7029 // The surface_scale can apply contents scale so the layer shouldn't need to
7030 // scale during draw.
7031 EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(0, 0));
7032 EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(1, 1));
7033
7034 // The surface_scale_child_scale can apply contents scale so it shouldn't need
7035 // to scale during draw.
7036 EXPECT_FLOAT_EQ(
7037 1.0, surface_scale_child_scale->draw_transform().matrix().get(0, 0));
7038 EXPECT_FLOAT_EQ(
7039 1.0, surface_scale_child_scale->draw_transform().matrix().get(1, 1));
7040
7041 // The surface_scale_child_no_scale can not apply contents scale, so it needs
7042 // to be scaled during draw.
7043 EXPECT_FLOAT_EQ(
7044 device_scale_factor * page_scale_factor * initial_parent_scale *
7045 initial_child_scale * initial_child_scale,
7046 surface_scale_child_no_scale->draw_transform().matrix().get(0, 0));
7047 EXPECT_FLOAT_EQ(
7048 device_scale_factor * page_scale_factor * initial_parent_scale *
7049 initial_child_scale * initial_child_scale,
7050 surface_scale_child_no_scale->draw_transform().matrix().get(1, 1));
7051
7052 // RenderSurfaces should always be 1:1 with their target.
7053 EXPECT_FLOAT_EQ(
7054 1.0,
7055 surface_no_scale->render_surface()->draw_transform().matrix().get(0, 0));
7056 EXPECT_FLOAT_EQ(
7057 1.0,
7058 surface_no_scale->render_surface()->draw_transform().matrix().get(1, 1));
7059
7060 // The surface_no_scale layer can not apply contents scale, so it needs to be
7061 // scaled during draw.
7062 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
7063 initial_parent_scale * initial_child_scale,
7064 surface_no_scale->draw_transform().matrix().get(0, 0));
7065 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor *
7066 initial_parent_scale * initial_child_scale,
7067 surface_no_scale->draw_transform().matrix().get(1, 1));
7068
7069 // The surface_scale_child_scale can apply contents scale so it shouldn't need
7070 // to scale during draw.
7071 EXPECT_FLOAT_EQ(
7072 1.0, surface_no_scale_child_scale->draw_transform().matrix().get(0, 0));
7073 EXPECT_FLOAT_EQ(
7074 1.0, surface_no_scale_child_scale->draw_transform().matrix().get(1, 1));
7075
7076 // The surface_scale_child_no_scale can not apply contents scale, so it needs
7077 // to be scaled during draw.
7078 EXPECT_FLOAT_EQ(
7079 device_scale_factor * page_scale_factor * initial_parent_scale *
7080 initial_child_scale * initial_child_scale,
7081 surface_no_scale_child_no_scale->draw_transform().matrix().get(0, 0));
7082 EXPECT_FLOAT_EQ(
7083 device_scale_factor * page_scale_factor * initial_parent_scale *
7084 initial_child_scale * initial_child_scale,
7085 surface_no_scale_child_no_scale->draw_transform().matrix().get(1, 1));
7086 }
7087
TEST_F(LayerTreeHostCommonTest,ContentsScaleForSurfaces_LayerTransformsDontAffectContentsScale)7088 TEST_F(LayerTreeHostCommonTest,
7089 ContentsScaleForSurfaces_LayerTransformsDontAffectContentsScale) {
7090 MockContentLayerClient delegate;
7091 gfx::Transform identity_matrix;
7092
7093 gfx::Transform parent_scale_matrix;
7094 SkMScalar initial_parent_scale = 2.0;
7095 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
7096
7097 gfx::Transform child_scale_matrix;
7098 SkMScalar initial_child_scale = 3.0;
7099 child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
7100
7101 scoped_refptr<Layer> root = Layer::Create();
7102 root->SetBounds(gfx::Size(100, 100));
7103
7104 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
7105 SetLayerPropertiesForTesting(parent.get(),
7106 parent_scale_matrix,
7107 identity_matrix,
7108 gfx::PointF(),
7109 gfx::PointF(),
7110 gfx::Size(100, 100),
7111 true);
7112
7113 scoped_refptr<ContentLayer> surface_scale =
7114 CreateDrawableContentLayer(&delegate);
7115 SetLayerPropertiesForTesting(surface_scale.get(),
7116 child_scale_matrix,
7117 identity_matrix,
7118 gfx::PointF(),
7119 gfx::PointF(2.f, 2.f),
7120 gfx::Size(10, 10),
7121 true);
7122
7123 scoped_refptr<ContentLayer> surface_scale_child_scale =
7124 CreateDrawableContentLayer(&delegate);
7125 SetLayerPropertiesForTesting(surface_scale_child_scale.get(),
7126 child_scale_matrix,
7127 identity_matrix,
7128 gfx::PointF(),
7129 gfx::PointF(),
7130 gfx::Size(10, 10),
7131 true);
7132
7133 scoped_refptr<NoScaleContentLayer> surface_scale_child_no_scale =
7134 CreateNoScaleDrawableContentLayer(&delegate);
7135 SetLayerPropertiesForTesting(surface_scale_child_no_scale.get(),
7136 child_scale_matrix,
7137 identity_matrix,
7138 gfx::PointF(),
7139 gfx::PointF(),
7140 gfx::Size(10, 10),
7141 true);
7142
7143 scoped_refptr<NoScaleContentLayer> surface_no_scale =
7144 CreateNoScaleDrawableContentLayer(&delegate);
7145 SetLayerPropertiesForTesting(surface_no_scale.get(),
7146 child_scale_matrix,
7147 identity_matrix,
7148 gfx::PointF(),
7149 gfx::PointF(12.f, 12.f),
7150 gfx::Size(10, 10),
7151 true);
7152
7153 scoped_refptr<ContentLayer> surface_no_scale_child_scale =
7154 CreateDrawableContentLayer(&delegate);
7155 SetLayerPropertiesForTesting(surface_no_scale_child_scale.get(),
7156 child_scale_matrix,
7157 identity_matrix,
7158 gfx::PointF(),
7159 gfx::PointF(),
7160 gfx::Size(10, 10),
7161 true);
7162
7163 scoped_refptr<NoScaleContentLayer> surface_no_scale_child_no_scale =
7164 CreateNoScaleDrawableContentLayer(&delegate);
7165 SetLayerPropertiesForTesting(surface_no_scale_child_no_scale.get(),
7166 child_scale_matrix,
7167 identity_matrix,
7168 gfx::PointF(),
7169 gfx::PointF(),
7170 gfx::Size(10, 10),
7171 true);
7172
7173 root->AddChild(parent);
7174
7175 parent->AddChild(surface_scale);
7176 parent->AddChild(surface_no_scale);
7177
7178 surface_scale->SetForceRenderSurface(true);
7179 surface_scale->AddChild(surface_scale_child_scale);
7180 surface_scale->AddChild(surface_scale_child_no_scale);
7181
7182 surface_no_scale->SetForceRenderSurface(true);
7183 surface_no_scale->AddChild(surface_no_scale_child_scale);
7184 surface_no_scale->AddChild(surface_no_scale_child_no_scale);
7185
7186 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
7187 host->SetRootLayer(root);
7188
7189 RenderSurfaceLayerList render_surface_layer_list;
7190
7191 SkMScalar device_scale_factor = 5.0;
7192 SkMScalar page_scale_factor = 7.0;
7193 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
7194 root.get(), root->bounds(), &render_surface_layer_list);
7195 inputs.device_scale_factor = device_scale_factor;
7196 inputs.page_scale_factor = page_scale_factor;
7197 inputs.page_scale_application_layer = root.get();
7198 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
7199
7200 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
7201 parent);
7202 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
7203 surface_scale);
7204 EXPECT_CONTENTS_SCALE_EQ(1.f, surface_no_scale);
7205 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
7206 surface_scale_child_scale);
7207 EXPECT_CONTENTS_SCALE_EQ(1.f, surface_scale_child_no_scale);
7208 EXPECT_CONTENTS_SCALE_EQ(device_scale_factor * page_scale_factor,
7209 surface_no_scale_child_scale);
7210 EXPECT_CONTENTS_SCALE_EQ(1.f, surface_no_scale_child_no_scale);
7211
7212 // The parent is scaled up during draw, since its contents are not scaled by
7213 // the transform hierarchy.
7214 EXPECT_FLOAT_EQ(initial_parent_scale,
7215 parent->draw_transform().matrix().get(0, 0));
7216 EXPECT_FLOAT_EQ(initial_parent_scale,
7217 parent->draw_transform().matrix().get(1, 1));
7218
7219 // The child surface is scaled up during draw since its subtree is not scaled
7220 // by the transform hierarchy.
7221 EXPECT_FLOAT_EQ(
7222 initial_parent_scale * initial_child_scale,
7223 surface_scale->render_surface()->draw_transform().matrix().get(0, 0));
7224 EXPECT_FLOAT_EQ(
7225 initial_parent_scale * initial_child_scale,
7226 surface_scale->render_surface()->draw_transform().matrix().get(1, 1));
7227
7228 // The surface_scale's RenderSurface is scaled during draw, so the layer does
7229 // not need to be scaled when drawing into its surface.
7230 EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(0, 0));
7231 EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(1, 1));
7232
7233 // The surface_scale_child_scale is scaled when drawing into its surface,
7234 // since its content bounds are not scaled by the transform hierarchy.
7235 EXPECT_FLOAT_EQ(
7236 initial_child_scale,
7237 surface_scale_child_scale->draw_transform().matrix().get(0, 0));
7238 EXPECT_FLOAT_EQ(
7239 initial_child_scale,
7240 surface_scale_child_scale->draw_transform().matrix().get(1, 1));
7241
7242 // The surface_scale_child_no_scale has a fixed contents scale of 1, so it
7243 // needs to be scaled by the device and page scale factors, along with the
7244 // transform hierarchy.
7245 EXPECT_FLOAT_EQ(
7246 device_scale_factor * page_scale_factor * initial_child_scale,
7247 surface_scale_child_no_scale->draw_transform().matrix().get(0, 0));
7248 EXPECT_FLOAT_EQ(
7249 device_scale_factor * page_scale_factor * initial_child_scale,
7250 surface_scale_child_no_scale->draw_transform().matrix().get(1, 1));
7251
7252 // The child surface is scaled up during draw since its subtree is not scaled
7253 // by the transform hierarchy.
7254 EXPECT_FLOAT_EQ(
7255 initial_parent_scale * initial_child_scale,
7256 surface_no_scale->render_surface()->draw_transform().matrix().get(0, 0));
7257 EXPECT_FLOAT_EQ(
7258 initial_parent_scale * initial_child_scale,
7259 surface_no_scale->render_surface()->draw_transform().matrix().get(1, 1));
7260
7261 // The surface_no_scale layer has a fixed contents scale of 1, so it needs to
7262 // be scaled by the device and page scale factors. Its surface is already
7263 // scaled by the transform hierarchy so those don't need to scale the layer's
7264 // drawing.
7265 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor,
7266 surface_no_scale->draw_transform().matrix().get(0, 0));
7267 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor,
7268 surface_no_scale->draw_transform().matrix().get(1, 1));
7269
7270 // The surface_no_scale_child_scale has its contents scaled by the page and
7271 // device scale factors, but needs to be scaled by the transform hierarchy
7272 // when drawing.
7273 EXPECT_FLOAT_EQ(
7274 initial_child_scale,
7275 surface_no_scale_child_scale->draw_transform().matrix().get(0, 0));
7276 EXPECT_FLOAT_EQ(
7277 initial_child_scale,
7278 surface_no_scale_child_scale->draw_transform().matrix().get(1, 1));
7279
7280 // The surface_no_scale_child_no_scale has a fixed contents scale of 1, so it
7281 // needs to be scaled by the device and page scale factors. It also needs to
7282 // be scaled by any transform heirarchy below its target surface.
7283 EXPECT_FLOAT_EQ(
7284 device_scale_factor * page_scale_factor * initial_child_scale,
7285 surface_no_scale_child_no_scale->draw_transform().matrix().get(0, 0));
7286 EXPECT_FLOAT_EQ(
7287 device_scale_factor * page_scale_factor * initial_child_scale,
7288 surface_no_scale_child_no_scale->draw_transform().matrix().get(1, 1));
7289 }
7290
TEST_F(LayerTreeHostCommonTest,ContentsScaleForAnimatingLayer)7291 TEST_F(LayerTreeHostCommonTest, ContentsScaleForAnimatingLayer) {
7292 MockContentLayerClient delegate;
7293 gfx::Transform identity_matrix;
7294
7295 gfx::Transform parent_scale_matrix;
7296 SkMScalar initial_parent_scale = 1.75;
7297 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
7298
7299 gfx::Transform child_scale_matrix;
7300 SkMScalar initial_child_scale = 1.25;
7301 child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
7302
7303 scoped_refptr<Layer> root = Layer::Create();
7304 root->SetBounds(gfx::Size(100, 100));
7305
7306 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
7307 SetLayerPropertiesForTesting(parent.get(),
7308 parent_scale_matrix,
7309 identity_matrix,
7310 gfx::PointF(),
7311 gfx::PointF(),
7312 gfx::Size(100, 100),
7313 true);
7314
7315 scoped_refptr<ContentLayer> child_scale =
7316 CreateDrawableContentLayer(&delegate);
7317 SetLayerPropertiesForTesting(child_scale.get(),
7318 child_scale_matrix,
7319 identity_matrix,
7320 gfx::PointF(),
7321 gfx::PointF(2.f, 2.f),
7322 gfx::Size(10, 10),
7323 true);
7324
7325 root->AddChild(parent);
7326
7327 parent->AddChild(child_scale);
7328
7329 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
7330 host->SetRootLayer(root);
7331
7332 // Now put an animating transform on child.
7333 int animation_id = AddAnimatedTransformToController(
7334 child_scale->layer_animation_controller(), 10.0, 30, 0);
7335
7336 {
7337 RenderSurfaceLayerList render_surface_layer_list;
7338 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
7339 root.get(), root->bounds(), &render_surface_layer_list);
7340 inputs.can_adjust_raster_scales = true;
7341 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
7342
7343 EXPECT_CONTENTS_SCALE_EQ(initial_parent_scale, parent);
7344 // The layers with animating transforms should not compute a contents scale
7345 // other than 1 until they finish animating.
7346 EXPECT_CONTENTS_SCALE_EQ(1, child_scale);
7347 }
7348
7349 // Remove the animation, now it can save a raster scale.
7350 child_scale->layer_animation_controller()->RemoveAnimation(animation_id);
7351
7352 {
7353 RenderSurfaceLayerList render_surface_layer_list;
7354 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
7355 root.get(), root->bounds(), &render_surface_layer_list);
7356 inputs.can_adjust_raster_scales = true;
7357 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
7358
7359 EXPECT_CONTENTS_SCALE_EQ(initial_parent_scale, parent);
7360 // The layers with animating transforms should not compute a contents scale
7361 // other than 1 until they finish animating.
7362 EXPECT_CONTENTS_SCALE_EQ(initial_parent_scale * initial_child_scale,
7363 child_scale);
7364 }
7365 }
7366
TEST_F(LayerTreeHostCommonTest,RenderSurfaceTransformsInHighDPI)7367 TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) {
7368 MockContentLayerClient delegate;
7369 gfx::Transform identity_matrix;
7370
7371 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
7372 SetLayerPropertiesForTesting(parent.get(),
7373 identity_matrix,
7374 identity_matrix,
7375 gfx::PointF(),
7376 gfx::PointF(),
7377 gfx::Size(30, 30),
7378 true);
7379
7380 scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate);
7381 SetLayerPropertiesForTesting(child.get(),
7382 identity_matrix,
7383 identity_matrix,
7384 gfx::PointF(),
7385 gfx::PointF(2.f, 2.f),
7386 gfx::Size(10, 10),
7387 true);
7388
7389 gfx::Transform replica_transform;
7390 replica_transform.Scale(1.0, -1.0);
7391 scoped_refptr<ContentLayer> replica = CreateDrawableContentLayer(&delegate);
7392 SetLayerPropertiesForTesting(replica.get(),
7393 replica_transform,
7394 identity_matrix,
7395 gfx::PointF(),
7396 gfx::PointF(2.f, 2.f),
7397 gfx::Size(10, 10),
7398 true);
7399
7400 // This layer should end up in the same surface as child, with the same draw
7401 // and screen space transforms.
7402 scoped_refptr<ContentLayer> duplicate_child_non_owner =
7403 CreateDrawableContentLayer(&delegate);
7404 SetLayerPropertiesForTesting(duplicate_child_non_owner.get(),
7405 identity_matrix,
7406 identity_matrix,
7407 gfx::PointF(),
7408 gfx::PointF(),
7409 gfx::Size(10, 10),
7410 true);
7411
7412 parent->AddChild(child);
7413 child->AddChild(duplicate_child_non_owner);
7414 child->SetReplicaLayer(replica.get());
7415
7416 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
7417 host->SetRootLayer(parent);
7418
7419 RenderSurfaceLayerList render_surface_layer_list;
7420
7421 float device_scale_factor = 1.5f;
7422 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
7423 parent.get(), parent->bounds(), &render_surface_layer_list);
7424 inputs.device_scale_factor = device_scale_factor;
7425 inputs.can_adjust_raster_scales = true;
7426 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
7427
7428 // We should have two render surfaces. The root's render surface and child's
7429 // render surface (it needs one because it has a replica layer).
7430 EXPECT_EQ(2u, render_surface_layer_list.size());
7431
7432 gfx::Transform expected_parent_transform;
7433 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
7434 parent->screen_space_transform());
7435 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
7436 parent->draw_transform());
7437
7438 gfx::Transform expected_draw_transform;
7439 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_draw_transform,
7440 child->draw_transform());
7441
7442 gfx::Transform expected_screen_space_transform;
7443 expected_screen_space_transform.Translate(
7444 device_scale_factor * child->position().x(),
7445 device_scale_factor * child->position().y());
7446 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform,
7447 child->screen_space_transform());
7448
7449 gfx::Transform expected_duplicate_child_draw_transform =
7450 child->draw_transform();
7451 EXPECT_TRANSFORMATION_MATRIX_EQ(child->draw_transform(),
7452 duplicate_child_non_owner->draw_transform());
7453 EXPECT_TRANSFORMATION_MATRIX_EQ(
7454 child->screen_space_transform(),
7455 duplicate_child_non_owner->screen_space_transform());
7456 EXPECT_RECT_EQ(child->drawable_content_rect(),
7457 duplicate_child_non_owner->drawable_content_rect());
7458 EXPECT_EQ(child->content_bounds(),
7459 duplicate_child_non_owner->content_bounds());
7460
7461 gfx::Transform expected_render_surface_draw_transform;
7462 expected_render_surface_draw_transform.Translate(
7463 device_scale_factor * child->position().x(),
7464 device_scale_factor * child->position().y());
7465 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_render_surface_draw_transform,
7466 child->render_surface()->draw_transform());
7467
7468 gfx::Transform expected_surface_draw_transform;
7469 expected_surface_draw_transform.Translate(device_scale_factor * 2.f,
7470 device_scale_factor * 2.f);
7471 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
7472 child->render_surface()->draw_transform());
7473
7474 gfx::Transform expected_surface_screen_space_transform;
7475 expected_surface_screen_space_transform.Translate(device_scale_factor * 2.f,
7476 device_scale_factor * 2.f);
7477 EXPECT_TRANSFORMATION_MATRIX_EQ(
7478 expected_surface_screen_space_transform,
7479 child->render_surface()->screen_space_transform());
7480
7481 gfx::Transform expected_replica_draw_transform;
7482 expected_replica_draw_transform.matrix().set(1, 1, -1.0);
7483 expected_replica_draw_transform.matrix().set(0, 3, 6.0);
7484 expected_replica_draw_transform.matrix().set(1, 3, 6.0);
7485 EXPECT_TRANSFORMATION_MATRIX_EQ(
7486 expected_replica_draw_transform,
7487 child->render_surface()->replica_draw_transform());
7488
7489 gfx::Transform expected_replica_screen_space_transform;
7490 expected_replica_screen_space_transform.matrix().set(1, 1, -1.0);
7491 expected_replica_screen_space_transform.matrix().set(0, 3, 6.0);
7492 expected_replica_screen_space_transform.matrix().set(1, 3, 6.0);
7493 EXPECT_TRANSFORMATION_MATRIX_EQ(
7494 expected_replica_screen_space_transform,
7495 child->render_surface()->replica_screen_space_transform());
7496 EXPECT_TRANSFORMATION_MATRIX_EQ(
7497 expected_replica_screen_space_transform,
7498 child->render_surface()->replica_screen_space_transform());
7499 }
7500
TEST_F(LayerTreeHostCommonTest,RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition)7501 TEST_F(LayerTreeHostCommonTest,
7502 RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition) {
7503 MockContentLayerClient delegate;
7504 gfx::Transform identity_matrix;
7505
7506 scoped_refptr<ContentLayer> parent = CreateDrawableContentLayer(&delegate);
7507 SetLayerPropertiesForTesting(parent.get(),
7508 identity_matrix,
7509 identity_matrix,
7510 gfx::PointF(),
7511 gfx::PointF(),
7512 gfx::Size(33, 31),
7513 true);
7514
7515 scoped_refptr<ContentLayer> child = CreateDrawableContentLayer(&delegate);
7516 SetLayerPropertiesForTesting(child.get(),
7517 identity_matrix,
7518 identity_matrix,
7519 gfx::PointF(),
7520 gfx::PointF(),
7521 gfx::Size(13, 11),
7522 true);
7523
7524 gfx::Transform replica_transform;
7525 replica_transform.Scale(1.0, -1.0);
7526 scoped_refptr<ContentLayer> replica = CreateDrawableContentLayer(&delegate);
7527 SetLayerPropertiesForTesting(replica.get(),
7528 replica_transform,
7529 identity_matrix,
7530 gfx::PointF(),
7531 gfx::PointF(),
7532 gfx::Size(13, 11),
7533 true);
7534
7535 // This layer should end up in the same surface as child, with the same draw
7536 // and screen space transforms.
7537 scoped_refptr<ContentLayer> duplicate_child_non_owner =
7538 CreateDrawableContentLayer(&delegate);
7539 SetLayerPropertiesForTesting(duplicate_child_non_owner.get(),
7540 identity_matrix,
7541 identity_matrix,
7542 gfx::PointF(),
7543 gfx::PointF(),
7544 gfx::Size(13, 11),
7545 true);
7546
7547 parent->AddChild(child);
7548 child->AddChild(duplicate_child_non_owner);
7549 child->SetReplicaLayer(replica.get());
7550
7551 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
7552 host->SetRootLayer(parent);
7553
7554 float device_scale_factor = 1.7f;
7555
7556 RenderSurfaceLayerList render_surface_layer_list;
7557 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
7558 parent.get(), parent->bounds(), &render_surface_layer_list);
7559 inputs.device_scale_factor = device_scale_factor;
7560 inputs.can_adjust_raster_scales = true;
7561 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
7562
7563 // We should have two render surfaces. The root's render surface and child's
7564 // render surface (it needs one because it has a replica layer).
7565 EXPECT_EQ(2u, render_surface_layer_list.size());
7566
7567 gfx::Transform identity_transform;
7568
7569 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform,
7570 parent->screen_space_transform());
7571 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, parent->draw_transform());
7572 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform, child->draw_transform());
7573 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform,
7574 child->screen_space_transform());
7575 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform,
7576 duplicate_child_non_owner->draw_transform());
7577 EXPECT_TRANSFORMATION_MATRIX_EQ(
7578 identity_transform, duplicate_child_non_owner->screen_space_transform());
7579 EXPECT_RECT_EQ(child->drawable_content_rect(),
7580 duplicate_child_non_owner->drawable_content_rect());
7581 EXPECT_EQ(child->content_bounds(),
7582 duplicate_child_non_owner->content_bounds());
7583
7584 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform,
7585 child->render_surface()->draw_transform());
7586 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_transform,
7587 child->render_surface()->draw_transform());
7588 EXPECT_TRANSFORMATION_MATRIX_EQ(
7589 identity_transform, child->render_surface()->screen_space_transform());
7590
7591 gfx::Transform expected_replica_draw_transform;
7592 expected_replica_draw_transform.matrix().set(1, 1, -1.0);
7593 EXPECT_TRANSFORMATION_MATRIX_EQ(
7594 expected_replica_draw_transform,
7595 child->render_surface()->replica_draw_transform());
7596
7597 gfx::Transform expected_replica_screen_space_transform;
7598 expected_replica_screen_space_transform.matrix().set(1, 1, -1.0);
7599 EXPECT_TRANSFORMATION_MATRIX_EQ(
7600 expected_replica_screen_space_transform,
7601 child->render_surface()->replica_screen_space_transform());
7602 }
7603
TEST_F(LayerTreeHostCommonTest,SubtreeSearch)7604 TEST_F(LayerTreeHostCommonTest, SubtreeSearch) {
7605 scoped_refptr<Layer> root = Layer::Create();
7606 scoped_refptr<Layer> child = Layer::Create();
7607 scoped_refptr<Layer> grand_child = Layer::Create();
7608 scoped_refptr<Layer> mask_layer = Layer::Create();
7609 scoped_refptr<Layer> replica_layer = Layer::Create();
7610
7611 grand_child->SetReplicaLayer(replica_layer.get());
7612 child->AddChild(grand_child.get());
7613 child->SetMaskLayer(mask_layer.get());
7614 root->AddChild(child.get());
7615
7616 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
7617 host->SetRootLayer(root);
7618
7619 int nonexistent_id = -1;
7620 EXPECT_EQ(root,
7621 LayerTreeHostCommon::FindLayerInSubtree(root.get(), root->id()));
7622 EXPECT_EQ(child,
7623 LayerTreeHostCommon::FindLayerInSubtree(root.get(), child->id()));
7624 EXPECT_EQ(
7625 grand_child,
7626 LayerTreeHostCommon::FindLayerInSubtree(root.get(), grand_child->id()));
7627 EXPECT_EQ(
7628 mask_layer,
7629 LayerTreeHostCommon::FindLayerInSubtree(root.get(), mask_layer->id()));
7630 EXPECT_EQ(
7631 replica_layer,
7632 LayerTreeHostCommon::FindLayerInSubtree(root.get(), replica_layer->id()));
7633 EXPECT_EQ(
7634 0, LayerTreeHostCommon::FindLayerInSubtree(root.get(), nonexistent_id));
7635 }
7636
TEST_F(LayerTreeHostCommonTest,TransparentChildRenderSurfaceCreation)7637 TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) {
7638 scoped_refptr<Layer> root = Layer::Create();
7639 scoped_refptr<Layer> child = Layer::Create();
7640 scoped_refptr<LayerWithForcedDrawsContent> grand_child =
7641 make_scoped_refptr(new LayerWithForcedDrawsContent());
7642
7643 const gfx::Transform identity_matrix;
7644 SetLayerPropertiesForTesting(root.get(),
7645 identity_matrix,
7646 identity_matrix,
7647 gfx::PointF(),
7648 gfx::PointF(),
7649 gfx::Size(100, 100),
7650 false);
7651 SetLayerPropertiesForTesting(child.get(),
7652 identity_matrix,
7653 identity_matrix,
7654 gfx::PointF(),
7655 gfx::PointF(),
7656 gfx::Size(10, 10),
7657 false);
7658 SetLayerPropertiesForTesting(grand_child.get(),
7659 identity_matrix,
7660 identity_matrix,
7661 gfx::PointF(),
7662 gfx::PointF(),
7663 gfx::Size(10, 10),
7664 false);
7665
7666 root->AddChild(child);
7667 child->AddChild(grand_child);
7668 child->SetOpacity(0.5f);
7669
7670 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
7671 host->SetRootLayer(root);
7672
7673 ExecuteCalculateDrawProperties(root.get());
7674
7675 EXPECT_FALSE(child->render_surface());
7676 }
7677
TEST_F(LayerTreeHostCommonTest,OpacityAnimatingOnPendingTree)7678 TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) {
7679 FakeImplProxy proxy;
7680 FakeLayerTreeHostImpl host_impl(&proxy);
7681 host_impl.CreatePendingTree();
7682 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1);
7683
7684 const gfx::Transform identity_matrix;
7685 SetLayerPropertiesForTesting(root.get(),
7686 identity_matrix,
7687 identity_matrix,
7688 gfx::PointF(),
7689 gfx::PointF(),
7690 gfx::Size(100, 100),
7691 false);
7692 root->SetDrawsContent(true);
7693
7694 scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2);
7695 SetLayerPropertiesForTesting(child.get(),
7696 identity_matrix,
7697 identity_matrix,
7698 gfx::PointF(),
7699 gfx::PointF(),
7700 gfx::Size(50, 50),
7701 false);
7702 child->SetDrawsContent(true);
7703 child->SetOpacity(0.0f);
7704
7705 // Add opacity animation.
7706 AddOpacityTransitionToController(
7707 child->layer_animation_controller(), 10.0, 0.0f, 1.0f, false);
7708
7709 root->AddChild(child.Pass());
7710
7711 LayerImplList render_surface_layer_list;
7712 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
7713 root.get(), root->bounds(), &render_surface_layer_list);
7714 inputs.can_adjust_raster_scales = true;
7715 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
7716
7717 // We should have one render surface and two layers. The child
7718 // layer should be included even though it is transparent.
7719 ASSERT_EQ(1u, render_surface_layer_list.size());
7720 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
7721 }
7722
7723 typedef std::tr1::tuple<bool, bool> LCDTextTestParam;
7724 class LCDTextTest
7725 : public LayerTreeHostCommonTestBase,
7726 public testing::TestWithParam<LCDTextTestParam> {
7727 protected:
SetUp()7728 virtual void SetUp() {
7729 can_use_lcd_text_ = std::tr1::get<0>(GetParam());
7730
7731 root_ = Layer::Create();
7732 child_ = Layer::Create();
7733 grand_child_ = Layer::Create();
7734 child_->AddChild(grand_child_.get());
7735 root_->AddChild(child_.get());
7736
7737 gfx::Transform identity_matrix;
7738 SetLayerPropertiesForTesting(root_.get(),
7739 identity_matrix,
7740 identity_matrix,
7741 gfx::PointF(),
7742 gfx::PointF(),
7743 gfx::Size(1, 1),
7744 false);
7745 SetLayerPropertiesForTesting(child_.get(),
7746 identity_matrix,
7747 identity_matrix,
7748 gfx::PointF(),
7749 gfx::PointF(),
7750 gfx::Size(1, 1),
7751 false);
7752 SetLayerPropertiesForTesting(grand_child_.get(),
7753 identity_matrix,
7754 identity_matrix,
7755 gfx::PointF(),
7756 gfx::PointF(),
7757 gfx::Size(1, 1),
7758 false);
7759
7760 child_->SetForceRenderSurface(std::tr1::get<1>(GetParam()));
7761
7762 host_ = FakeLayerTreeHost::Create();
7763 host_->SetRootLayer(root_);
7764 }
7765
7766 bool can_use_lcd_text_;
7767 scoped_ptr<FakeLayerTreeHost> host_;
7768 scoped_refptr<Layer> root_;
7769 scoped_refptr<Layer> child_;
7770 scoped_refptr<Layer> grand_child_;
7771 };
7772
TEST_P(LCDTextTest,CanUseLCDText)7773 TEST_P(LCDTextTest, CanUseLCDText) {
7774 // Case 1: Identity transform.
7775 gfx::Transform identity_matrix;
7776 ExecuteCalculateDrawProperties(
7777 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7778 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7779 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
7780 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
7781
7782 // Case 2: Integral translation.
7783 gfx::Transform integral_translation;
7784 integral_translation.Translate(1.0, 2.0);
7785 child_->SetTransform(integral_translation);
7786 ExecuteCalculateDrawProperties(
7787 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7788 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7789 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
7790 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
7791
7792 // Case 3: Non-integral translation.
7793 gfx::Transform non_integral_translation;
7794 non_integral_translation.Translate(1.5, 2.5);
7795 child_->SetTransform(non_integral_translation);
7796 ExecuteCalculateDrawProperties(
7797 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7798 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7799 EXPECT_FALSE(child_->can_use_lcd_text());
7800 EXPECT_FALSE(grand_child_->can_use_lcd_text());
7801
7802 // Case 4: Rotation.
7803 gfx::Transform rotation;
7804 rotation.Rotate(10.0);
7805 child_->SetTransform(rotation);
7806 ExecuteCalculateDrawProperties(
7807 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7808 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7809 EXPECT_FALSE(child_->can_use_lcd_text());
7810 EXPECT_FALSE(grand_child_->can_use_lcd_text());
7811
7812 // Case 5: Scale.
7813 gfx::Transform scale;
7814 scale.Scale(2.0, 2.0);
7815 child_->SetTransform(scale);
7816 ExecuteCalculateDrawProperties(
7817 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7818 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7819 EXPECT_FALSE(child_->can_use_lcd_text());
7820 EXPECT_FALSE(grand_child_->can_use_lcd_text());
7821
7822 // Case 6: Skew.
7823 gfx::Transform skew;
7824 skew.SkewX(10.0);
7825 child_->SetTransform(skew);
7826 ExecuteCalculateDrawProperties(
7827 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7828 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7829 EXPECT_FALSE(child_->can_use_lcd_text());
7830 EXPECT_FALSE(grand_child_->can_use_lcd_text());
7831
7832 // Case 7: Translucent.
7833 child_->SetTransform(identity_matrix);
7834 child_->SetOpacity(0.5f);
7835 ExecuteCalculateDrawProperties(
7836 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7837 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7838 EXPECT_FALSE(child_->can_use_lcd_text());
7839 EXPECT_FALSE(grand_child_->can_use_lcd_text());
7840
7841 // Case 8: Sanity check: restore transform and opacity.
7842 child_->SetTransform(identity_matrix);
7843 child_->SetOpacity(1.f);
7844 ExecuteCalculateDrawProperties(
7845 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7846 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7847 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
7848 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
7849 }
7850
TEST_P(LCDTextTest,CanUseLCDTextWithAnimation)7851 TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) {
7852 // Sanity check: Make sure can_use_lcd_text_ is set on each node.
7853 ExecuteCalculateDrawProperties(
7854 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7855 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7856 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
7857 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
7858
7859 // Add opacity animation.
7860 child_->SetOpacity(0.9f);
7861 AddOpacityTransitionToController(
7862 child_->layer_animation_controller(), 10.0, 0.9f, 0.1f, false);
7863
7864 ExecuteCalculateDrawProperties(
7865 root_.get(), 1.f, 1.f, NULL, can_use_lcd_text_);
7866 // Text AA should not be adjusted while animation is active.
7867 // Make sure LCD text AA setting remains unchanged.
7868 EXPECT_EQ(can_use_lcd_text_, root_->can_use_lcd_text());
7869 EXPECT_EQ(can_use_lcd_text_, child_->can_use_lcd_text());
7870 EXPECT_EQ(can_use_lcd_text_, grand_child_->can_use_lcd_text());
7871 }
7872
7873 INSTANTIATE_TEST_CASE_P(LayerTreeHostCommonTest,
7874 LCDTextTest,
7875 testing::Combine(testing::Bool(), testing::Bool()));
7876
TEST_F(LayerTreeHostCommonTest,SubtreeHidden_SingleLayer)7877 TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayer) {
7878 FakeImplProxy proxy;
7879 FakeLayerTreeHostImpl host_impl(&proxy);
7880 host_impl.CreatePendingTree();
7881 const gfx::Transform identity_matrix;
7882
7883 scoped_refptr<Layer> root = Layer::Create();
7884 SetLayerPropertiesForTesting(root.get(),
7885 identity_matrix,
7886 identity_matrix,
7887 gfx::PointF(),
7888 gfx::PointF(),
7889 gfx::Size(50, 50),
7890 false);
7891 root->SetIsDrawable(true);
7892
7893 scoped_refptr<Layer> child = Layer::Create();
7894 SetLayerPropertiesForTesting(child.get(),
7895 identity_matrix,
7896 identity_matrix,
7897 gfx::PointF(),
7898 gfx::PointF(),
7899 gfx::Size(40, 40),
7900 false);
7901 child->SetIsDrawable(true);
7902
7903 scoped_refptr<Layer> grand_child = Layer::Create();
7904 SetLayerPropertiesForTesting(grand_child.get(),
7905 identity_matrix,
7906 identity_matrix,
7907 gfx::PointF(),
7908 gfx::PointF(),
7909 gfx::Size(30, 30),
7910 false);
7911 grand_child->SetIsDrawable(true);
7912 grand_child->SetHideLayerAndSubtree(true);
7913
7914 child->AddChild(grand_child);
7915 root->AddChild(child);
7916
7917 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
7918 host->SetRootLayer(root);
7919
7920 RenderSurfaceLayerList render_surface_layer_list;
7921 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
7922 root.get(), root->bounds(), &render_surface_layer_list);
7923 inputs.can_adjust_raster_scales = true;
7924 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
7925
7926 // We should have one render surface and two layers. The grand child has
7927 // hidden itself.
7928 ASSERT_EQ(1u, render_surface_layer_list.size());
7929 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
7930 EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
7931 EXPECT_EQ(child->id(), root->render_surface()->layer_list().at(1)->id());
7932 }
7933
TEST_F(LayerTreeHostCommonTest,SubtreeHidden_SingleLayerImpl)7934 TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) {
7935 FakeImplProxy proxy;
7936 FakeLayerTreeHostImpl host_impl(&proxy);
7937 host_impl.CreatePendingTree();
7938 const gfx::Transform identity_matrix;
7939
7940 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1);
7941 SetLayerPropertiesForTesting(root.get(),
7942 identity_matrix,
7943 identity_matrix,
7944 gfx::PointF(),
7945 gfx::PointF(),
7946 gfx::Size(50, 50),
7947 false);
7948 root->SetDrawsContent(true);
7949
7950 scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2);
7951 SetLayerPropertiesForTesting(child.get(),
7952 identity_matrix,
7953 identity_matrix,
7954 gfx::PointF(),
7955 gfx::PointF(),
7956 gfx::Size(40, 40),
7957 false);
7958 child->SetDrawsContent(true);
7959
7960 scoped_ptr<LayerImpl> grand_child =
7961 LayerImpl::Create(host_impl.pending_tree(), 3);
7962 SetLayerPropertiesForTesting(grand_child.get(),
7963 identity_matrix,
7964 identity_matrix,
7965 gfx::PointF(),
7966 gfx::PointF(),
7967 gfx::Size(30, 30),
7968 false);
7969 grand_child->SetDrawsContent(true);
7970 grand_child->SetHideLayerAndSubtree(true);
7971
7972 child->AddChild(grand_child.Pass());
7973 root->AddChild(child.Pass());
7974
7975 LayerImplList render_surface_layer_list;
7976 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
7977 root.get(), root->bounds(), &render_surface_layer_list);
7978 inputs.can_adjust_raster_scales = true;
7979 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
7980
7981 // We should have one render surface and two layers. The grand child has
7982 // hidden itself.
7983 ASSERT_EQ(1u, render_surface_layer_list.size());
7984 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
7985 EXPECT_EQ(1, root->render_surface()->layer_list().at(0)->id());
7986 EXPECT_EQ(2, root->render_surface()->layer_list().at(1)->id());
7987 }
7988
TEST_F(LayerTreeHostCommonTest,SubtreeHidden_TwoLayers)7989 TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayers) {
7990 FakeImplProxy proxy;
7991 FakeLayerTreeHostImpl host_impl(&proxy);
7992 host_impl.CreatePendingTree();
7993 const gfx::Transform identity_matrix;
7994
7995 scoped_refptr<Layer> root = Layer::Create();
7996 SetLayerPropertiesForTesting(root.get(),
7997 identity_matrix,
7998 identity_matrix,
7999 gfx::PointF(),
8000 gfx::PointF(),
8001 gfx::Size(50, 50),
8002 false);
8003 root->SetIsDrawable(true);
8004
8005 scoped_refptr<Layer> child = Layer::Create();
8006 SetLayerPropertiesForTesting(child.get(),
8007 identity_matrix,
8008 identity_matrix,
8009 gfx::PointF(),
8010 gfx::PointF(),
8011 gfx::Size(40, 40),
8012 false);
8013 child->SetIsDrawable(true);
8014 child->SetHideLayerAndSubtree(true);
8015
8016 scoped_refptr<Layer> grand_child = Layer::Create();
8017 SetLayerPropertiesForTesting(grand_child.get(),
8018 identity_matrix,
8019 identity_matrix,
8020 gfx::PointF(),
8021 gfx::PointF(),
8022 gfx::Size(30, 30),
8023 false);
8024 grand_child->SetIsDrawable(true);
8025
8026 child->AddChild(grand_child);
8027 root->AddChild(child);
8028
8029 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
8030 host->SetRootLayer(root);
8031
8032 RenderSurfaceLayerList render_surface_layer_list;
8033 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
8034 root.get(), root->bounds(), &render_surface_layer_list);
8035 inputs.can_adjust_raster_scales = true;
8036 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
8037
8038 // We should have one render surface and one layers. The child has
8039 // hidden itself and the grand child.
8040 ASSERT_EQ(1u, render_surface_layer_list.size());
8041 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
8042 EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
8043 }
8044
TEST_F(LayerTreeHostCommonTest,SubtreeHidden_TwoLayersImpl)8045 TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) {
8046 FakeImplProxy proxy;
8047 FakeLayerTreeHostImpl host_impl(&proxy);
8048 host_impl.CreatePendingTree();
8049 const gfx::Transform identity_matrix;
8050
8051 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1);
8052 SetLayerPropertiesForTesting(root.get(),
8053 identity_matrix,
8054 identity_matrix,
8055 gfx::PointF(),
8056 gfx::PointF(),
8057 gfx::Size(50, 50),
8058 false);
8059 root->SetDrawsContent(true);
8060
8061 scoped_ptr<LayerImpl> child = LayerImpl::Create(host_impl.pending_tree(), 2);
8062 SetLayerPropertiesForTesting(child.get(),
8063 identity_matrix,
8064 identity_matrix,
8065 gfx::PointF(),
8066 gfx::PointF(),
8067 gfx::Size(40, 40),
8068 false);
8069 child->SetDrawsContent(true);
8070 child->SetHideLayerAndSubtree(true);
8071
8072 scoped_ptr<LayerImpl> grand_child =
8073 LayerImpl::Create(host_impl.pending_tree(), 3);
8074 SetLayerPropertiesForTesting(grand_child.get(),
8075 identity_matrix,
8076 identity_matrix,
8077 gfx::PointF(),
8078 gfx::PointF(),
8079 gfx::Size(30, 30),
8080 false);
8081 grand_child->SetDrawsContent(true);
8082
8083 child->AddChild(grand_child.Pass());
8084 root->AddChild(child.Pass());
8085
8086 LayerImplList render_surface_layer_list;
8087 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
8088 root.get(), root->bounds(), &render_surface_layer_list);
8089 inputs.can_adjust_raster_scales = true;
8090 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
8091
8092 // We should have one render surface and one layers. The child has
8093 // hidden itself and the grand child.
8094 ASSERT_EQ(1u, render_surface_layer_list.size());
8095 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
8096 EXPECT_EQ(1, root->render_surface()->layer_list().at(0)->id());
8097 }
8098
EmptyCopyOutputCallback(scoped_ptr<CopyOutputResult> result)8099 void EmptyCopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}
8100
TEST_F(LayerTreeHostCommonTest,SubtreeHiddenWithCopyRequest)8101 TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) {
8102 FakeImplProxy proxy;
8103 FakeLayerTreeHostImpl host_impl(&proxy);
8104 host_impl.CreatePendingTree();
8105 const gfx::Transform identity_matrix;
8106
8107 scoped_refptr<Layer> root = Layer::Create();
8108 SetLayerPropertiesForTesting(root.get(),
8109 identity_matrix,
8110 identity_matrix,
8111 gfx::PointF(),
8112 gfx::PointF(),
8113 gfx::Size(50, 50),
8114 false);
8115 root->SetIsDrawable(true);
8116
8117 scoped_refptr<Layer> copy_grand_parent = Layer::Create();
8118 SetLayerPropertiesForTesting(copy_grand_parent.get(),
8119 identity_matrix,
8120 identity_matrix,
8121 gfx::PointF(),
8122 gfx::PointF(),
8123 gfx::Size(40, 40),
8124 false);
8125 copy_grand_parent->SetIsDrawable(true);
8126
8127 scoped_refptr<Layer> copy_parent = Layer::Create();
8128 SetLayerPropertiesForTesting(copy_parent.get(),
8129 identity_matrix,
8130 identity_matrix,
8131 gfx::PointF(),
8132 gfx::PointF(),
8133 gfx::Size(30, 30),
8134 false);
8135 copy_parent->SetIsDrawable(true);
8136 copy_parent->SetForceRenderSurface(true);
8137
8138 scoped_refptr<Layer> copy_layer = Layer::Create();
8139 SetLayerPropertiesForTesting(copy_layer.get(),
8140 identity_matrix,
8141 identity_matrix,
8142 gfx::PointF(),
8143 gfx::PointF(),
8144 gfx::Size(20, 20),
8145 false);
8146 copy_layer->SetIsDrawable(true);
8147
8148 scoped_refptr<Layer> copy_child = Layer::Create();
8149 SetLayerPropertiesForTesting(copy_child.get(),
8150 identity_matrix,
8151 identity_matrix,
8152 gfx::PointF(),
8153 gfx::PointF(),
8154 gfx::Size(20, 20),
8155 false);
8156 copy_child->SetIsDrawable(true);
8157
8158 scoped_refptr<Layer> copy_grand_parent_sibling_before = Layer::Create();
8159 SetLayerPropertiesForTesting(copy_grand_parent_sibling_before.get(),
8160 identity_matrix,
8161 identity_matrix,
8162 gfx::PointF(),
8163 gfx::PointF(),
8164 gfx::Size(40, 40),
8165 false);
8166 copy_grand_parent_sibling_before->SetIsDrawable(true);
8167
8168 scoped_refptr<Layer> copy_grand_parent_sibling_after = Layer::Create();
8169 SetLayerPropertiesForTesting(copy_grand_parent_sibling_after.get(),
8170 identity_matrix,
8171 identity_matrix,
8172 gfx::PointF(),
8173 gfx::PointF(),
8174 gfx::Size(40, 40),
8175 false);
8176 copy_grand_parent_sibling_after->SetIsDrawable(true);
8177
8178 copy_layer->AddChild(copy_child);
8179 copy_parent->AddChild(copy_layer);
8180 copy_grand_parent->AddChild(copy_parent);
8181 root->AddChild(copy_grand_parent_sibling_before);
8182 root->AddChild(copy_grand_parent);
8183 root->AddChild(copy_grand_parent_sibling_after);
8184
8185 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
8186 host->SetRootLayer(root);
8187
8188 // Hide the copy_grand_parent and its subtree. But make a copy request in that
8189 // hidden subtree on copy_layer.
8190 copy_grand_parent->SetHideLayerAndSubtree(true);
8191 copy_grand_parent_sibling_before->SetHideLayerAndSubtree(true);
8192 copy_grand_parent_sibling_after->SetHideLayerAndSubtree(true);
8193 copy_layer->RequestCopyOfOutput(CopyOutputRequest::CreateRequest(
8194 base::Bind(&EmptyCopyOutputCallback)));
8195 EXPECT_TRUE(copy_layer->HasCopyRequest());
8196
8197 RenderSurfaceLayerList render_surface_layer_list;
8198 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
8199 root.get(), root->bounds(), &render_surface_layer_list);
8200 inputs.can_adjust_raster_scales = true;
8201 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
8202
8203 EXPECT_TRUE(root->draw_properties().layer_or_descendant_has_copy_request);
8204 EXPECT_TRUE(copy_grand_parent->draw_properties().
8205 layer_or_descendant_has_copy_request);
8206 EXPECT_TRUE(copy_parent->draw_properties().
8207 layer_or_descendant_has_copy_request);
8208 EXPECT_TRUE(copy_layer->draw_properties().
8209 layer_or_descendant_has_copy_request);
8210 EXPECT_FALSE(copy_child->draw_properties().
8211 layer_or_descendant_has_copy_request);
8212 EXPECT_FALSE(copy_grand_parent_sibling_before->draw_properties().
8213 layer_or_descendant_has_copy_request);
8214 EXPECT_FALSE(copy_grand_parent_sibling_after->draw_properties().
8215 layer_or_descendant_has_copy_request);
8216
8217 // We should have three render surfaces, one for the root, one for the parent
8218 // since it owns a surface, and one for the copy_layer.
8219 ASSERT_EQ(3u, render_surface_layer_list.size());
8220 EXPECT_EQ(root->id(), render_surface_layer_list.at(0)->id());
8221 EXPECT_EQ(copy_parent->id(), render_surface_layer_list.at(1)->id());
8222 EXPECT_EQ(copy_layer->id(), render_surface_layer_list.at(2)->id());
8223
8224 // The root render surface should have 2 contributing layers. The
8225 // copy_grand_parent is hidden along with its siblings, but the copy_parent
8226 // will appear since something in its subtree needs to be drawn for a copy
8227 // request.
8228 ASSERT_EQ(2u, root->render_surface()->layer_list().size());
8229 EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
8230 EXPECT_EQ(copy_parent->id(),
8231 root->render_surface()->layer_list().at(1)->id());
8232
8233 // Nothing actually drawns into the copy parent, so only the copy_layer will
8234 // appear in its list, since it needs to be drawn for the copy request.
8235 ASSERT_EQ(1u, copy_parent->render_surface()->layer_list().size());
8236 EXPECT_EQ(copy_layer->id(),
8237 copy_parent->render_surface()->layer_list().at(0)->id());
8238
8239 // The copy_layer's render surface should have two contributing layers.
8240 ASSERT_EQ(2u, copy_layer->render_surface()->layer_list().size());
8241 EXPECT_EQ(copy_layer->id(),
8242 copy_layer->render_surface()->layer_list().at(0)->id());
8243 EXPECT_EQ(copy_child->id(),
8244 copy_layer->render_surface()->layer_list().at(1)->id());
8245 }
8246
TEST_F(LayerTreeHostCommonTest,ClippedOutCopyRequest)8247 TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) {
8248 FakeImplProxy proxy;
8249 FakeLayerTreeHostImpl host_impl(&proxy);
8250 host_impl.CreatePendingTree();
8251 const gfx::Transform identity_matrix;
8252
8253 scoped_refptr<Layer> root = Layer::Create();
8254 SetLayerPropertiesForTesting(root.get(),
8255 identity_matrix,
8256 identity_matrix,
8257 gfx::PointF(),
8258 gfx::PointF(),
8259 gfx::Size(50, 50),
8260 false);
8261 root->SetIsDrawable(true);
8262
8263 scoped_refptr<Layer> copy_parent = Layer::Create();
8264 SetLayerPropertiesForTesting(copy_parent.get(),
8265 identity_matrix,
8266 identity_matrix,
8267 gfx::PointF(),
8268 gfx::PointF(),
8269 gfx::Size(),
8270 false);
8271 copy_parent->SetIsDrawable(true);
8272 copy_parent->SetMasksToBounds(true);
8273
8274 scoped_refptr<Layer> copy_layer = Layer::Create();
8275 SetLayerPropertiesForTesting(copy_layer.get(),
8276 identity_matrix,
8277 identity_matrix,
8278 gfx::PointF(),
8279 gfx::PointF(),
8280 gfx::Size(30, 30),
8281 false);
8282 copy_layer->SetIsDrawable(true);
8283
8284 scoped_refptr<Layer> copy_child = Layer::Create();
8285 SetLayerPropertiesForTesting(copy_child.get(),
8286 identity_matrix,
8287 identity_matrix,
8288 gfx::PointF(),
8289 gfx::PointF(),
8290 gfx::Size(20, 20),
8291 false);
8292 copy_child->SetIsDrawable(true);
8293
8294 copy_layer->AddChild(copy_child);
8295 copy_parent->AddChild(copy_layer);
8296 root->AddChild(copy_parent);
8297
8298 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
8299 host->SetRootLayer(root);
8300
8301 copy_layer->RequestCopyOfOutput(CopyOutputRequest::CreateRequest(
8302 base::Bind(&EmptyCopyOutputCallback)));
8303 EXPECT_TRUE(copy_layer->HasCopyRequest());
8304
8305 RenderSurfaceLayerList render_surface_layer_list;
8306 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
8307 root.get(), root->bounds(), &render_surface_layer_list);
8308 inputs.can_adjust_raster_scales = true;
8309 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
8310
8311 // We should have one render surface, as the others are clipped out.
8312 ASSERT_EQ(1u, render_surface_layer_list.size());
8313 EXPECT_EQ(root->id(), render_surface_layer_list.at(0)->id());
8314
8315 // The root render surface should only have 1 contributing layer, since the
8316 // other layers are empty/clipped away.
8317 ASSERT_EQ(1u, root->render_surface()->layer_list().size());
8318 EXPECT_EQ(root->id(), root->render_surface()->layer_list().at(0)->id());
8319 }
8320
TEST_F(LayerTreeHostCommonTest,VisibleContentRectInsideSurface)8321 TEST_F(LayerTreeHostCommonTest, VisibleContentRectInsideSurface) {
8322 FakeImplProxy proxy;
8323 FakeLayerTreeHostImpl host_impl(&proxy);
8324 host_impl.CreatePendingTree();
8325 const gfx::Transform identity_matrix;
8326
8327 scoped_refptr<Layer> root = Layer::Create();
8328 SetLayerPropertiesForTesting(root.get(),
8329 identity_matrix,
8330 identity_matrix,
8331 gfx::PointF(),
8332 gfx::PointF(),
8333 gfx::Size(50, 50),
8334 false);
8335 root->SetIsDrawable(true);
8336
8337 // The surface is moved slightly outside of the viewport.
8338 scoped_refptr<Layer> surface = Layer::Create();
8339 SetLayerPropertiesForTesting(surface.get(),
8340 identity_matrix,
8341 identity_matrix,
8342 gfx::PointF(),
8343 gfx::PointF(-10, -20),
8344 gfx::Size(),
8345 false);
8346 surface->SetForceRenderSurface(true);
8347
8348 scoped_refptr<Layer> surface_child = Layer::Create();
8349 SetLayerPropertiesForTesting(surface_child.get(),
8350 identity_matrix,
8351 identity_matrix,
8352 gfx::PointF(),
8353 gfx::PointF(),
8354 gfx::Size(50, 50),
8355 false);
8356 surface_child->SetIsDrawable(true);
8357
8358 surface->AddChild(surface_child);
8359 root->AddChild(surface);
8360
8361 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
8362 host->SetRootLayer(root);
8363
8364 RenderSurfaceLayerList render_surface_layer_list;
8365 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
8366 root.get(), root->bounds(), &render_surface_layer_list);
8367 inputs.can_adjust_raster_scales = true;
8368 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
8369
8370 // The visible_content_rect for the |surface_child| should not be clipped by
8371 // the viewport.
8372 EXPECT_EQ(gfx::Rect(50, 50).ToString(),
8373 surface_child->visible_content_rect().ToString());
8374 }
8375
TEST_F(LayerTreeHostCommonTest,TransformedClipParent)8376 TEST_F(LayerTreeHostCommonTest, TransformedClipParent) {
8377 // Ensure that a transform between the layer and its render surface is not a
8378 // problem. Constructs the following layer tree.
8379 //
8380 // root (a render surface)
8381 // + render_surface
8382 // + clip_parent (scaled)
8383 // + intervening_clipping_layer
8384 // + clip_child
8385 //
8386 // The render surface should be resized correctly and the clip child should
8387 // inherit the right clip rect.
8388 scoped_refptr<Layer> root = Layer::Create();
8389 scoped_refptr<Layer> render_surface = Layer::Create();
8390 scoped_refptr<Layer> clip_parent = Layer::Create();
8391 scoped_refptr<Layer> intervening = Layer::Create();
8392 scoped_refptr<LayerWithForcedDrawsContent> clip_child =
8393 make_scoped_refptr(new LayerWithForcedDrawsContent);
8394
8395 root->AddChild(render_surface);
8396 render_surface->AddChild(clip_parent);
8397 clip_parent->AddChild(intervening);
8398 intervening->AddChild(clip_child);
8399
8400 clip_child->SetClipParent(clip_parent.get());
8401
8402 intervening->SetMasksToBounds(true);
8403 clip_parent->SetMasksToBounds(true);
8404
8405 render_surface->SetForceRenderSurface(true);
8406
8407 gfx::Transform scale_transform;
8408 scale_transform.Scale(2, 2);
8409
8410 gfx::Transform identity_transform;
8411
8412 SetLayerPropertiesForTesting(root.get(),
8413 identity_transform,
8414 identity_transform,
8415 gfx::PointF(),
8416 gfx::PointF(),
8417 gfx::Size(50, 50),
8418 false);
8419 SetLayerPropertiesForTesting(render_surface.get(),
8420 identity_transform,
8421 identity_transform,
8422 gfx::PointF(),
8423 gfx::PointF(),
8424 gfx::Size(10, 10),
8425 false);
8426 SetLayerPropertiesForTesting(clip_parent.get(),
8427 scale_transform,
8428 identity_transform,
8429 gfx::PointF(),
8430 gfx::PointF(1.f, 1.f),
8431 gfx::Size(10, 10),
8432 false);
8433 SetLayerPropertiesForTesting(intervening.get(),
8434 identity_transform,
8435 identity_transform,
8436 gfx::PointF(),
8437 gfx::PointF(1.f, 1.f),
8438 gfx::Size(5, 5),
8439 false);
8440 SetLayerPropertiesForTesting(clip_child.get(),
8441 identity_transform,
8442 identity_transform,
8443 gfx::PointF(),
8444 gfx::PointF(1.f, 1.f),
8445 gfx::Size(10, 10),
8446 false);
8447
8448 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
8449 host->SetRootLayer(root);
8450
8451 ExecuteCalculateDrawProperties(root.get());
8452
8453 ASSERT_TRUE(root->render_surface());
8454 ASSERT_TRUE(render_surface->render_surface());
8455
8456 // Ensure that we've inherited our clip parent's clip and weren't affected
8457 // by the intervening clip layer.
8458 ASSERT_EQ(gfx::Rect(1, 1, 20, 20).ToString(),
8459 clip_parent->clip_rect().ToString());
8460 ASSERT_EQ(clip_parent->clip_rect().ToString(),
8461 clip_child->clip_rect().ToString());
8462 ASSERT_EQ(gfx::Rect(3, 3, 10, 10).ToString(),
8463 intervening->clip_rect().ToString());
8464
8465 // Ensure that the render surface reports a content rect that has been grown
8466 // to accomodate for the clip child.
8467 ASSERT_EQ(gfx::Rect(5, 5, 16, 16).ToString(),
8468 render_surface->render_surface()->content_rect().ToString());
8469
8470 // The above check implies the two below, but they nicely demonstrate that
8471 // we've grown, despite the intervening layer's clip.
8472 ASSERT_TRUE(clip_parent->clip_rect().Contains(
8473 render_surface->render_surface()->content_rect()));
8474 ASSERT_FALSE(intervening->clip_rect().Contains(
8475 render_surface->render_surface()->content_rect()));
8476 }
8477
TEST_F(LayerTreeHostCommonTest,ClipParentWithInterveningRenderSurface)8478 TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) {
8479 // Ensure that intervening render surfaces are not a problem in the basic
8480 // case. In the following tree, both render surfaces should be resized to
8481 // accomodate for the clip child, despite an intervening clip.
8482 //
8483 // root (a render surface)
8484 // + clip_parent (masks to bounds)
8485 // + render_surface1 (sets opacity)
8486 // + intervening (masks to bounds)
8487 // + render_surface2 (also sets opacity)
8488 // + clip_child
8489 //
8490 scoped_refptr<Layer> root = Layer::Create();
8491 scoped_refptr<Layer> clip_parent = Layer::Create();
8492 scoped_refptr<Layer> render_surface1 = Layer::Create();
8493 scoped_refptr<Layer> intervening = Layer::Create();
8494 scoped_refptr<Layer> render_surface2 = Layer::Create();
8495 scoped_refptr<LayerWithForcedDrawsContent> clip_child =
8496 make_scoped_refptr(new LayerWithForcedDrawsContent);
8497
8498 root->AddChild(clip_parent);
8499 clip_parent->AddChild(render_surface1);
8500 render_surface1->AddChild(intervening);
8501 intervening->AddChild(render_surface2);
8502 render_surface2->AddChild(clip_child);
8503
8504 clip_child->SetClipParent(clip_parent.get());
8505
8506 intervening->SetMasksToBounds(true);
8507 clip_parent->SetMasksToBounds(true);
8508
8509 render_surface1->SetForceRenderSurface(true);
8510 render_surface2->SetForceRenderSurface(true);
8511
8512 gfx::Transform translation_transform;
8513 translation_transform.Translate(2, 2);
8514
8515 gfx::Transform identity_transform;
8516 SetLayerPropertiesForTesting(root.get(),
8517 identity_transform,
8518 identity_transform,
8519 gfx::PointF(),
8520 gfx::PointF(),
8521 gfx::Size(50, 50),
8522 false);
8523 SetLayerPropertiesForTesting(clip_parent.get(),
8524 translation_transform,
8525 identity_transform,
8526 gfx::PointF(),
8527 gfx::PointF(1.f, 1.f),
8528 gfx::Size(40, 40),
8529 false);
8530 SetLayerPropertiesForTesting(render_surface1.get(),
8531 identity_transform,
8532 identity_transform,
8533 gfx::PointF(),
8534 gfx::PointF(),
8535 gfx::Size(10, 10),
8536 false);
8537 SetLayerPropertiesForTesting(intervening.get(),
8538 identity_transform,
8539 identity_transform,
8540 gfx::PointF(),
8541 gfx::PointF(1.f, 1.f),
8542 gfx::Size(5, 5),
8543 false);
8544 SetLayerPropertiesForTesting(render_surface2.get(),
8545 identity_transform,
8546 identity_transform,
8547 gfx::PointF(),
8548 gfx::PointF(),
8549 gfx::Size(10, 10),
8550 false);
8551 SetLayerPropertiesForTesting(clip_child.get(),
8552 identity_transform,
8553 identity_transform,
8554 gfx::PointF(),
8555 gfx::PointF(-10.f, -10.f),
8556 gfx::Size(60, 60),
8557 false);
8558
8559 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
8560 host->SetRootLayer(root);
8561
8562 ExecuteCalculateDrawProperties(root.get());
8563
8564 EXPECT_TRUE(root->render_surface());
8565 EXPECT_TRUE(render_surface1->render_surface());
8566 EXPECT_TRUE(render_surface2->render_surface());
8567
8568 // Since the render surfaces could have expanded, they should not clip (their
8569 // bounds would no longer be reliable). We should resort to layer clipping
8570 // in this case.
8571 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
8572 render_surface1->render_surface()->clip_rect().ToString());
8573 EXPECT_FALSE(render_surface1->render_surface()->is_clipped());
8574 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
8575 render_surface2->render_surface()->clip_rect().ToString());
8576 EXPECT_FALSE(render_surface2->render_surface()->is_clipped());
8577
8578 // NB: clip rects are in target space.
8579 EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
8580 render_surface1->clip_rect().ToString());
8581 EXPECT_TRUE(render_surface1->is_clipped());
8582
8583 // This value is inherited from the clipping ancestor layer, 'intervening'.
8584 EXPECT_EQ(gfx::Rect(0, 0, 5, 5).ToString(),
8585 render_surface2->clip_rect().ToString());
8586 EXPECT_TRUE(render_surface2->is_clipped());
8587
8588 // The content rects of both render surfaces should both have expanded to
8589 // contain the clip child.
8590 EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
8591 render_surface1->render_surface()->content_rect().ToString());
8592 EXPECT_EQ(gfx::Rect(-1, -1, 40, 40).ToString(),
8593 render_surface2->render_surface()->content_rect().ToString());
8594
8595 // The clip child should have inherited the clip parent's clip (projected to
8596 // the right space, of course), and should have the correctly sized visible
8597 // content rect.
8598 EXPECT_EQ(gfx::Rect(-1, -1, 40, 40).ToString(),
8599 clip_child->clip_rect().ToString());
8600 EXPECT_EQ(gfx::Rect(9, 9, 40, 40).ToString(),
8601 clip_child->visible_content_rect().ToString());
8602 EXPECT_TRUE(clip_child->is_clipped());
8603 }
8604
TEST_F(LayerTreeHostCommonTest,ClipParentScrolledInterveningLayer)8605 TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) {
8606 // Ensure that intervening render surfaces are not a problem, even if there
8607 // is a scroll involved. Note, we do _not_ have to consider any other sort
8608 // of transform.
8609 //
8610 // root (a render surface)
8611 // + clip_parent (masks to bounds)
8612 // + render_surface1 (sets opacity)
8613 // + intervening (masks to bounds AND scrolls)
8614 // + render_surface2 (also sets opacity)
8615 // + clip_child
8616 //
8617 scoped_refptr<Layer> root = Layer::Create();
8618 scoped_refptr<Layer> clip_parent = Layer::Create();
8619 scoped_refptr<Layer> render_surface1 = Layer::Create();
8620 scoped_refptr<Layer> intervening = Layer::Create();
8621 scoped_refptr<Layer> render_surface2 = Layer::Create();
8622 scoped_refptr<LayerWithForcedDrawsContent> clip_child =
8623 make_scoped_refptr(new LayerWithForcedDrawsContent);
8624
8625 root->AddChild(clip_parent);
8626 clip_parent->AddChild(render_surface1);
8627 render_surface1->AddChild(intervening);
8628 intervening->AddChild(render_surface2);
8629 render_surface2->AddChild(clip_child);
8630
8631 clip_child->SetClipParent(clip_parent.get());
8632
8633 intervening->SetMasksToBounds(true);
8634 clip_parent->SetMasksToBounds(true);
8635 intervening->SetScrollable(true);
8636 intervening->SetMaxScrollOffset(gfx::Vector2d(50, 50));
8637 intervening->SetScrollOffset(gfx::Vector2d(3, 3));
8638
8639 render_surface1->SetForceRenderSurface(true);
8640 render_surface2->SetForceRenderSurface(true);
8641
8642 gfx::Transform translation_transform;
8643 translation_transform.Translate(2, 2);
8644
8645 gfx::Transform identity_transform;
8646 SetLayerPropertiesForTesting(root.get(),
8647 identity_transform,
8648 identity_transform,
8649 gfx::PointF(),
8650 gfx::PointF(),
8651 gfx::Size(50, 50),
8652 false);
8653 SetLayerPropertiesForTesting(clip_parent.get(),
8654 translation_transform,
8655 identity_transform,
8656 gfx::PointF(),
8657 gfx::PointF(1.f, 1.f),
8658 gfx::Size(40, 40),
8659 false);
8660 SetLayerPropertiesForTesting(render_surface1.get(),
8661 identity_transform,
8662 identity_transform,
8663 gfx::PointF(),
8664 gfx::PointF(),
8665 gfx::Size(10, 10),
8666 false);
8667 SetLayerPropertiesForTesting(intervening.get(),
8668 identity_transform,
8669 identity_transform,
8670 gfx::PointF(),
8671 gfx::PointF(1.f, 1.f),
8672 gfx::Size(5, 5),
8673 false);
8674 SetLayerPropertiesForTesting(render_surface2.get(),
8675 identity_transform,
8676 identity_transform,
8677 gfx::PointF(),
8678 gfx::PointF(),
8679 gfx::Size(10, 10),
8680 false);
8681 SetLayerPropertiesForTesting(clip_child.get(),
8682 identity_transform,
8683 identity_transform,
8684 gfx::PointF(),
8685 gfx::PointF(-10.f, -10.f),
8686 gfx::Size(60, 60),
8687 false);
8688
8689 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
8690 host->SetRootLayer(root);
8691
8692 ExecuteCalculateDrawProperties(root.get());
8693
8694 EXPECT_TRUE(root->render_surface());
8695 EXPECT_TRUE(render_surface1->render_surface());
8696 EXPECT_TRUE(render_surface2->render_surface());
8697
8698 // Since the render surfaces could have expanded, they should not clip (their
8699 // bounds would no longer be reliable). We should resort to layer clipping
8700 // in this case.
8701 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
8702 render_surface1->render_surface()->clip_rect().ToString());
8703 EXPECT_FALSE(render_surface1->render_surface()->is_clipped());
8704 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
8705 render_surface2->render_surface()->clip_rect().ToString());
8706 EXPECT_FALSE(render_surface2->render_surface()->is_clipped());
8707
8708 // NB: clip rects are in target space.
8709 EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
8710 render_surface1->clip_rect().ToString());
8711 EXPECT_TRUE(render_surface1->is_clipped());
8712
8713 // This value is inherited from the clipping ancestor layer, 'intervening'.
8714 EXPECT_EQ(gfx::Rect(2, 2, 3, 3).ToString(),
8715 render_surface2->clip_rect().ToString());
8716 EXPECT_TRUE(render_surface2->is_clipped());
8717
8718 // The content rects of both render surfaces should both have expanded to
8719 // contain the clip child.
8720 EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
8721 render_surface1->render_surface()->content_rect().ToString());
8722 EXPECT_EQ(gfx::Rect(2, 2, 40, 40).ToString(),
8723 render_surface2->render_surface()->content_rect().ToString());
8724
8725 // The clip child should have inherited the clip parent's clip (projected to
8726 // the right space, of course), and should have the correctly sized visible
8727 // content rect.
8728 EXPECT_EQ(gfx::Rect(2, 2, 40, 40).ToString(),
8729 clip_child->clip_rect().ToString());
8730 EXPECT_EQ(gfx::Rect(12, 12, 40, 40).ToString(),
8731 clip_child->visible_content_rect().ToString());
8732 EXPECT_TRUE(clip_child->is_clipped());
8733 }
8734
TEST_F(LayerTreeHostCommonTest,DescendantsOfClipChildren)8735 TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) {
8736 // Ensures that descendants of the clip child inherit the correct clip.
8737 //
8738 // root (a render surface)
8739 // + clip_parent (masks to bounds)
8740 // + intervening (masks to bounds)
8741 // + clip_child
8742 // + child
8743 //
8744 scoped_refptr<Layer> root = Layer::Create();
8745 scoped_refptr<Layer> clip_parent = Layer::Create();
8746 scoped_refptr<Layer> intervening = Layer::Create();
8747 scoped_refptr<Layer> clip_child = Layer::Create();
8748 scoped_refptr<LayerWithForcedDrawsContent> child =
8749 make_scoped_refptr(new LayerWithForcedDrawsContent);
8750
8751 root->AddChild(clip_parent);
8752 clip_parent->AddChild(intervening);
8753 intervening->AddChild(clip_child);
8754 clip_child->AddChild(child);
8755
8756 clip_child->SetClipParent(clip_parent.get());
8757
8758 intervening->SetMasksToBounds(true);
8759 clip_parent->SetMasksToBounds(true);
8760
8761 gfx::Transform identity_transform;
8762 SetLayerPropertiesForTesting(root.get(),
8763 identity_transform,
8764 identity_transform,
8765 gfx::PointF(),
8766 gfx::PointF(),
8767 gfx::Size(50, 50),
8768 false);
8769 SetLayerPropertiesForTesting(clip_parent.get(),
8770 identity_transform,
8771 identity_transform,
8772 gfx::PointF(),
8773 gfx::PointF(),
8774 gfx::Size(40, 40),
8775 false);
8776 SetLayerPropertiesForTesting(intervening.get(),
8777 identity_transform,
8778 identity_transform,
8779 gfx::PointF(),
8780 gfx::PointF(),
8781 gfx::Size(5, 5),
8782 false);
8783 SetLayerPropertiesForTesting(clip_child.get(),
8784 identity_transform,
8785 identity_transform,
8786 gfx::PointF(),
8787 gfx::PointF(),
8788 gfx::Size(60, 60),
8789 false);
8790 SetLayerPropertiesForTesting(child.get(),
8791 identity_transform,
8792 identity_transform,
8793 gfx::PointF(),
8794 gfx::PointF(),
8795 gfx::Size(60, 60),
8796 false);
8797
8798 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
8799 host->SetRootLayer(root);
8800
8801 ExecuteCalculateDrawProperties(root.get());
8802
8803 EXPECT_TRUE(root->render_surface());
8804
8805 // Neither the clip child nor its descendant should have inherited the clip
8806 // from |intervening|.
8807 EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
8808 clip_child->clip_rect().ToString());
8809 EXPECT_TRUE(clip_child->is_clipped());
8810 EXPECT_EQ(gfx::Rect(0, 0, 40, 40).ToString(),
8811 child->visible_content_rect().ToString());
8812 EXPECT_TRUE(child->is_clipped());
8813 }
8814
TEST_F(LayerTreeHostCommonTest,SurfacesShouldBeUnaffectedByNonDescendantClipChildren)8815 TEST_F(LayerTreeHostCommonTest,
8816 SurfacesShouldBeUnaffectedByNonDescendantClipChildren) {
8817 // Ensures that non-descendant clip children in the tree do not affect
8818 // render surfaces.
8819 //
8820 // root (a render surface)
8821 // + clip_parent (masks to bounds)
8822 // + render_surface1
8823 // + clip_child
8824 // + render_surface2
8825 // + non_clip_child
8826 //
8827 // In this example render_surface2 should be unaffected by clip_child.
8828 scoped_refptr<Layer> root = Layer::Create();
8829 scoped_refptr<Layer> clip_parent = Layer::Create();
8830 scoped_refptr<Layer> render_surface1 = Layer::Create();
8831 scoped_refptr<LayerWithForcedDrawsContent> clip_child =
8832 make_scoped_refptr(new LayerWithForcedDrawsContent);
8833 scoped_refptr<Layer> render_surface2 = Layer::Create();
8834 scoped_refptr<LayerWithForcedDrawsContent> non_clip_child =
8835 make_scoped_refptr(new LayerWithForcedDrawsContent);
8836
8837 root->AddChild(clip_parent);
8838 clip_parent->AddChild(render_surface1);
8839 render_surface1->AddChild(clip_child);
8840 clip_parent->AddChild(render_surface2);
8841 render_surface2->AddChild(non_clip_child);
8842
8843 clip_child->SetClipParent(clip_parent.get());
8844
8845 clip_parent->SetMasksToBounds(true);
8846 render_surface1->SetMasksToBounds(true);
8847
8848 gfx::Transform identity_transform;
8849 SetLayerPropertiesForTesting(root.get(),
8850 identity_transform,
8851 identity_transform,
8852 gfx::PointF(),
8853 gfx::PointF(),
8854 gfx::Size(15, 15),
8855 false);
8856 SetLayerPropertiesForTesting(clip_parent.get(),
8857 identity_transform,
8858 identity_transform,
8859 gfx::PointF(),
8860 gfx::PointF(),
8861 gfx::Size(10, 10),
8862 false);
8863 SetLayerPropertiesForTesting(render_surface1.get(),
8864 identity_transform,
8865 identity_transform,
8866 gfx::PointF(),
8867 gfx::PointF(5, 5),
8868 gfx::Size(5, 5),
8869 false);
8870 SetLayerPropertiesForTesting(render_surface2.get(),
8871 identity_transform,
8872 identity_transform,
8873 gfx::PointF(),
8874 gfx::PointF(),
8875 gfx::Size(5, 5),
8876 false);
8877 SetLayerPropertiesForTesting(clip_child.get(),
8878 identity_transform,
8879 identity_transform,
8880 gfx::PointF(),
8881 gfx::PointF(-1, 1),
8882 gfx::Size(10, 10),
8883 false);
8884 SetLayerPropertiesForTesting(non_clip_child.get(),
8885 identity_transform,
8886 identity_transform,
8887 gfx::PointF(),
8888 gfx::PointF(),
8889 gfx::Size(5, 5),
8890 false);
8891
8892 render_surface1->SetForceRenderSurface(true);
8893 render_surface2->SetForceRenderSurface(true);
8894
8895 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
8896 host->SetRootLayer(root);
8897
8898 ExecuteCalculateDrawProperties(root.get());
8899
8900 EXPECT_TRUE(root->render_surface());
8901 EXPECT_TRUE(render_surface1->render_surface());
8902 EXPECT_TRUE(render_surface2->render_surface());
8903
8904 EXPECT_EQ(gfx::Rect(0, 0, 5, 5).ToString(),
8905 render_surface1->clip_rect().ToString());
8906 EXPECT_TRUE(render_surface1->is_clipped());
8907
8908 // The render surface should not clip (it has unclipped descendants), instead
8909 // it should rely on layer clipping.
8910 EXPECT_EQ(gfx::Rect(0, 0, 0, 0).ToString(),
8911 render_surface1->render_surface()->clip_rect().ToString());
8912 EXPECT_FALSE(render_surface1->render_surface()->is_clipped());
8913
8914 // That said, it should have grown to accomodate the unclipped descendant.
8915 EXPECT_EQ(gfx::Rect(-1, 1, 6, 4).ToString(),
8916 render_surface1->render_surface()->content_rect().ToString());
8917
8918 // This render surface should clip. It has no unclipped descendants.
8919 EXPECT_EQ(gfx::Rect(0, 0, 5, 5).ToString(),
8920 render_surface2->clip_rect().ToString());
8921 EXPECT_TRUE(render_surface2->render_surface()->is_clipped());
8922
8923 // It also shouldn't have grown to accomodate the clip child.
8924 EXPECT_EQ(gfx::Rect(0, 0, 5, 5).ToString(),
8925 render_surface2->render_surface()->content_rect().ToString());
8926
8927 // Sanity check our num_unclipped_descendants values.
8928 EXPECT_EQ(1, render_surface1->num_unclipped_descendants());
8929 EXPECT_EQ(0, render_surface2->num_unclipped_descendants());
8930 }
8931
TEST_F(LayerTreeHostCommonTest,CanRenderToSeparateSurface)8932 TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
8933 FakeImplProxy proxy;
8934 FakeLayerTreeHostImpl host_impl(&proxy);
8935 scoped_ptr<LayerImpl> root =
8936 LayerImpl::Create(host_impl.active_tree(), 12345);
8937 scoped_ptr<LayerImpl> child1 =
8938 LayerImpl::Create(host_impl.active_tree(), 123456);
8939 scoped_ptr<LayerImpl> child2 =
8940 LayerImpl::Create(host_impl.active_tree(), 1234567);
8941 scoped_ptr<LayerImpl> child3 =
8942 LayerImpl::Create(host_impl.active_tree(), 12345678);
8943
8944 gfx::Transform identity_matrix;
8945 gfx::PointF anchor;
8946 gfx::PointF position;
8947 gfx::Size bounds(100, 100);
8948 SetLayerPropertiesForTesting(root.get(),
8949 identity_matrix,
8950 identity_matrix,
8951 anchor,
8952 position,
8953 bounds,
8954 false);
8955 root->SetDrawsContent(true);
8956
8957 // This layer structure normally forces render surface due to preserves3d
8958 // behavior.
8959 bool preserves3d = true;
8960 SetLayerPropertiesForTesting(child1.get(),
8961 identity_matrix,
8962 identity_matrix,
8963 anchor,
8964 position,
8965 bounds,
8966 preserves3d);
8967 child1->SetDrawsContent(true);
8968 SetLayerPropertiesForTesting(child2.get(),
8969 identity_matrix,
8970 identity_matrix,
8971 anchor,
8972 position,
8973 bounds,
8974 false);
8975 child2->SetDrawsContent(true);
8976 SetLayerPropertiesForTesting(child3.get(),
8977 identity_matrix,
8978 identity_matrix,
8979 anchor,
8980 position,
8981 bounds,
8982 false);
8983 child3->SetDrawsContent(true);
8984
8985 child2->AddChild(child3.Pass());
8986 child1->AddChild(child2.Pass());
8987 root->AddChild(child1.Pass());
8988
8989 {
8990 LayerImplList render_surface_layer_list;
8991 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
8992 root.get(), root->bounds(), &render_surface_layer_list);
8993 inputs.can_render_to_separate_surface = true;
8994 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
8995
8996 EXPECT_EQ(2u, render_surface_layer_list.size());
8997 }
8998
8999 {
9000 LayerImplList render_surface_layer_list;
9001 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
9002 root.get(), root->bounds(), &render_surface_layer_list);
9003 inputs.can_render_to_separate_surface = false;
9004 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
9005
9006 EXPECT_EQ(1u, render_surface_layer_list.size());
9007 }
9008 }
9009
TEST_F(LayerTreeHostCommonTest,DoNotIncludeBackfaceInvisibleSurfaces)9010 TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) {
9011 scoped_refptr<Layer> root = Layer::Create();
9012 scoped_refptr<Layer> render_surface = Layer::Create();
9013 scoped_refptr<LayerWithForcedDrawsContent> child =
9014 make_scoped_refptr(new LayerWithForcedDrawsContent);
9015
9016 root->AddChild(render_surface);
9017 render_surface->AddChild(child);
9018
9019 gfx::Transform identity_transform;
9020 SetLayerPropertiesForTesting(root.get(),
9021 identity_transform,
9022 identity_transform,
9023 gfx::PointF(),
9024 gfx::PointF(),
9025 gfx::Size(50, 50),
9026 false);
9027 SetLayerPropertiesForTesting(render_surface.get(),
9028 identity_transform,
9029 identity_transform,
9030 gfx::PointF(),
9031 gfx::PointF(),
9032 gfx::Size(30, 30),
9033 false);
9034 SetLayerPropertiesForTesting(child.get(),
9035 identity_transform,
9036 identity_transform,
9037 gfx::PointF(),
9038 gfx::PointF(),
9039 gfx::Size(20, 20),
9040 false);
9041
9042 root->SetPreserves3d(true);
9043 render_surface->SetDoubleSided(false);
9044 render_surface->SetForceRenderSurface(true);
9045
9046 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
9047 host->SetRootLayer(root);
9048
9049 ExecuteCalculateDrawProperties(root.get());
9050
9051 EXPECT_EQ(2u, render_surface_layer_list()->size());
9052 EXPECT_EQ(1u,
9053 render_surface_layer_list()->at(0)
9054 ->render_surface()->layer_list().size());
9055 EXPECT_EQ(1u,
9056 render_surface_layer_list()->at(1)
9057 ->render_surface()->layer_list().size());
9058
9059 gfx::Transform rotation_transform = identity_transform;
9060 rotation_transform.RotateAboutXAxis(180.0);
9061
9062 render_surface->SetTransform(rotation_transform);
9063
9064 ExecuteCalculateDrawProperties(root.get());
9065
9066 EXPECT_EQ(1u, render_surface_layer_list()->size());
9067 EXPECT_EQ(0u,
9068 render_surface_layer_list()->at(0)
9069 ->render_surface()->layer_list().size());
9070 }
9071
TEST_F(LayerTreeHostCommonTest,ClippedByScrollParent)9072 TEST_F(LayerTreeHostCommonTest, ClippedByScrollParent) {
9073 // Checks that the simple case (being clipped by a scroll parent that would
9074 // have been processed before you anyhow) results in the right clips.
9075 //
9076 // + root
9077 // + scroll_parent_border
9078 // | + scroll_parent_clip
9079 // | + scroll_parent
9080 // + scroll_child
9081 //
9082 scoped_refptr<Layer> root = Layer::Create();
9083 scoped_refptr<Layer> scroll_parent_border = Layer::Create();
9084 scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
9085 scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
9086 make_scoped_refptr(new LayerWithForcedDrawsContent);
9087 scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
9088 make_scoped_refptr(new LayerWithForcedDrawsContent);
9089
9090 root->AddChild(scroll_child);
9091
9092 root->AddChild(scroll_parent_border);
9093 scroll_parent_border->AddChild(scroll_parent_clip);
9094 scroll_parent_clip->AddChild(scroll_parent);
9095
9096 scroll_parent_clip->SetMasksToBounds(true);
9097
9098 scroll_child->SetScrollParent(scroll_parent.get());
9099
9100 gfx::Transform identity_transform;
9101 SetLayerPropertiesForTesting(root.get(),
9102 identity_transform,
9103 identity_transform,
9104 gfx::PointF(),
9105 gfx::PointF(),
9106 gfx::Size(50, 50),
9107 false);
9108 SetLayerPropertiesForTesting(scroll_parent_border.get(),
9109 identity_transform,
9110 identity_transform,
9111 gfx::PointF(),
9112 gfx::PointF(),
9113 gfx::Size(40, 40),
9114 false);
9115 SetLayerPropertiesForTesting(scroll_parent_clip.get(),
9116 identity_transform,
9117 identity_transform,
9118 gfx::PointF(),
9119 gfx::PointF(),
9120 gfx::Size(30, 30),
9121 false);
9122 SetLayerPropertiesForTesting(scroll_parent.get(),
9123 identity_transform,
9124 identity_transform,
9125 gfx::PointF(),
9126 gfx::PointF(),
9127 gfx::Size(50, 50),
9128 false);
9129 SetLayerPropertiesForTesting(scroll_child.get(),
9130 identity_transform,
9131 identity_transform,
9132 gfx::PointF(),
9133 gfx::PointF(),
9134 gfx::Size(50, 50),
9135 false);
9136
9137 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
9138 host->SetRootLayer(root);
9139
9140 ExecuteCalculateDrawProperties(root.get());
9141
9142 EXPECT_TRUE(root->render_surface());
9143
9144 EXPECT_EQ(gfx::Rect(0, 0, 30, 30).ToString(),
9145 scroll_child->clip_rect().ToString());
9146 EXPECT_TRUE(scroll_child->is_clipped());
9147 }
9148
TEST_F(LayerTreeHostCommonTest,ClippedByOutOfOrderScrollParent)9149 TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollParent) {
9150 // Checks that clipping by a scroll parent that follows you in paint order
9151 // still results in correct clipping.
9152 //
9153 // + root
9154 // + scroll_child
9155 // + scroll_parent_border
9156 // + scroll_parent_clip
9157 // + scroll_parent
9158 //
9159 scoped_refptr<Layer> root = Layer::Create();
9160 scoped_refptr<Layer> scroll_parent_border = Layer::Create();
9161 scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
9162 scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
9163 make_scoped_refptr(new LayerWithForcedDrawsContent);
9164 scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
9165 make_scoped_refptr(new LayerWithForcedDrawsContent);
9166
9167 root->AddChild(scroll_parent_border);
9168 scroll_parent_border->AddChild(scroll_parent_clip);
9169 scroll_parent_clip->AddChild(scroll_parent);
9170
9171 root->AddChild(scroll_child);
9172
9173 scroll_parent_clip->SetMasksToBounds(true);
9174
9175 scroll_child->SetScrollParent(scroll_parent.get());
9176
9177 gfx::Transform identity_transform;
9178 SetLayerPropertiesForTesting(root.get(),
9179 identity_transform,
9180 identity_transform,
9181 gfx::PointF(),
9182 gfx::PointF(),
9183 gfx::Size(50, 50),
9184 false);
9185 SetLayerPropertiesForTesting(scroll_parent_border.get(),
9186 identity_transform,
9187 identity_transform,
9188 gfx::PointF(),
9189 gfx::PointF(),
9190 gfx::Size(40, 40),
9191 false);
9192 SetLayerPropertiesForTesting(scroll_parent_clip.get(),
9193 identity_transform,
9194 identity_transform,
9195 gfx::PointF(),
9196 gfx::PointF(),
9197 gfx::Size(30, 30),
9198 false);
9199 SetLayerPropertiesForTesting(scroll_parent.get(),
9200 identity_transform,
9201 identity_transform,
9202 gfx::PointF(),
9203 gfx::PointF(),
9204 gfx::Size(50, 50),
9205 false);
9206 SetLayerPropertiesForTesting(scroll_child.get(),
9207 identity_transform,
9208 identity_transform,
9209 gfx::PointF(),
9210 gfx::PointF(),
9211 gfx::Size(50, 50),
9212 false);
9213
9214 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
9215 host->SetRootLayer(root);
9216
9217 ExecuteCalculateDrawProperties(root.get());
9218
9219 EXPECT_TRUE(root->render_surface());
9220
9221 EXPECT_EQ(gfx::Rect(0, 0, 30, 30).ToString(),
9222 scroll_child->clip_rect().ToString());
9223 EXPECT_TRUE(scroll_child->is_clipped());
9224 }
9225
TEST_F(LayerTreeHostCommonTest,ClippedByOutOfOrderScrollGrandparent)9226 TEST_F(LayerTreeHostCommonTest, ClippedByOutOfOrderScrollGrandparent) {
9227 // Checks that clipping by a scroll parent and scroll grandparent that follow
9228 // you in paint order still results in correct clipping.
9229 //
9230 // + root
9231 // + scroll_child
9232 // + scroll_parent_border
9233 // | + scroll_parent_clip
9234 // | + scroll_parent
9235 // + scroll_grandparent_border
9236 // + scroll_grandparent_clip
9237 // + scroll_grandparent
9238 //
9239 scoped_refptr<Layer> root = Layer::Create();
9240 scoped_refptr<Layer> scroll_parent_border = Layer::Create();
9241 scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
9242 scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
9243 make_scoped_refptr(new LayerWithForcedDrawsContent);
9244
9245 scoped_refptr<Layer> scroll_grandparent_border = Layer::Create();
9246 scoped_refptr<Layer> scroll_grandparent_clip = Layer::Create();
9247 scoped_refptr<LayerWithForcedDrawsContent> scroll_grandparent =
9248 make_scoped_refptr(new LayerWithForcedDrawsContent);
9249
9250 scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
9251 make_scoped_refptr(new LayerWithForcedDrawsContent);
9252
9253 root->AddChild(scroll_child);
9254
9255 root->AddChild(scroll_parent_border);
9256 scroll_parent_border->AddChild(scroll_parent_clip);
9257 scroll_parent_clip->AddChild(scroll_parent);
9258
9259 root->AddChild(scroll_grandparent_border);
9260 scroll_grandparent_border->AddChild(scroll_grandparent_clip);
9261 scroll_grandparent_clip->AddChild(scroll_grandparent);
9262
9263 scroll_parent_clip->SetMasksToBounds(true);
9264 scroll_grandparent_clip->SetMasksToBounds(true);
9265
9266 scroll_child->SetScrollParent(scroll_parent.get());
9267 scroll_parent_border->SetScrollParent(scroll_grandparent.get());
9268
9269 gfx::Transform identity_transform;
9270 SetLayerPropertiesForTesting(root.get(),
9271 identity_transform,
9272 identity_transform,
9273 gfx::PointF(),
9274 gfx::PointF(),
9275 gfx::Size(50, 50),
9276 false);
9277 SetLayerPropertiesForTesting(scroll_grandparent_border.get(),
9278 identity_transform,
9279 identity_transform,
9280 gfx::PointF(),
9281 gfx::PointF(),
9282 gfx::Size(40, 40),
9283 false);
9284 SetLayerPropertiesForTesting(scroll_grandparent_clip.get(),
9285 identity_transform,
9286 identity_transform,
9287 gfx::PointF(),
9288 gfx::PointF(),
9289 gfx::Size(20, 20),
9290 false);
9291 SetLayerPropertiesForTesting(scroll_grandparent.get(),
9292 identity_transform,
9293 identity_transform,
9294 gfx::PointF(),
9295 gfx::PointF(),
9296 gfx::Size(50, 50),
9297 false);
9298 SetLayerPropertiesForTesting(scroll_parent_border.get(),
9299 identity_transform,
9300 identity_transform,
9301 gfx::PointF(),
9302 gfx::PointF(),
9303 gfx::Size(40, 40),
9304 false);
9305 SetLayerPropertiesForTesting(scroll_parent_clip.get(),
9306 identity_transform,
9307 identity_transform,
9308 gfx::PointF(),
9309 gfx::PointF(),
9310 gfx::Size(30, 30),
9311 false);
9312 SetLayerPropertiesForTesting(scroll_parent.get(),
9313 identity_transform,
9314 identity_transform,
9315 gfx::PointF(),
9316 gfx::PointF(),
9317 gfx::Size(50, 50),
9318 false);
9319 SetLayerPropertiesForTesting(scroll_child.get(),
9320 identity_transform,
9321 identity_transform,
9322 gfx::PointF(),
9323 gfx::PointF(),
9324 gfx::Size(50, 50),
9325 false);
9326
9327 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
9328 host->SetRootLayer(root);
9329
9330 ExecuteCalculateDrawProperties(root.get());
9331
9332 EXPECT_TRUE(root->render_surface());
9333
9334 EXPECT_EQ(gfx::Rect(0, 0, 20, 20).ToString(),
9335 scroll_child->clip_rect().ToString());
9336 EXPECT_TRUE(scroll_child->is_clipped());
9337
9338 // Despite the fact that we visited the above layers out of order to get the
9339 // correct clip, the layer lists should be unaffected.
9340 EXPECT_EQ(3u, root->render_surface()->layer_list().size());
9341 EXPECT_EQ(scroll_child.get(),
9342 root->render_surface()->layer_list().at(0));
9343 EXPECT_EQ(scroll_parent.get(),
9344 root->render_surface()->layer_list().at(1));
9345 EXPECT_EQ(scroll_grandparent.get(),
9346 root->render_surface()->layer_list().at(2));
9347 }
9348
TEST_F(LayerTreeHostCommonTest,OutOfOrderClippingRequiresRSLLSorting)9349 TEST_F(LayerTreeHostCommonTest, OutOfOrderClippingRequiresRSLLSorting) {
9350 // Ensures that even if we visit layers out of order, we still produce a
9351 // correctly ordered render surface layer list.
9352 // + root
9353 // + scroll_child
9354 // + scroll_parent_border
9355 // + scroll_parent_clip
9356 // + scroll_parent
9357 // + render_surface1
9358 // + scroll_grandparent_border
9359 // + scroll_grandparent_clip
9360 // + scroll_grandparent
9361 // + render_surface2
9362 //
9363 scoped_refptr<LayerWithForcedDrawsContent> root =
9364 make_scoped_refptr(new LayerWithForcedDrawsContent);
9365
9366 scoped_refptr<Layer> scroll_parent_border = Layer::Create();
9367 scoped_refptr<Layer> scroll_parent_clip = Layer::Create();
9368 scoped_refptr<LayerWithForcedDrawsContent> scroll_parent =
9369 make_scoped_refptr(new LayerWithForcedDrawsContent);
9370 scoped_refptr<LayerWithForcedDrawsContent> render_surface1 =
9371 make_scoped_refptr(new LayerWithForcedDrawsContent);
9372
9373 scoped_refptr<Layer> scroll_grandparent_border = Layer::Create();
9374 scoped_refptr<Layer> scroll_grandparent_clip = Layer::Create();
9375 scoped_refptr<LayerWithForcedDrawsContent> scroll_grandparent =
9376 make_scoped_refptr(new LayerWithForcedDrawsContent);
9377 scoped_refptr<LayerWithForcedDrawsContent> render_surface2 =
9378 make_scoped_refptr(new LayerWithForcedDrawsContent);
9379
9380 scoped_refptr<LayerWithForcedDrawsContent> scroll_child =
9381 make_scoped_refptr(new LayerWithForcedDrawsContent);
9382
9383 root->AddChild(scroll_child);
9384
9385 root->AddChild(scroll_parent_border);
9386 scroll_parent_border->AddChild(scroll_parent_clip);
9387 scroll_parent_clip->AddChild(scroll_parent);
9388 scroll_parent->AddChild(render_surface2);
9389
9390 root->AddChild(scroll_grandparent_border);
9391 scroll_grandparent_border->AddChild(scroll_grandparent_clip);
9392 scroll_grandparent_clip->AddChild(scroll_grandparent);
9393 scroll_grandparent->AddChild(render_surface1);
9394
9395 scroll_parent_clip->SetMasksToBounds(true);
9396 scroll_grandparent_clip->SetMasksToBounds(true);
9397
9398 scroll_child->SetScrollParent(scroll_parent.get());
9399 scroll_parent_border->SetScrollParent(scroll_grandparent.get());
9400
9401 render_surface1->SetForceRenderSurface(true);
9402 render_surface2->SetForceRenderSurface(true);
9403
9404 gfx::Transform identity_transform;
9405 SetLayerPropertiesForTesting(root.get(),
9406 identity_transform,
9407 identity_transform,
9408 gfx::PointF(),
9409 gfx::PointF(),
9410 gfx::Size(50, 50),
9411 false);
9412 SetLayerPropertiesForTesting(scroll_grandparent_border.get(),
9413 identity_transform,
9414 identity_transform,
9415 gfx::PointF(),
9416 gfx::PointF(),
9417 gfx::Size(40, 40),
9418 false);
9419 SetLayerPropertiesForTesting(scroll_grandparent_clip.get(),
9420 identity_transform,
9421 identity_transform,
9422 gfx::PointF(),
9423 gfx::PointF(),
9424 gfx::Size(20, 20),
9425 false);
9426 SetLayerPropertiesForTesting(scroll_grandparent.get(),
9427 identity_transform,
9428 identity_transform,
9429 gfx::PointF(),
9430 gfx::PointF(),
9431 gfx::Size(50, 50),
9432 false);
9433 SetLayerPropertiesForTesting(render_surface1.get(),
9434 identity_transform,
9435 identity_transform,
9436 gfx::PointF(),
9437 gfx::PointF(),
9438 gfx::Size(50, 50),
9439 false);
9440 SetLayerPropertiesForTesting(scroll_parent_border.get(),
9441 identity_transform,
9442 identity_transform,
9443 gfx::PointF(),
9444 gfx::PointF(),
9445 gfx::Size(40, 40),
9446 false);
9447 SetLayerPropertiesForTesting(scroll_parent_clip.get(),
9448 identity_transform,
9449 identity_transform,
9450 gfx::PointF(),
9451 gfx::PointF(),
9452 gfx::Size(30, 30),
9453 false);
9454 SetLayerPropertiesForTesting(scroll_parent.get(),
9455 identity_transform,
9456 identity_transform,
9457 gfx::PointF(),
9458 gfx::PointF(),
9459 gfx::Size(50, 50),
9460 false);
9461 SetLayerPropertiesForTesting(render_surface2.get(),
9462 identity_transform,
9463 identity_transform,
9464 gfx::PointF(),
9465 gfx::PointF(),
9466 gfx::Size(50, 50),
9467 false);
9468 SetLayerPropertiesForTesting(scroll_child.get(),
9469 identity_transform,
9470 identity_transform,
9471 gfx::PointF(),
9472 gfx::PointF(),
9473 gfx::Size(50, 50),
9474 false);
9475
9476 scoped_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create();
9477 host->SetRootLayer(root);
9478
9479 RenderSurfaceLayerList render_surface_layer_list;
9480 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
9481 root.get(),
9482 root->bounds(),
9483 identity_transform,
9484 &render_surface_layer_list);
9485
9486 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
9487
9488 EXPECT_TRUE(root->render_surface());
9489
9490 EXPECT_EQ(gfx::Rect(0, 0, 20, 20).ToString(),
9491 scroll_child->clip_rect().ToString());
9492 EXPECT_TRUE(scroll_child->is_clipped());
9493
9494 // Despite the fact that we had to process the layers out of order to get the
9495 // right clip, our render_surface_layer_list's order should be unaffected.
9496 EXPECT_EQ(3u, render_surface_layer_list.size());
9497 EXPECT_EQ(root.get(), render_surface_layer_list.at(0));
9498 EXPECT_EQ(render_surface2.get(), render_surface_layer_list.at(1));
9499 EXPECT_EQ(render_surface1.get(), render_surface_layer_list.at(2));
9500 EXPECT_TRUE(render_surface_layer_list.at(0)->render_surface());
9501 EXPECT_TRUE(render_surface_layer_list.at(1)->render_surface());
9502 EXPECT_TRUE(render_surface_layer_list.at(2)->render_surface());
9503 }
9504
TEST_F(LayerTreeHostCommonTest,DoNotClobberSorting)9505 TEST_F(LayerTreeHostCommonTest, DoNotClobberSorting) {
9506 // We rearrange layer list contributions if we have to visit children out of
9507 // order, but it should be a 'stable' rearrangement. That is, the layer list
9508 // additions for a single layer should not be reordered, though their position
9509 // wrt to the contributions due to a sibling may vary.
9510 //
9511 // + root
9512 // + scroll_child
9513 // + top_content
9514 // + bottom_content
9515 // + scroll_parent_border
9516 // + scroll_parent_clip
9517 // + scroll_parent
9518 //
9519 FakeImplProxy proxy;
9520 FakeLayerTreeHostImpl host_impl(&proxy);
9521 host_impl.CreatePendingTree();
9522 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
9523 scoped_ptr<LayerImpl> scroll_parent_border =
9524 LayerImpl::Create(host_impl.active_tree(), 2);
9525 scoped_ptr<LayerImpl> scroll_parent_clip =
9526 LayerImpl::Create(host_impl.active_tree(), 3);
9527 scoped_ptr<LayerImpl> scroll_parent =
9528 LayerImpl::Create(host_impl.active_tree(), 4);
9529 scoped_ptr<LayerImpl> scroll_child =
9530 LayerImpl::Create(host_impl.active_tree(), 5);
9531 scoped_ptr<LayerImpl> bottom_content =
9532 LayerImpl::Create(host_impl.active_tree(), 6);
9533 scoped_ptr<LayerImpl> top_content =
9534 LayerImpl::Create(host_impl.active_tree(), 7);
9535
9536 scroll_parent_clip->SetMasksToBounds(true);
9537
9538 scroll_child->SetScrollParent(scroll_parent.get());
9539 scoped_ptr<std::set<LayerImpl*> > scroll_children(new std::set<LayerImpl*>);
9540 scroll_children->insert(scroll_child.get());
9541 scroll_parent->SetScrollChildren(scroll_children.release());
9542
9543 scroll_child->SetDrawsContent(true);
9544 scroll_parent->SetDrawsContent(true);
9545 top_content->SetDrawsContent(true);
9546 bottom_content->SetDrawsContent(true);
9547
9548 gfx::Transform identity_transform;
9549 gfx::Transform top_transform;
9550 top_transform.Translate3d(0.0, 0.0, 5.0);
9551 gfx::Transform bottom_transform;
9552 bottom_transform.Translate3d(0.0, 0.0, 3.0);
9553
9554 SetLayerPropertiesForTesting(root.get(),
9555 identity_transform,
9556 identity_transform,
9557 gfx::PointF(),
9558 gfx::PointF(),
9559 gfx::Size(50, 50),
9560 false);
9561 SetLayerPropertiesForTesting(scroll_parent_border.get(),
9562 identity_transform,
9563 identity_transform,
9564 gfx::PointF(),
9565 gfx::PointF(),
9566 gfx::Size(40, 40),
9567 false);
9568 SetLayerPropertiesForTesting(scroll_parent_clip.get(),
9569 identity_transform,
9570 identity_transform,
9571 gfx::PointF(),
9572 gfx::PointF(),
9573 gfx::Size(30, 30),
9574 false);
9575 SetLayerPropertiesForTesting(scroll_parent.get(),
9576 identity_transform,
9577 identity_transform,
9578 gfx::PointF(),
9579 gfx::PointF(),
9580 gfx::Size(50, 50),
9581 false);
9582 SetLayerPropertiesForTesting(scroll_child.get(),
9583 identity_transform,
9584 identity_transform,
9585 gfx::PointF(),
9586 gfx::PointF(),
9587 gfx::Size(50, 50),
9588 false);
9589 SetLayerPropertiesForTesting(top_content.get(),
9590 top_transform,
9591 top_transform,
9592 gfx::PointF(),
9593 gfx::PointF(),
9594 gfx::Size(50, 50),
9595 false);
9596 SetLayerPropertiesForTesting(bottom_content.get(),
9597 bottom_transform,
9598 bottom_transform,
9599 gfx::PointF(),
9600 gfx::PointF(),
9601 gfx::Size(50, 50),
9602 false);
9603
9604 scroll_child->SetPreserves3d(true);
9605
9606 scroll_child->AddChild(top_content.Pass());
9607 scroll_child->AddChild(bottom_content.Pass());
9608 root->AddChild(scroll_child.Pass());
9609
9610 scroll_parent_clip->AddChild(scroll_parent.Pass());
9611 scroll_parent_border->AddChild(scroll_parent_clip.Pass());
9612 root->AddChild(scroll_parent_border.Pass());
9613
9614 LayerImplList render_surface_layer_list;
9615 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
9616 root.get(), root->bounds(), &render_surface_layer_list);
9617
9618 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
9619
9620 EXPECT_TRUE(root->render_surface());
9621
9622 // If we don't sort by depth and let the layers get added in the order they
9623 // would normally be visited in, then layers 6 and 7 will be out of order. In
9624 // other words, although we've had to shift 5, 6, and 7 to appear before 4
9625 // in the list (because of the scroll parent relationship), this should not
9626 // have an effect on the the order of 5, 6, and 7 (which had been reordered
9627 // due to layer sorting).
9628 EXPECT_EQ(4u, root->render_surface()->layer_list().size());
9629 EXPECT_EQ(5, root->render_surface()->layer_list().at(0)->id());
9630 EXPECT_EQ(6, root->render_surface()->layer_list().at(1)->id());
9631 EXPECT_EQ(7, root->render_surface()->layer_list().at(2)->id());
9632 EXPECT_EQ(4, root->render_surface()->layer_list().at(3)->id());
9633 }
9634
TEST_F(LayerTreeHostCommonTest,ScrollCompensationWithRounding)9635 TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) {
9636 // This test verifies that a scrolling layer that gets snapped to
9637 // integer coordinates doesn't move a fixed position child.
9638 //
9639 // + root
9640 // + container
9641 // + scroller
9642 // + fixed
9643 //
9644 FakeImplProxy proxy;
9645 FakeLayerTreeHostImpl host_impl(&proxy);
9646 host_impl.CreatePendingTree();
9647 scoped_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1);
9648 scoped_ptr<LayerImpl> container =
9649 LayerImpl::Create(host_impl.active_tree(), 2);
9650 LayerImpl* container_layer = container.get();
9651 scoped_ptr<LayerImpl> scroller =
9652 LayerImpl::Create(host_impl.active_tree(), 3);
9653 LayerImpl* scroll_layer = scroller.get();
9654 scoped_ptr<LayerImpl> fixed = LayerImpl::Create(host_impl.active_tree(), 4);
9655 LayerImpl* fixed_layer = fixed.get();
9656
9657 container->SetIsContainerForFixedPositionLayers(true);
9658
9659 LayerPositionConstraint constraint;
9660 constraint.set_is_fixed_position(true);
9661 fixed->SetPositionConstraint(constraint);
9662
9663 scroller->SetScrollable(true);
9664
9665 gfx::Transform identity_transform;
9666 gfx::Transform container_transform;
9667 container_transform.Translate3d(10.0, 20.0, 0.0);
9668 gfx::Vector2dF container_offset = container_transform.To2dTranslation();
9669
9670 SetLayerPropertiesForTesting(root.get(),
9671 identity_transform,
9672 identity_transform,
9673 gfx::PointF(),
9674 gfx::PointF(),
9675 gfx::Size(50, 50),
9676 false);
9677 SetLayerPropertiesForTesting(container.get(),
9678 container_transform,
9679 identity_transform,
9680 gfx::PointF(),
9681 gfx::PointF(),
9682 gfx::Size(40, 40),
9683 false);
9684 SetLayerPropertiesForTesting(scroller.get(),
9685 identity_transform,
9686 identity_transform,
9687 gfx::PointF(),
9688 gfx::PointF(),
9689 gfx::Size(30, 30),
9690 false);
9691 SetLayerPropertiesForTesting(fixed.get(),
9692 identity_transform,
9693 identity_transform,
9694 gfx::PointF(),
9695 gfx::PointF(),
9696 gfx::Size(50, 50),
9697 false);
9698
9699 scroller->AddChild(fixed.Pass());
9700 container->AddChild(scroller.Pass());
9701 root->AddChild(container.Pass());
9702
9703 // Rounded to integers already.
9704 {
9705 gfx::Vector2dF scroll_delta(3.0, 5.0);
9706 scroll_layer->SetScrollDelta(scroll_delta);
9707
9708 LayerImplList render_surface_layer_list;
9709 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
9710 root.get(), root->bounds(), &render_surface_layer_list);
9711 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
9712
9713 EXPECT_TRANSFORMATION_MATRIX_EQ(
9714 container_layer->draw_properties().screen_space_transform,
9715 fixed_layer->draw_properties().screen_space_transform);
9716 EXPECT_VECTOR_EQ(
9717 fixed_layer->draw_properties().screen_space_transform.To2dTranslation(),
9718 container_offset);
9719 EXPECT_VECTOR_EQ(scroll_layer->draw_properties()
9720 .screen_space_transform.To2dTranslation(),
9721 container_offset - scroll_delta);
9722 }
9723
9724 // Scroll delta requiring rounding.
9725 {
9726 gfx::Vector2dF scroll_delta(4.1f, 8.1f);
9727 scroll_layer->SetScrollDelta(scroll_delta);
9728
9729 gfx::Vector2dF rounded_scroll_delta(4.f, 8.f);
9730
9731 LayerImplList render_surface_layer_list;
9732 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
9733 root.get(), root->bounds(), &render_surface_layer_list);
9734 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
9735
9736 EXPECT_TRANSFORMATION_MATRIX_EQ(
9737 container_layer->draw_properties().screen_space_transform,
9738 fixed_layer->draw_properties().screen_space_transform);
9739 EXPECT_VECTOR_EQ(
9740 fixed_layer->draw_properties().screen_space_transform.To2dTranslation(),
9741 container_offset);
9742 EXPECT_VECTOR_EQ(scroll_layer->draw_properties()
9743 .screen_space_transform.To2dTranslation(),
9744 container_offset - rounded_scroll_delta);
9745 }
9746 }
9747
9748 } // namespace
9749 } // namespace cc
9750