[safe browsing] Push missing download BINHASH histograms.
[chromium-blink-merge.git] / cc / layers / layer_position_constraint_unittest.cc
blob4a41c797bef5034a8079cb39400d85592d5d95b8
1 // Copyright 2013 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.
5 #include "cc/layers/layer_position_constraint.h"
7 #include <vector>
9 #include "cc/layers/layer_impl.h"
10 #include "cc/test/fake_impl_proxy.h"
11 #include "cc/test/fake_layer_tree_host_impl.h"
12 #include "cc/test/geometry_test_utils.h"
13 #include "cc/trees/layer_tree_host_common.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace cc {
17 namespace {
19 void SetLayerPropertiesForTesting(LayerImpl* layer,
20 const gfx::Transform& transform,
21 const gfx::PointF& anchor,
22 const gfx::PointF& position,
23 const gfx::Size& bounds,
24 bool flatten_transform,
25 bool is_3d_sorted) {
26 layer->SetTransform(transform);
27 layer->SetAnchorPoint(anchor);
28 layer->SetPosition(position);
29 layer->SetBounds(bounds);
30 layer->SetShouldFlattenTransform(flatten_transform);
31 layer->SetIs3dSorted(is_3d_sorted);
32 layer->SetContentBounds(bounds);
35 void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
36 float device_scale_factor,
37 float page_scale_factor,
38 LayerImpl* page_scale_application_layer,
39 bool can_use_lcd_text) {
40 gfx::Transform identity_matrix;
41 std::vector<LayerImpl*> dummy_render_surface_layer_list;
42 LayerImpl* scroll_layer = root_layer->children()[0];
43 gfx::Size device_viewport_size =
44 gfx::Size(root_layer->bounds().width() * device_scale_factor,
45 root_layer->bounds().height() * device_scale_factor);
47 // We are probably not testing what is intended if the scroll_layer bounds are
48 // empty.
49 DCHECK(!scroll_layer->bounds().IsEmpty());
50 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
51 root_layer, device_viewport_size, &dummy_render_surface_layer_list);
52 inputs.device_scale_factor = device_scale_factor;
53 inputs.page_scale_factor = page_scale_factor;
54 inputs.page_scale_application_layer = page_scale_application_layer;
55 inputs.can_use_lcd_text = can_use_lcd_text;
56 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
59 void ExecuteCalculateDrawProperties(LayerImpl* root_layer) {
60 LayerImpl* page_scale_application_layer = NULL;
61 ExecuteCalculateDrawProperties(
62 root_layer, 1.f, 1.f, page_scale_application_layer, false);
65 class LayerPositionConstraintTest : public testing::Test {
66 public:
67 LayerPositionConstraintTest()
68 : host_impl_(&proxy_) {
69 root_ = CreateTreeForTest();
70 scroll_ = root_->children()[0];
71 fixed_to_top_left_.set_is_fixed_position(true);
72 fixed_to_bottom_right_.set_is_fixed_position(true);
73 fixed_to_bottom_right_.set_is_fixed_to_right_edge(true);
74 fixed_to_bottom_right_.set_is_fixed_to_bottom_edge(true);
77 scoped_ptr<LayerImpl> CreateTreeForTest() {
78 scoped_ptr<LayerImpl> root =
79 LayerImpl::Create(host_impl_.active_tree(), 42);
80 scoped_ptr<LayerImpl> scroll_layer =
81 LayerImpl::Create(host_impl_.active_tree(), 1);
82 scoped_ptr<LayerImpl> child =
83 LayerImpl::Create(host_impl_.active_tree(), 2);
84 scoped_ptr<LayerImpl> grand_child =
85 LayerImpl::Create(host_impl_.active_tree(), 3);
86 scoped_ptr<LayerImpl> great_grand_child =
87 LayerImpl::Create(host_impl_.active_tree(), 4);
89 gfx::Transform IdentityMatrix;
90 gfx::PointF anchor;
91 gfx::PointF position;
92 gfx::Size bounds(200, 200);
93 gfx::Size clip_bounds(100, 100);
94 SetLayerPropertiesForTesting(scroll_layer.get(),
95 IdentityMatrix,
96 anchor,
97 position,
98 bounds,
99 true,
100 false);
101 SetLayerPropertiesForTesting(child.get(),
102 IdentityMatrix,
103 anchor,
104 position,
105 bounds,
106 true,
107 false);
108 SetLayerPropertiesForTesting(grand_child.get(),
109 IdentityMatrix,
110 anchor,
111 position,
112 bounds,
113 true,
114 false);
115 SetLayerPropertiesForTesting(great_grand_child.get(),
116 IdentityMatrix,
117 anchor,
118 position,
119 bounds,
120 true,
121 false);
123 root->SetBounds(clip_bounds);
124 scroll_layer->SetScrollClipLayer(root->id());
125 child->SetScrollClipLayer(root->id());
126 grand_child->SetScrollClipLayer(root->id());
128 grand_child->AddChild(great_grand_child.Pass());
129 child->AddChild(grand_child.Pass());
130 scroll_layer->AddChild(child.Pass());
131 root->AddChild(scroll_layer.Pass());
133 return root.Pass();
136 protected:
137 FakeImplProxy proxy_;
138 FakeLayerTreeHostImpl host_impl_;
139 scoped_ptr<LayerImpl> root_;
140 LayerImpl* scroll_;
142 LayerPositionConstraint fixed_to_top_left_;
143 LayerPositionConstraint fixed_to_bottom_right_;
146 TEST_F(LayerPositionConstraintTest,
147 ScrollCompensationForFixedPositionLayerWithDirectContainer) {
148 // This test checks for correct scroll compensation when the fixed-position
149 // container is the direct parent of the fixed-position layer.
150 LayerImpl* child = scroll_->children()[0];
151 LayerImpl* grand_child = child->children()[0];
153 child->SetIsContainerForFixedPositionLayers(true);
154 grand_child->SetPositionConstraint(fixed_to_top_left_);
156 // Case 1: scroll delta of 0, 0
157 child->SetScrollDelta(gfx::Vector2d(0, 0));
158 ExecuteCalculateDrawProperties(root_.get());
160 gfx::Transform expected_child_transform;
161 gfx::Transform expected_grand_child_transform = expected_child_transform;
163 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
164 child->draw_transform());
165 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
166 grand_child->draw_transform());
168 // Case 2: scroll delta of 10, 10
169 child->SetScrollDelta(gfx::Vector2d(10, 10));
170 ExecuteCalculateDrawProperties(root_.get());
172 // Here the child is affected by scroll delta, but the fixed position
173 // grand_child should not be affected.
174 expected_child_transform.MakeIdentity();
175 expected_child_transform.Translate(-10.0, -10.0);
177 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
178 child->draw_transform());
179 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
180 grand_child->draw_transform());
182 // Case 3: fixed-container size delta of 20, 20
183 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
184 ExecuteCalculateDrawProperties(root_.get());
186 // Top-left fixed-position layer should not be affected by container size.
187 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
188 child->draw_transform());
189 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
190 grand_child->draw_transform());
192 // Case 4: Bottom-right fixed-position layer.
193 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
194 ExecuteCalculateDrawProperties(root_.get());
196 // Bottom-right fixed-position layer moves as container resizes.
197 expected_grand_child_transform.MakeIdentity();
198 // Apply size delta from the child(container) layer.
199 expected_grand_child_transform.Translate(20.0, 20.0);
201 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
202 child->draw_transform());
203 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
204 grand_child->draw_transform());
207 TEST_F(LayerPositionConstraintTest,
208 ScrollCompensationForFixedPositionLayerWithTransformedDirectContainer) {
209 // This test checks for correct scroll compensation when the fixed-position
210 // container is the direct parent of the fixed-position layer, but that
211 // container is transformed. In this case, the fixed position element
212 // inherits the container's transform, but the scroll delta that has to be
213 // undone should not be affected by that transform.
215 // Transforms are in general non-commutative; using something like a
216 // non-uniform scale helps to verify that translations and non-uniform scales
217 // are applied in the correct order.
218 LayerImpl* child = scroll_->children()[0];
219 LayerImpl* grand_child = child->children()[0];
221 // This scale will cause child and grand_child to be effectively 200 x 800
222 // with respect to the render target.
223 gfx::Transform non_uniform_scale;
224 non_uniform_scale.Scale(2.0, 8.0);
225 child->SetTransform(non_uniform_scale);
227 child->SetIsContainerForFixedPositionLayers(true);
228 grand_child->SetPositionConstraint(fixed_to_top_left_);
230 // Case 1: scroll delta of 0, 0
231 child->SetScrollDelta(gfx::Vector2d(0, 0));
232 ExecuteCalculateDrawProperties(root_.get());
234 gfx::Transform expected_child_transform;
235 expected_child_transform.PreconcatTransform(non_uniform_scale);
237 gfx::Transform expected_grand_child_transform = expected_child_transform;
239 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
240 child->draw_transform());
241 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
242 grand_child->draw_transform());
244 // Case 2: scroll delta of 10, 20
245 child->SetScrollDelta(gfx::Vector2d(10, 20));
246 ExecuteCalculateDrawProperties(root_.get());
248 // The child should be affected by scroll delta, but the fixed position
249 // grand_child should not be affected.
250 expected_child_transform.MakeIdentity();
251 expected_child_transform.Translate(-10.0, -20.0); // scroll delta
252 expected_child_transform.PreconcatTransform(non_uniform_scale);
254 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
255 child->draw_transform());
256 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
257 grand_child->draw_transform());
259 // Case 3: fixed-container size delta of 20, 20
260 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
261 ExecuteCalculateDrawProperties(root_.get());
263 // Top-left fixed-position layer should not be affected by container size.
264 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
265 child->draw_transform());
266 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
267 grand_child->draw_transform());
269 // Case 4: Bottom-right fixed-position layer.
270 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
271 ExecuteCalculateDrawProperties(root_.get());
273 // Bottom-right fixed-position layer moves as container resizes.
274 expected_grand_child_transform.MakeIdentity();
275 // Apply child layer transform.
276 expected_grand_child_transform.PreconcatTransform(non_uniform_scale);
277 // Apply size delta from the child(container) layer.
278 expected_grand_child_transform.Translate(20.0, 20.0);
280 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
281 child->draw_transform());
282 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
283 grand_child->draw_transform());
286 TEST_F(LayerPositionConstraintTest,
287 ScrollCompensationForFixedPositionLayerWithDistantContainer) {
288 // This test checks for correct scroll compensation when the fixed-position
289 // container is NOT the direct parent of the fixed-position layer.
290 LayerImpl* child = scroll_->children()[0];
291 LayerImpl* grand_child = child->children()[0];
292 LayerImpl* great_grand_child = grand_child->children()[0];
294 child->SetIsContainerForFixedPositionLayers(true);
295 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
296 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
298 // Case 1: scroll delta of 0, 0
299 child->SetScrollDelta(gfx::Vector2d(0, 0));
300 ExecuteCalculateDrawProperties(root_.get());
302 gfx::Transform expected_child_transform;
303 gfx::Transform expected_grand_child_transform;
304 expected_grand_child_transform.Translate(8.0, 6.0);
306 gfx::Transform expected_great_grand_child_transform =
307 expected_grand_child_transform;
309 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
310 child->draw_transform());
311 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
312 grand_child->draw_transform());
313 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
314 great_grand_child->draw_transform());
316 // Case 2: scroll delta of 10, 10
317 child->SetScrollDelta(gfx::Vector2d(10, 10));
318 ExecuteCalculateDrawProperties(root_.get());
320 // Here the child and grand_child are affected by scroll delta, but the fixed
321 // position great_grand_child should not be affected.
322 expected_child_transform.MakeIdentity();
323 expected_child_transform.Translate(-10.0, -10.0);
324 expected_grand_child_transform.MakeIdentity();
325 expected_grand_child_transform.Translate(-2.0, -4.0);
326 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
327 child->draw_transform());
328 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
329 grand_child->draw_transform());
330 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
331 great_grand_child->draw_transform());
333 // Case 3: fixed-container size delta of 20, 20
334 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
335 ExecuteCalculateDrawProperties(root_.get());
337 // Top-left fixed-position layer should not be affected by container size.
338 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
339 child->draw_transform());
340 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
341 grand_child->draw_transform());
342 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
343 great_grand_child->draw_transform());
345 // Case 4: Bottom-right fixed-position layer.
346 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
347 ExecuteCalculateDrawProperties(root_.get());
349 // Bottom-right fixed-position layer moves as container resizes.
350 expected_great_grand_child_transform.MakeIdentity();
351 // Apply size delta from the child(container) layer.
352 expected_great_grand_child_transform.Translate(20.0, 20.0);
353 // Apply layer position from the grand child layer.
354 expected_great_grand_child_transform.Translate(8.0, 6.0);
356 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
357 child->draw_transform());
358 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
359 grand_child->draw_transform());
360 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
361 great_grand_child->draw_transform());
364 TEST_F(LayerPositionConstraintTest,
365 ScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms) {
366 // This test checks for correct scroll compensation when the fixed-position
367 // container is NOT the direct parent of the fixed-position layer, and the
368 // hierarchy has various transforms that have to be processed in the correct
369 // order.
370 LayerImpl* child = scroll_->children()[0];
371 LayerImpl* grand_child = child->children()[0];
372 LayerImpl* great_grand_child = grand_child->children()[0];
374 gfx::Transform rotation_about_z;
375 rotation_about_z.RotateAboutZAxis(90.0);
377 child->SetIsContainerForFixedPositionLayers(true);
378 child->SetTransform(rotation_about_z);
379 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
380 grand_child->SetTransform(rotation_about_z);
381 // great_grand_child is positioned upside-down with respect to the render
382 // target.
383 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
385 // Case 1: scroll delta of 0, 0
386 child->SetScrollDelta(gfx::Vector2d(0, 0));
387 ExecuteCalculateDrawProperties(root_.get());
389 gfx::Transform expected_child_transform;
390 expected_child_transform.PreconcatTransform(rotation_about_z);
392 gfx::Transform expected_grand_child_transform;
393 expected_grand_child_transform.PreconcatTransform(
394 rotation_about_z); // child's local transform is inherited
395 // translation because of position occurs before layer's local transform.
396 expected_grand_child_transform.Translate(8.0, 6.0);
397 expected_grand_child_transform.PreconcatTransform(
398 rotation_about_z); // grand_child's local transform
400 gfx::Transform expected_great_grand_child_transform =
401 expected_grand_child_transform;
403 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
404 child->draw_transform());
405 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
406 grand_child->draw_transform());
407 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
408 great_grand_child->draw_transform());
410 // Case 2: scroll delta of 10, 20
411 child->SetScrollDelta(gfx::Vector2d(10, 20));
412 ExecuteCalculateDrawProperties(root_.get());
414 // Here the child and grand_child are affected by scroll delta, but the fixed
415 // position great_grand_child should not be affected.
416 expected_child_transform.MakeIdentity();
417 expected_child_transform.Translate(-10.0, -20.0); // scroll delta
418 expected_child_transform.PreconcatTransform(rotation_about_z);
420 expected_grand_child_transform.MakeIdentity();
421 expected_grand_child_transform.Translate(
422 -10.0, -20.0); // child's scroll delta is inherited
423 expected_grand_child_transform.PreconcatTransform(
424 rotation_about_z); // child's local transform is inherited
425 // translation because of position occurs before layer's local transform.
426 expected_grand_child_transform.Translate(8.0, 6.0);
427 expected_grand_child_transform.PreconcatTransform(
428 rotation_about_z); // grand_child's local transform
430 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
431 child->draw_transform());
432 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
433 grand_child->draw_transform());
434 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
435 great_grand_child->draw_transform());
437 // Case 3: fixed-container size delta of 20, 20
438 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
439 ExecuteCalculateDrawProperties(root_.get());
441 // Top-left fixed-position layer should not be affected by container size.
442 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
443 child->draw_transform());
444 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
445 grand_child->draw_transform());
446 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
447 great_grand_child->draw_transform());
449 // Case 4: Bottom-right fixed-position layer.
450 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
451 ExecuteCalculateDrawProperties(root_.get());
453 // Bottom-right fixed-position layer moves as container resizes.
454 expected_great_grand_child_transform.MakeIdentity();
455 // Apply child layer transform.
456 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
457 // Apply size delta from the child(container) layer.
458 expected_great_grand_child_transform.Translate(20.0, 20.0);
459 // Apply layer position from the grand child layer.
460 expected_great_grand_child_transform.Translate(8.0, 6.0);
461 // Apply grand child layer transform.
462 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
464 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
465 child->draw_transform());
466 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
467 grand_child->draw_transform());
468 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
469 great_grand_child->draw_transform());
472 TEST_F(LayerPositionConstraintTest,
473 ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas) {
474 // This test checks for correct scroll compensation when the fixed-position
475 // container has multiple ancestors that have nonzero scroll delta before
476 // reaching the space where the layer is fixed. In this test, each scroll
477 // delta occurs in a different space because of each layer's local transform.
478 // This test checks for correct scroll compensation when the fixed-position
479 // container is NOT the direct parent of the fixed-position layer, and the
480 // hierarchy has various transforms that have to be processed in the correct
481 // order.
482 LayerImpl* child = scroll_->children()[0];
483 LayerImpl* grand_child = child->children()[0];
484 LayerImpl* great_grand_child = grand_child->children()[0];
486 gfx::Transform rotation_about_z;
487 rotation_about_z.RotateAboutZAxis(90.0);
489 child->SetIsContainerForFixedPositionLayers(true);
490 child->SetTransform(rotation_about_z);
491 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
492 grand_child->SetTransform(rotation_about_z);
493 // great_grand_child is positioned upside-down with respect to the render
494 // target.
495 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
497 // Case 1: scroll delta of 0, 0
498 child->SetScrollDelta(gfx::Vector2d(0, 0));
499 ExecuteCalculateDrawProperties(root_.get());
501 gfx::Transform expected_child_transform;
502 expected_child_transform.PreconcatTransform(rotation_about_z);
504 gfx::Transform expected_grand_child_transform;
505 expected_grand_child_transform.PreconcatTransform(
506 rotation_about_z); // child's local transform is inherited
507 // translation because of position occurs before layer's local transform.
508 expected_grand_child_transform.Translate(8.0, 6.0);
509 expected_grand_child_transform.PreconcatTransform(
510 rotation_about_z); // grand_child's local transform
512 gfx::Transform expected_great_grand_child_transform =
513 expected_grand_child_transform;
515 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
516 child->draw_transform());
517 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
518 grand_child->draw_transform());
519 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
520 great_grand_child->draw_transform());
522 // Case 2: scroll delta of 10, 20
523 child->SetScrollDelta(gfx::Vector2d(10, 0));
524 grand_child->SetScrollDelta(gfx::Vector2d(5, 0));
525 ExecuteCalculateDrawProperties(root_.get());
527 // Here the child and grand_child are affected by scroll delta, but the fixed
528 // position great_grand_child should not be affected.
529 expected_child_transform.MakeIdentity();
530 expected_child_transform.Translate(-10.0, 0.0); // scroll delta
531 expected_child_transform.PreconcatTransform(rotation_about_z);
533 expected_grand_child_transform.MakeIdentity();
534 expected_grand_child_transform.Translate(
535 -10.0, 0.0); // child's scroll delta is inherited
536 expected_grand_child_transform.PreconcatTransform(
537 rotation_about_z); // child's local transform is inherited
538 expected_grand_child_transform.Translate(-5.0,
539 0.0); // grand_child's scroll delta
540 // translation because of position occurs before layer's local transform.
541 expected_grand_child_transform.Translate(8.0, 6.0);
542 expected_grand_child_transform.PreconcatTransform(
543 rotation_about_z); // grand_child's local transform
545 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
546 child->draw_transform());
547 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
548 grand_child->draw_transform());
549 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
550 great_grand_child->draw_transform());
552 // Case 3: fixed-container size delta of 20, 20
553 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
554 ExecuteCalculateDrawProperties(root_.get());
556 // Top-left fixed-position layer should not be affected by container size.
557 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
558 child->draw_transform());
559 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
560 grand_child->draw_transform());
561 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
562 great_grand_child->draw_transform());
564 // Case 4: Bottom-right fixed-position layer.
565 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
566 ExecuteCalculateDrawProperties(root_.get());
568 // Bottom-right fixed-position layer moves as container resizes.
569 expected_great_grand_child_transform.MakeIdentity();
570 // Apply child layer transform.
571 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
572 // Apply size delta from the child(container) layer.
573 expected_great_grand_child_transform.Translate(20.0, 20.0);
574 // Apply layer position from the grand child layer.
575 expected_great_grand_child_transform.Translate(8.0, 6.0);
576 // Apply grand child layer transform.
577 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
579 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
580 child->draw_transform());
581 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
582 grand_child->draw_transform());
583 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
584 great_grand_child->draw_transform());
587 TEST_F(LayerPositionConstraintTest,
588 ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms) {
589 // This test checks for correct scroll compensation when the fixed-position
590 // container contributes to a different render surface than the fixed-position
591 // layer. In this case, the surface draw transforms also have to be accounted
592 // for when checking the scroll delta.
593 LayerImpl* child = scroll_->children()[0];
594 LayerImpl* grand_child = child->children()[0];
595 LayerImpl* great_grand_child = grand_child->children()[0];
597 child->SetIsContainerForFixedPositionLayers(true);
598 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
599 grand_child->SetForceRenderSurface(true);
600 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
601 great_grand_child->SetDrawsContent(true);
603 gfx::Transform rotation_about_z;
604 rotation_about_z.RotateAboutZAxis(90.0);
605 grand_child->SetTransform(rotation_about_z);
607 // Case 1: scroll delta of 0, 0
608 child->SetScrollDelta(gfx::Vector2d(0, 0));
609 ExecuteCalculateDrawProperties(root_.get());
611 gfx::Transform expected_child_transform;
612 gfx::Transform expected_surface_draw_transform;
613 expected_surface_draw_transform.Translate(8.0, 6.0);
614 expected_surface_draw_transform.PreconcatTransform(rotation_about_z);
615 gfx::Transform expected_grand_child_transform;
616 gfx::Transform expected_great_grand_child_transform;
617 ASSERT_TRUE(grand_child->render_surface());
618 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
619 child->draw_transform());
620 EXPECT_TRANSFORMATION_MATRIX_EQ(
621 expected_surface_draw_transform,
622 grand_child->render_surface()->draw_transform());
623 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
624 grand_child->draw_transform());
625 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
626 great_grand_child->draw_transform());
628 // Case 2: scroll delta of 10, 30
629 child->SetScrollDelta(gfx::Vector2d(10, 30));
630 ExecuteCalculateDrawProperties(root_.get());
632 // Here the grand_child remains unchanged, because it scrolls along with the
633 // render surface, and the translation is actually in the render surface. But,
634 // the fixed position great_grand_child is more awkward: its actually being
635 // drawn with respect to the render surface, but it needs to remain fixed with
636 // resepct to a container beyond that surface. So, the net result is that,
637 // unlike previous tests where the fixed position layer's transform remains
638 // unchanged, here the fixed position layer's transform explicitly contains
639 // the translation that cancels out the scroll.
640 expected_child_transform.MakeIdentity();
641 expected_child_transform.Translate(-10.0, -30.0); // scroll delta
643 expected_surface_draw_transform.MakeIdentity();
644 expected_surface_draw_transform.Translate(-10.0, -30.0); // scroll delta
645 expected_surface_draw_transform.Translate(8.0, 6.0);
646 expected_surface_draw_transform.PreconcatTransform(rotation_about_z);
648 // The rotation and its inverse are needed to place the scroll delta
649 // compensation in the correct space. This test will fail if the
650 // rotation/inverse are backwards, too, so it requires perfect order of
651 // operations.
652 expected_great_grand_child_transform.MakeIdentity();
653 expected_great_grand_child_transform.PreconcatTransform(
654 Inverse(rotation_about_z));
655 // explicit canceling out the scroll delta that gets embedded in the fixed
656 // position layer's surface.
657 expected_great_grand_child_transform.Translate(10.0, 30.0);
658 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
660 ASSERT_TRUE(grand_child->render_surface());
661 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
662 child->draw_transform());
663 EXPECT_TRANSFORMATION_MATRIX_EQ(
664 expected_surface_draw_transform,
665 grand_child->render_surface()->draw_transform());
666 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
667 grand_child->draw_transform());
668 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
669 great_grand_child->draw_transform());
671 // Case 3: fixed-container size delta of 20, 20
672 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
673 ExecuteCalculateDrawProperties(root_.get());
675 // Top-left fixed-position layer should not be affected by container size.
676 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
677 child->draw_transform());
678 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
679 grand_child->draw_transform());
680 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
681 great_grand_child->draw_transform());
683 // Case 4: Bottom-right fixed-position layer.
684 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
685 ExecuteCalculateDrawProperties(root_.get());
687 // Bottom-right fixed-position layer moves as container resizes.
688 expected_great_grand_child_transform.MakeIdentity();
689 // The rotation and its inverse are needed to place the scroll delta
690 // compensation in the correct space. This test will fail if the
691 // rotation/inverse are backwards, too, so it requires perfect order of
692 // operations.
693 expected_great_grand_child_transform.PreconcatTransform(
694 Inverse(rotation_about_z));
695 // explicit canceling out the scroll delta that gets embedded in the fixed
696 // position layer's surface.
697 expected_great_grand_child_transform.Translate(10.0, 30.0);
698 // Also apply size delta in the child(container) layer space.
699 expected_great_grand_child_transform.Translate(20.0, 20.0);
700 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
702 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
703 child->draw_transform());
704 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
705 grand_child->draw_transform());
706 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
707 great_grand_child->draw_transform());
710 TEST_F(LayerPositionConstraintTest,
711 ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces) {
712 // This test checks for correct scroll compensation when the fixed-position
713 // container contributes to a different render surface than the fixed-position
714 // layer, with additional render surfaces in-between. This checks that the
715 // conversion to ancestor surfaces is accumulated properly in the final matrix
716 // transform.
717 LayerImpl* child = scroll_->children()[0];
718 LayerImpl* grand_child = child->children()[0];
719 LayerImpl* great_grand_child = grand_child->children()[0];
721 // Add one more layer to the test tree for this scenario.
723 gfx::Transform identity;
724 scoped_ptr<LayerImpl> fixed_position_child =
725 LayerImpl::Create(host_impl_.active_tree(), 5);
726 SetLayerPropertiesForTesting(fixed_position_child.get(),
727 identity,
728 gfx::PointF(),
729 gfx::PointF(),
730 gfx::Size(100, 100),
731 true,
732 false);
733 great_grand_child->AddChild(fixed_position_child.Pass());
735 LayerImpl* fixed_position_child = great_grand_child->children()[0];
737 // Actually set up the scenario here.
738 child->SetIsContainerForFixedPositionLayers(true);
739 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
740 grand_child->SetForceRenderSurface(true);
741 great_grand_child->SetPosition(gfx::PointF(40.f, 60.f));
742 great_grand_child->SetForceRenderSurface(true);
743 fixed_position_child->SetPositionConstraint(fixed_to_top_left_);
744 fixed_position_child->SetDrawsContent(true);
746 // The additional rotations, which are non-commutative with translations, help
747 // to verify that we have correct order-of-operations in the final scroll
748 // compensation. Note that rotating about the center of the layer ensures we
749 // do not accidentally clip away layers that we want to test.
750 gfx::Transform rotation_about_z;
751 rotation_about_z.Translate(50.0, 50.0);
752 rotation_about_z.RotateAboutZAxis(90.0);
753 rotation_about_z.Translate(-50.0, -50.0);
754 grand_child->SetTransform(rotation_about_z);
755 great_grand_child->SetTransform(rotation_about_z);
757 // Case 1: scroll delta of 0, 0
758 child->SetScrollDelta(gfx::Vector2d(0, 0));
759 ExecuteCalculateDrawProperties(root_.get());
761 gfx::Transform expected_child_transform;
763 gfx::Transform expected_grand_child_surface_draw_transform;
764 expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
765 expected_grand_child_surface_draw_transform.PreconcatTransform(
766 rotation_about_z);
768 gfx::Transform expected_grand_child_transform;
770 gfx::Transform expected_great_grand_child_surface_draw_transform;
771 expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0);
772 expected_great_grand_child_surface_draw_transform.PreconcatTransform(
773 rotation_about_z);
775 gfx::Transform expected_great_grand_child_transform;
777 gfx::Transform expected_fixed_position_child_transform;
779 ASSERT_TRUE(grand_child->render_surface());
780 ASSERT_TRUE(great_grand_child->render_surface());
781 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
782 child->draw_transform());
783 EXPECT_TRANSFORMATION_MATRIX_EQ(
784 expected_grand_child_surface_draw_transform,
785 grand_child->render_surface()->draw_transform());
786 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
787 grand_child->draw_transform());
788 EXPECT_TRANSFORMATION_MATRIX_EQ(
789 expected_great_grand_child_surface_draw_transform,
790 great_grand_child->render_surface()->draw_transform());
791 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
792 great_grand_child->draw_transform());
793 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
794 fixed_position_child->draw_transform());
796 // Case 2: scroll delta of 10, 30
797 child->SetScrollDelta(gfx::Vector2d(10, 30));
798 ExecuteCalculateDrawProperties(root_.get());
800 expected_child_transform.MakeIdentity();
801 expected_child_transform.Translate(-10.0, -30.0); // scroll delta
803 expected_grand_child_surface_draw_transform.MakeIdentity();
804 expected_grand_child_surface_draw_transform.Translate(-10.0,
805 -30.0); // scroll delta
806 expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
807 expected_grand_child_surface_draw_transform.PreconcatTransform(
808 rotation_about_z);
810 // grand_child, great_grand_child, and great_grand_child's surface are not
811 // expected to change, since they are all not fixed, and they are all drawn
812 // with respect to grand_child's surface that already has the scroll delta
813 // accounted for.
815 // But the great-great grandchild, "fixed_position_child", should have a
816 // transform that explicitly cancels out the scroll delta. The expected
817 // transform is: compound_draw_transform.Inverse() * translate(positive scroll
818 // delta) * compound_origin_transform from great_grand_childSurface's origin
819 // to the root surface.
820 gfx::Transform compound_draw_transform;
821 compound_draw_transform.Translate(8.0,
822 6.0); // origin translation of grand_child
823 compound_draw_transform.PreconcatTransform(
824 rotation_about_z); // rotation of grand_child
825 compound_draw_transform.Translate(
826 40.0, 60.0); // origin translation of great_grand_child
827 compound_draw_transform.PreconcatTransform(
828 rotation_about_z); // rotation of great_grand_child
830 expected_fixed_position_child_transform.MakeIdentity();
831 expected_fixed_position_child_transform.PreconcatTransform(
832 Inverse(compound_draw_transform));
833 // explicit canceling out the scroll delta that gets embedded in the fixed
834 // position layer's surface.
835 expected_fixed_position_child_transform.Translate(10.0, 30.0);
836 expected_fixed_position_child_transform.PreconcatTransform(
837 compound_draw_transform);
839 ASSERT_TRUE(grand_child->render_surface());
840 ASSERT_TRUE(great_grand_child->render_surface());
841 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
842 child->draw_transform());
843 EXPECT_TRANSFORMATION_MATRIX_EQ(
844 expected_grand_child_surface_draw_transform,
845 grand_child->render_surface()->draw_transform());
846 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
847 grand_child->draw_transform());
848 EXPECT_TRANSFORMATION_MATRIX_EQ(
849 expected_great_grand_child_surface_draw_transform,
850 great_grand_child->render_surface()->draw_transform());
851 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
852 great_grand_child->draw_transform());
853 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
854 fixed_position_child->draw_transform());
857 // Case 3: fixed-container size delta of 20, 20
858 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
859 ExecuteCalculateDrawProperties(root_.get());
861 // Top-left fixed-position layer should not be affected by container size.
862 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
863 child->draw_transform());
864 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
865 grand_child->draw_transform());
866 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
867 great_grand_child->draw_transform());
868 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
869 fixed_position_child->draw_transform());
871 // Case 4: Bottom-right fixed-position layer.
872 fixed_position_child->SetPositionConstraint(fixed_to_bottom_right_);
873 ExecuteCalculateDrawProperties(root_.get());
875 // Bottom-right fixed-position layer moves as container resizes.
876 expected_fixed_position_child_transform.MakeIdentity();
877 expected_fixed_position_child_transform.PreconcatTransform(
878 Inverse(compound_draw_transform));
879 // explicit canceling out the scroll delta that gets embedded in the fixed
880 // position layer's surface.
881 expected_fixed_position_child_transform.Translate(10.0, 30.0);
882 // Also apply size delta in the child(container) layer space.
883 expected_fixed_position_child_transform.Translate(20.0, 20.0);
884 expected_fixed_position_child_transform.PreconcatTransform(
885 compound_draw_transform);
887 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
888 child->draw_transform());
889 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
890 grand_child->draw_transform());
891 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
892 great_grand_child->draw_transform());
893 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
894 fixed_position_child->draw_transform());
897 TEST_F(LayerPositionConstraintTest,
898 ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface) {
899 // This test checks for correct scroll compensation when the fixed-position
900 // container itself has a render surface. In this case, the container layer
901 // should be treated like a layer that contributes to a render target, and
902 // that render target is completely irrelevant; it should not affect the
903 // scroll compensation.
904 LayerImpl* child = scroll_->children()[0];
905 LayerImpl* grand_child = child->children()[0];
907 child->SetIsContainerForFixedPositionLayers(true);
908 child->SetForceRenderSurface(true);
909 grand_child->SetPositionConstraint(fixed_to_top_left_);
910 grand_child->SetDrawsContent(true);
912 // Case 1: scroll delta of 0, 0
913 child->SetScrollDelta(gfx::Vector2d(0, 0));
914 ExecuteCalculateDrawProperties(root_.get());
916 gfx::Transform expected_surface_draw_transform;
917 expected_surface_draw_transform.Translate(0.0, 0.0);
918 gfx::Transform expected_child_transform;
919 gfx::Transform expected_grand_child_transform;
920 ASSERT_TRUE(child->render_surface());
921 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
922 child->render_surface()->draw_transform());
923 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
924 child->draw_transform());
925 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
926 grand_child->draw_transform());
928 // Case 2: scroll delta of 10, 10
929 child->SetScrollDelta(gfx::Vector2d(10, 10));
930 ExecuteCalculateDrawProperties(root_.get());
932 // The surface is translated by scroll delta, the child transform doesn't
933 // change because it scrolls along with the surface, but the fixed position
934 // grand_child needs to compensate for the scroll translation.
935 expected_surface_draw_transform.MakeIdentity();
936 expected_surface_draw_transform.Translate(-10.0, -10.0);
937 expected_grand_child_transform.MakeIdentity();
938 expected_grand_child_transform.Translate(10.0, 10.0);
940 ASSERT_TRUE(child->render_surface());
941 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
942 child->render_surface()->draw_transform());
943 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
944 child->draw_transform());
945 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
946 grand_child->draw_transform());
948 // Case 3: fixed-container size delta of 20, 20
949 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
950 ExecuteCalculateDrawProperties(root_.get());
952 // Top-left fixed-position layer should not be affected by container size.
953 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
954 child->draw_transform());
955 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
956 grand_child->draw_transform());
958 // Case 4: Bottom-right fixed-position layer.
959 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
960 ExecuteCalculateDrawProperties(root_.get());
962 // Bottom-right fixed-position layer moves as container resizes.
963 expected_grand_child_transform.MakeIdentity();
964 // The surface is translated by scroll delta, the child transform doesn't
965 // change because it scrolls along with the surface, but the fixed position
966 // grand_child needs to compensate for the scroll translation.
967 expected_grand_child_transform.Translate(10.0, 10.0);
968 // Apply size delta from the child(container) layer.
969 expected_grand_child_transform.Translate(20.0, 20.0);
971 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
972 child->draw_transform());
973 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
974 grand_child->draw_transform());
977 TEST_F(LayerPositionConstraintTest,
978 ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer) {
979 // This test checks the scenario where a fixed-position layer also happens to
980 // be a container itself for a descendant fixed position layer. In particular,
981 // the layer should not accidentally be fixed to itself.
982 LayerImpl* child = scroll_->children()[0];
983 LayerImpl* grand_child = child->children()[0];
985 child->SetIsContainerForFixedPositionLayers(true);
986 grand_child->SetPositionConstraint(fixed_to_top_left_);
988 // This should not confuse the grand_child. If correct, the grand_child would
989 // still be considered fixed to its container (i.e. "child").
990 grand_child->SetIsContainerForFixedPositionLayers(true);
992 // Case 1: scroll delta of 0, 0
993 child->SetScrollDelta(gfx::Vector2d(0, 0));
994 ExecuteCalculateDrawProperties(root_.get());
996 gfx::Transform expected_child_transform;
997 gfx::Transform expected_grand_child_transform;
998 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
999 child->draw_transform());
1000 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1001 grand_child->draw_transform());
1003 // Case 2: scroll delta of 10, 10
1004 child->SetScrollDelta(gfx::Vector2d(10, 10));
1005 ExecuteCalculateDrawProperties(root_.get());
1007 // Here the child is affected by scroll delta, but the fixed position
1008 // grand_child should not be affected.
1009 expected_child_transform.MakeIdentity();
1010 expected_child_transform.Translate(-10.0, -10.0);
1011 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1012 child->draw_transform());
1013 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1014 grand_child->draw_transform());
1016 // Case 3: fixed-container size delta of 20, 20
1017 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
1018 ExecuteCalculateDrawProperties(root_.get());
1020 // Top-left fixed-position layer should not be affected by container size.
1021 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1022 child->draw_transform());
1023 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1024 grand_child->draw_transform());
1026 // Case 4: Bottom-right fixed-position layer.
1027 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
1028 ExecuteCalculateDrawProperties(root_.get());
1030 // Bottom-right fixed-position layer moves as container resizes.
1031 expected_grand_child_transform.MakeIdentity();
1032 // Apply size delta from the child(container) layer.
1033 expected_grand_child_transform.Translate(20.0, 20.0);
1035 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1036 child->draw_transform());
1037 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1038 grand_child->draw_transform());
1041 TEST_F(LayerPositionConstraintTest,
1042 ScrollCompensationForFixedWithinFixedWithSameContainer) {
1043 // This test checks scroll compensation for a fixed-position layer that is
1044 // inside of another fixed-position layer and both share the same container.
1045 // In this situation, the parent fixed-position layer will receive
1046 // the scroll compensation, and the child fixed-position layer does not
1047 // need to compensate further.
1049 LayerImpl* child = scroll_->children()[0];
1050 LayerImpl* grand_child = child->children()[0];
1051 LayerImpl* great_grand_child = grand_child->children()[0];
1053 child->SetIsContainerForFixedPositionLayers(true);
1054 grand_child->SetPositionConstraint(fixed_to_top_left_);
1056 // Note carefully - great_grand_child is fixed to bottom right, to test
1057 // sizeDelta being applied correctly; the compensation skips the grand_child
1058 // because it is fixed to top left.
1059 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
1061 // Case 1: scrollDelta
1062 child->SetScrollDelta(gfx::Vector2d(10, 10));
1063 ExecuteCalculateDrawProperties(root_.get());
1065 // Here the child is affected by scroll delta, but the fixed position
1066 // grand_child should not be affected.
1067 gfx::Transform expected_child_transform;
1068 expected_child_transform.Translate(-10.0, -10.0);
1070 gfx::Transform expected_grand_child_transform;
1071 gfx::Transform expected_great_grand_child_transform;
1073 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1074 child->draw_transform());
1075 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1076 grand_child->draw_transform());
1077 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
1078 great_grand_child->draw_transform());
1080 // Case 2: sizeDelta
1081 child->SetScrollDelta(gfx::Vector2d(0, 0));
1082 child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20));
1083 ExecuteCalculateDrawProperties(root_.get());
1085 expected_child_transform.MakeIdentity();
1087 expected_grand_child_transform.MakeIdentity();
1089 // Fixed to bottom-right, size-delta compensation is applied.
1090 expected_great_grand_child_transform.MakeIdentity();
1091 expected_great_grand_child_transform.Translate(20.0, 20.0);
1093 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1094 child->draw_transform());
1095 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1096 grand_child->draw_transform());
1097 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
1098 great_grand_child->draw_transform());
1101 TEST_F(LayerPositionConstraintTest,
1102 ScrollCompensationForFixedWithinFixedWithInterveningContainer) {
1103 // This test checks scroll compensation for a fixed-position layer that is
1104 // inside of another fixed-position layer, but they have different fixed
1105 // position containers. In this situation, the child fixed-position element
1106 // would still have to compensate with respect to its container.
1108 LayerImpl* container1 = scroll_->children()[0];
1109 LayerImpl* fixed_to_container1 = container1->children()[0];
1110 LayerImpl* container2 = fixed_to_container1->children()[0];
1113 // Add one more layer to the hierarchy for this test.
1114 scoped_ptr<LayerImpl> fixed_to_container2_ptr =
1115 LayerImpl::Create(host_impl_.active_tree(), 5);
1116 container2->AddChild(fixed_to_container2_ptr.Pass());
1119 LayerImpl* fixed_to_container2 = container2->children()[0];
1121 container1->SetIsContainerForFixedPositionLayers(true);
1122 fixed_to_container1->SetPositionConstraint(fixed_to_top_left_);
1123 container2->SetIsContainerForFixedPositionLayers(true);
1124 fixed_to_container2->SetPositionConstraint(fixed_to_top_left_);
1126 container1->SetScrollDelta(gfx::Vector2d(0, 15));
1127 container2->SetScrollDelta(gfx::Vector2d(30, 0));
1128 ExecuteCalculateDrawProperties(root_.get());
1130 gfx::Transform expected_container1_transform;
1131 expected_container1_transform.Translate(0.0, -15.0);
1133 gfx::Transform expected_fixed_to_container1_transform;
1135 // Since the container is a descendant of the fixed layer above,
1136 // the expected draw transform for container2 would not
1137 // include the scrollDelta that was applied to container1.
1138 gfx::Transform expected_container2_transform;
1139 expected_container2_transform.Translate(-30.0, 0.0);
1141 gfx::Transform expected_fixed_to_container2_transform;
1143 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform,
1144 container1->draw_transform());
1146 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform,
1147 fixed_to_container1->draw_transform());
1149 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform,
1150 container2->draw_transform());
1152 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform,
1153 fixed_to_container2->draw_transform());
1155 } // namespace
1156 } // namespace cc