cc: Make VideoResourceUpdater use CopyToResource instead of SetPixels.
[chromium-blink-merge.git] / cc / layers / layer_position_constraint_unittest.cc
blob1c0619b8bcd3c8197c0076859a83f8c6f337e7ab
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/test/test_shared_bitmap_manager.h"
14 #include "cc/trees/layer_tree_host_common.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace cc {
18 namespace {
20 void SetLayerPropertiesForTesting(LayerImpl* layer,
21 const gfx::Transform& transform,
22 const gfx::Point3F& transform_origin,
23 const gfx::PointF& position,
24 const gfx::Size& bounds,
25 bool flatten_transform) {
26 layer->SetTransform(transform);
27 layer->SetTransformOrigin(transform_origin);
28 layer->SetPosition(position);
29 layer->SetBounds(bounds);
30 layer->SetShouldFlattenTransform(flatten_transform);
31 layer->SetContentBounds(bounds);
34 void ExecuteCalculateDrawProperties(LayerImpl* root_layer,
35 float device_scale_factor,
36 float page_scale_factor,
37 LayerImpl* page_scale_application_layer,
38 bool can_use_lcd_text) {
39 gfx::Transform identity_matrix;
40 std::vector<LayerImpl*> dummy_render_surface_layer_list;
41 LayerImpl* scroll_layer = root_layer->children()[0];
42 gfx::Size device_viewport_size =
43 gfx::Size(root_layer->bounds().width() * device_scale_factor,
44 root_layer->bounds().height() * device_scale_factor);
46 // We are probably not testing what is intended if the scroll_layer bounds are
47 // empty.
48 DCHECK(!scroll_layer->bounds().IsEmpty());
49 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs(
50 root_layer, device_viewport_size, &dummy_render_surface_layer_list);
51 inputs.device_scale_factor = device_scale_factor;
52 inputs.page_scale_factor = page_scale_factor;
53 inputs.page_scale_application_layer = page_scale_application_layer;
54 inputs.can_use_lcd_text = can_use_lcd_text;
55 LayerTreeHostCommon::CalculateDrawProperties(&inputs);
58 void ExecuteCalculateDrawProperties(LayerImpl* root_layer) {
59 LayerImpl* page_scale_application_layer = nullptr;
60 ExecuteCalculateDrawProperties(
61 root_layer, 1.f, 1.f, page_scale_application_layer, false);
64 class LayerPositionConstraintTest : public testing::Test {
65 public:
66 LayerPositionConstraintTest() : host_impl_(&proxy_, &shared_bitmap_manager_) {
67 root_ = CreateTreeForTest();
68 scroll_ = root_->children()[0];
69 fixed_to_top_left_.set_is_fixed_position(true);
70 fixed_to_bottom_right_.set_is_fixed_position(true);
71 fixed_to_bottom_right_.set_is_fixed_to_right_edge(true);
72 fixed_to_bottom_right_.set_is_fixed_to_bottom_edge(true);
75 scoped_ptr<LayerImpl> CreateTreeForTest() {
76 scoped_ptr<LayerImpl> root =
77 LayerImpl::Create(host_impl_.active_tree(), 42);
78 scoped_ptr<LayerImpl> scroll_layer =
79 LayerImpl::Create(host_impl_.active_tree(), 1);
80 scoped_ptr<LayerImpl> child =
81 LayerImpl::Create(host_impl_.active_tree(), 2);
82 scoped_ptr<LayerImpl> grand_child =
83 LayerImpl::Create(host_impl_.active_tree(), 3);
84 scoped_ptr<LayerImpl> great_grand_child =
85 LayerImpl::Create(host_impl_.active_tree(), 4);
87 root->SetHasRenderSurface(true);
88 gfx::Transform IdentityMatrix;
89 gfx::Point3F transform_origin;
90 gfx::PointF position;
91 gfx::Size bounds(200, 200);
92 gfx::Size clip_bounds(100, 100);
93 SetLayerPropertiesForTesting(scroll_layer.get(),
94 IdentityMatrix,
95 transform_origin,
96 position,
97 bounds,
98 true);
99 SetLayerPropertiesForTesting(
100 child.get(), IdentityMatrix, transform_origin, position, bounds, true);
101 SetLayerPropertiesForTesting(grand_child.get(),
102 IdentityMatrix,
103 transform_origin,
104 position,
105 bounds,
106 true);
107 SetLayerPropertiesForTesting(great_grand_child.get(),
108 IdentityMatrix,
109 transform_origin,
110 position,
111 bounds,
112 true);
114 root->SetBounds(clip_bounds);
115 scroll_layer->SetScrollClipLayer(root->id());
116 child->SetScrollClipLayer(root->id());
117 grand_child->SetScrollClipLayer(root->id());
119 grand_child->AddChild(great_grand_child.Pass());
120 child->AddChild(grand_child.Pass());
121 scroll_layer->AddChild(child.Pass());
122 root->AddChild(scroll_layer.Pass());
124 return root.Pass();
127 protected:
128 FakeImplProxy proxy_;
129 TestSharedBitmapManager shared_bitmap_manager_;
130 FakeLayerTreeHostImpl host_impl_;
131 scoped_ptr<LayerImpl> root_;
132 LayerImpl* scroll_;
134 LayerPositionConstraint fixed_to_top_left_;
135 LayerPositionConstraint fixed_to_bottom_right_;
138 namespace {
140 void SetFixedContainerSizeDelta(LayerImpl* scroll_layer,
141 const gfx::Vector2d& delta) {
142 DCHECK(scroll_layer);
143 DCHECK(scroll_layer->scrollable());
145 LayerImpl* container_layer = scroll_layer->scroll_clip_layer();
146 container_layer->SetBoundsDelta(delta);
148 } // namespace
150 TEST_F(LayerPositionConstraintTest,
151 ScrollCompensationForFixedPositionLayerWithDirectContainer) {
152 // This test checks for correct scroll compensation when the fixed-position
153 // container is the direct parent of the fixed-position layer.
154 LayerImpl* child = scroll_->children()[0];
155 LayerImpl* grand_child = child->children()[0];
157 child->SetIsContainerForFixedPositionLayers(true);
158 grand_child->SetPositionConstraint(fixed_to_top_left_);
160 // Case 1: scroll delta of 0, 0
161 child->SetScrollDelta(gfx::Vector2d(0, 0));
162 ExecuteCalculateDrawProperties(root_.get());
164 gfx::Transform expected_child_transform;
165 gfx::Transform expected_grand_child_transform = expected_child_transform;
167 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
168 child->draw_transform());
169 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
170 grand_child->draw_transform());
172 // Case 2: scroll delta of 10, 10
173 child->SetScrollDelta(gfx::Vector2d(10, 10));
174 ExecuteCalculateDrawProperties(root_.get());
176 // Here the child is affected by scroll delta, but the fixed position
177 // grand_child should not be affected.
178 expected_child_transform.MakeIdentity();
179 expected_child_transform.Translate(-10.0, -10.0);
181 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
182 child->draw_transform());
183 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
184 grand_child->draw_transform());
186 // Case 3: fixed-container size delta of 20, 20
187 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
188 ExecuteCalculateDrawProperties(root_.get());
190 // Top-left fixed-position layer should not be affected by container size.
191 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
192 child->draw_transform());
193 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
194 grand_child->draw_transform());
196 // Case 4: Bottom-right fixed-position layer.
197 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
198 ExecuteCalculateDrawProperties(root_.get());
200 // Bottom-right fixed-position layer moves as container resizes.
201 expected_grand_child_transform.MakeIdentity();
202 // Apply size delta from the child(container) layer.
203 expected_grand_child_transform.Translate(20.0, 20.0);
205 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
206 child->draw_transform());
207 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
208 grand_child->draw_transform());
211 TEST_F(LayerPositionConstraintTest,
212 ScrollCompensationForFixedPositionLayerWithTransformedDirectContainer) {
213 // This test checks for correct scroll compensation when the fixed-position
214 // container is the direct parent of the fixed-position layer, but that
215 // container is transformed. In this case, the fixed position element
216 // inherits the container's transform, but the scroll delta that has to be
217 // undone should not be affected by that transform.
219 // Transforms are in general non-commutative; using something like a
220 // non-uniform scale helps to verify that translations and non-uniform scales
221 // are applied in the correct order.
222 LayerImpl* child = scroll_->children()[0];
223 LayerImpl* grand_child = child->children()[0];
225 // This scale will cause child and grand_child to be effectively 200 x 800
226 // with respect to the render target.
227 gfx::Transform non_uniform_scale;
228 non_uniform_scale.Scale(2.0, 8.0);
229 child->SetTransform(non_uniform_scale);
231 child->SetIsContainerForFixedPositionLayers(true);
232 grand_child->SetPositionConstraint(fixed_to_top_left_);
234 // Case 1: scroll delta of 0, 0
235 child->SetScrollDelta(gfx::Vector2d(0, 0));
236 ExecuteCalculateDrawProperties(root_.get());
238 gfx::Transform expected_child_transform;
239 expected_child_transform.PreconcatTransform(non_uniform_scale);
241 gfx::Transform expected_grand_child_transform = expected_child_transform;
243 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
244 child->draw_transform());
245 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
246 grand_child->draw_transform());
248 // Case 2: scroll delta of 10, 20
249 child->SetScrollDelta(gfx::Vector2d(10, 20));
250 ExecuteCalculateDrawProperties(root_.get());
252 // The child should be affected by scroll delta, but the fixed position
253 // grand_child should not be affected.
254 expected_child_transform.MakeIdentity();
255 expected_child_transform.Translate(-10.0, -20.0); // scroll delta
256 expected_child_transform.PreconcatTransform(non_uniform_scale);
258 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
259 child->draw_transform());
260 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
261 grand_child->draw_transform());
263 // Case 3: fixed-container size delta of 20, 20
264 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
265 ExecuteCalculateDrawProperties(root_.get());
267 // Top-left fixed-position layer should not be affected by container size.
268 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
269 child->draw_transform());
270 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
271 grand_child->draw_transform());
273 // Case 4: Bottom-right fixed-position layer.
274 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
275 ExecuteCalculateDrawProperties(root_.get());
277 // Bottom-right fixed-position layer moves as container resizes.
278 expected_grand_child_transform.MakeIdentity();
279 // Apply child layer transform.
280 expected_grand_child_transform.PreconcatTransform(non_uniform_scale);
281 // Apply size delta from the child(container) layer.
282 expected_grand_child_transform.Translate(20.0, 20.0);
284 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
285 child->draw_transform());
286 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
287 grand_child->draw_transform());
290 TEST_F(LayerPositionConstraintTest,
291 ScrollCompensationForFixedPositionLayerWithDistantContainer) {
292 // This test checks for correct scroll compensation when the fixed-position
293 // container is NOT the direct parent of the fixed-position layer.
294 LayerImpl* child = scroll_->children()[0];
295 LayerImpl* grand_child = child->children()[0];
296 LayerImpl* great_grand_child = grand_child->children()[0];
298 child->SetIsContainerForFixedPositionLayers(true);
299 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
300 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
302 // Case 1: scroll delta of 0, 0
303 child->SetScrollDelta(gfx::Vector2d(0, 0));
304 ExecuteCalculateDrawProperties(root_.get());
306 gfx::Transform expected_child_transform;
307 gfx::Transform expected_grand_child_transform;
308 expected_grand_child_transform.Translate(8.0, 6.0);
310 gfx::Transform expected_great_grand_child_transform =
311 expected_grand_child_transform;
313 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
314 child->draw_transform());
315 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
316 grand_child->draw_transform());
317 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
318 great_grand_child->draw_transform());
320 // Case 2: scroll delta of 10, 10
321 child->SetScrollDelta(gfx::Vector2d(10, 10));
322 ExecuteCalculateDrawProperties(root_.get());
324 // Here the child and grand_child are affected by scroll delta, but the fixed
325 // position great_grand_child should not be affected.
326 expected_child_transform.MakeIdentity();
327 expected_child_transform.Translate(-10.0, -10.0);
328 expected_grand_child_transform.MakeIdentity();
329 expected_grand_child_transform.Translate(-2.0, -4.0);
330 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
331 child->draw_transform());
332 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
333 grand_child->draw_transform());
334 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
335 great_grand_child->draw_transform());
337 // Case 3: fixed-container size delta of 20, 20
338 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
339 ExecuteCalculateDrawProperties(root_.get());
341 // Top-left fixed-position layer should not be affected by container size.
342 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
343 child->draw_transform());
344 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
345 grand_child->draw_transform());
346 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
347 great_grand_child->draw_transform());
349 // Case 4: Bottom-right fixed-position layer.
350 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
351 ExecuteCalculateDrawProperties(root_.get());
353 // Bottom-right fixed-position layer moves as container resizes.
354 expected_great_grand_child_transform.MakeIdentity();
355 // Apply size delta from the child(container) layer.
356 expected_great_grand_child_transform.Translate(20.0, 20.0);
357 // Apply layer position from the grand child layer.
358 expected_great_grand_child_transform.Translate(8.0, 6.0);
360 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
361 child->draw_transform());
362 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
363 grand_child->draw_transform());
364 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
365 great_grand_child->draw_transform());
368 TEST_F(LayerPositionConstraintTest,
369 ScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms) {
370 // This test checks for correct scroll compensation when the fixed-position
371 // container is NOT the direct parent of the fixed-position layer, and the
372 // hierarchy has various transforms that have to be processed in the correct
373 // order.
374 LayerImpl* child = scroll_->children()[0];
375 LayerImpl* grand_child = child->children()[0];
376 LayerImpl* great_grand_child = grand_child->children()[0];
378 gfx::Transform rotation_about_z;
379 rotation_about_z.RotateAboutZAxis(90.0);
381 child->SetIsContainerForFixedPositionLayers(true);
382 child->SetTransform(rotation_about_z);
383 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
384 grand_child->SetTransform(rotation_about_z);
385 // great_grand_child is positioned upside-down with respect to the render
386 // target.
387 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
389 // Case 1: scroll delta of 0, 0
390 child->SetScrollDelta(gfx::Vector2d(0, 0));
391 ExecuteCalculateDrawProperties(root_.get());
393 gfx::Transform expected_child_transform;
394 expected_child_transform.PreconcatTransform(rotation_about_z);
396 gfx::Transform expected_grand_child_transform;
397 expected_grand_child_transform.PreconcatTransform(
398 rotation_about_z); // child's local transform is inherited
399 // translation because of position occurs before layer's local transform.
400 expected_grand_child_transform.Translate(8.0, 6.0);
401 expected_grand_child_transform.PreconcatTransform(
402 rotation_about_z); // grand_child's local transform
404 gfx::Transform expected_great_grand_child_transform =
405 expected_grand_child_transform;
407 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
408 child->draw_transform());
409 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
410 grand_child->draw_transform());
411 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
412 great_grand_child->draw_transform());
414 // Case 2: scroll delta of 10, 20
415 child->SetScrollDelta(gfx::Vector2d(10, 20));
416 ExecuteCalculateDrawProperties(root_.get());
418 // Here the child and grand_child are affected by scroll delta, but the fixed
419 // position great_grand_child should not be affected.
420 expected_child_transform.MakeIdentity();
421 expected_child_transform.Translate(-10.0, -20.0); // scroll delta
422 expected_child_transform.PreconcatTransform(rotation_about_z);
424 expected_grand_child_transform.MakeIdentity();
425 expected_grand_child_transform.Translate(
426 -10.0, -20.0); // child's scroll delta is inherited
427 expected_grand_child_transform.PreconcatTransform(
428 rotation_about_z); // child's local transform is inherited
429 // translation because of position occurs before layer's local transform.
430 expected_grand_child_transform.Translate(8.0, 6.0);
431 expected_grand_child_transform.PreconcatTransform(
432 rotation_about_z); // grand_child's local transform
434 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
435 child->draw_transform());
436 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
437 grand_child->draw_transform());
438 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
439 great_grand_child->draw_transform());
441 // Case 3: fixed-container size delta of 20, 20
442 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
443 ExecuteCalculateDrawProperties(root_.get());
445 // Top-left fixed-position layer should not be affected by container size.
446 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
447 child->draw_transform());
448 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
449 grand_child->draw_transform());
450 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
451 great_grand_child->draw_transform());
453 // Case 4: Bottom-right fixed-position layer.
454 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
455 ExecuteCalculateDrawProperties(root_.get());
457 // Bottom-right fixed-position layer moves as container resizes.
458 expected_great_grand_child_transform.MakeIdentity();
459 // Apply child layer transform.
460 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
461 // Apply size delta from the child(container) layer.
462 expected_great_grand_child_transform.Translate(20.0, 20.0);
463 // Apply layer position from the grand child layer.
464 expected_great_grand_child_transform.Translate(8.0, 6.0);
465 // Apply grand child layer transform.
466 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
468 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
469 child->draw_transform());
470 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
471 grand_child->draw_transform());
472 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
473 great_grand_child->draw_transform());
476 TEST_F(LayerPositionConstraintTest,
477 ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas) {
478 // This test checks for correct scroll compensation when the fixed-position
479 // container has multiple ancestors that have nonzero scroll delta before
480 // reaching the space where the layer is fixed. In this test, each scroll
481 // delta occurs in a different space because of each layer's local transform.
482 // This test checks for correct scroll compensation when the fixed-position
483 // container is NOT the direct parent of the fixed-position layer, and the
484 // hierarchy has various transforms that have to be processed in the correct
485 // order.
486 LayerImpl* child = scroll_->children()[0];
487 LayerImpl* grand_child = child->children()[0];
488 LayerImpl* great_grand_child = grand_child->children()[0];
490 gfx::Transform rotation_about_z;
491 rotation_about_z.RotateAboutZAxis(90.0);
493 child->SetIsContainerForFixedPositionLayers(true);
494 child->SetTransform(rotation_about_z);
495 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
496 grand_child->SetTransform(rotation_about_z);
497 // great_grand_child is positioned upside-down with respect to the render
498 // target.
499 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
501 // Case 1: scroll delta of 0, 0
502 child->SetScrollDelta(gfx::Vector2d(0, 0));
503 ExecuteCalculateDrawProperties(root_.get());
505 gfx::Transform expected_child_transform;
506 expected_child_transform.PreconcatTransform(rotation_about_z);
508 gfx::Transform expected_grand_child_transform;
509 expected_grand_child_transform.PreconcatTransform(
510 rotation_about_z); // child's local transform is inherited
511 // translation because of position occurs before layer's local transform.
512 expected_grand_child_transform.Translate(8.0, 6.0);
513 expected_grand_child_transform.PreconcatTransform(
514 rotation_about_z); // grand_child's local transform
516 gfx::Transform expected_great_grand_child_transform =
517 expected_grand_child_transform;
519 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
520 child->draw_transform());
521 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
522 grand_child->draw_transform());
523 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
524 great_grand_child->draw_transform());
526 // Case 2: scroll delta of 10, 20
527 child->SetScrollDelta(gfx::Vector2d(10, 0));
528 grand_child->SetScrollDelta(gfx::Vector2d(5, 0));
529 ExecuteCalculateDrawProperties(root_.get());
531 // Here the child and grand_child are affected by scroll delta, but the fixed
532 // position great_grand_child should not be affected.
533 expected_child_transform.MakeIdentity();
534 expected_child_transform.Translate(-10.0, 0.0); // scroll delta
535 expected_child_transform.PreconcatTransform(rotation_about_z);
537 expected_grand_child_transform.MakeIdentity();
538 expected_grand_child_transform.Translate(
539 -10.0, 0.0); // child's scroll delta is inherited
540 expected_grand_child_transform.PreconcatTransform(
541 rotation_about_z); // child's local transform is inherited
542 expected_grand_child_transform.Translate(-5.0,
543 0.0); // grand_child's scroll delta
544 // translation because of position occurs before layer's local transform.
545 expected_grand_child_transform.Translate(8.0, 6.0);
546 expected_grand_child_transform.PreconcatTransform(
547 rotation_about_z); // grand_child's local transform
549 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
550 child->draw_transform());
551 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
552 grand_child->draw_transform());
553 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
554 great_grand_child->draw_transform());
556 // Case 3: fixed-container size delta of 20, 20
557 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
558 ExecuteCalculateDrawProperties(root_.get());
560 // Top-left fixed-position layer should not be affected by container size.
561 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
562 child->draw_transform());
563 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
564 grand_child->draw_transform());
565 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
566 great_grand_child->draw_transform());
568 // Case 4: Bottom-right fixed-position layer.
569 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
570 ExecuteCalculateDrawProperties(root_.get());
572 // Bottom-right fixed-position layer moves as container resizes.
573 expected_great_grand_child_transform.MakeIdentity();
574 // Apply child layer transform.
575 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
576 // Apply size delta from the child(container) layer.
577 expected_great_grand_child_transform.Translate(20.0, 20.0);
578 // Apply layer position from the grand child layer.
579 expected_great_grand_child_transform.Translate(8.0, 6.0);
580 // Apply grand child layer transform.
581 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
583 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
584 child->draw_transform());
585 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
586 grand_child->draw_transform());
587 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
588 great_grand_child->draw_transform());
591 TEST_F(LayerPositionConstraintTest,
592 ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms) {
593 // This test checks for correct scroll compensation when the fixed-position
594 // container contributes to a different render surface than the fixed-position
595 // layer. In this case, the surface draw transforms also have to be accounted
596 // for when checking the scroll delta.
597 LayerImpl* child = scroll_->children()[0];
598 LayerImpl* grand_child = child->children()[0];
599 LayerImpl* great_grand_child = grand_child->children()[0];
601 child->SetIsContainerForFixedPositionLayers(true);
602 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
603 grand_child->SetHasRenderSurface(true);
604 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
605 great_grand_child->SetDrawsContent(true);
607 gfx::Transform rotation_about_z;
608 rotation_about_z.RotateAboutZAxis(90.0);
609 grand_child->SetTransform(rotation_about_z);
611 // Case 1: scroll delta of 0, 0
612 child->SetScrollDelta(gfx::Vector2d(0, 0));
613 ExecuteCalculateDrawProperties(root_.get());
615 gfx::Transform expected_child_transform;
616 gfx::Transform expected_surface_draw_transform;
617 expected_surface_draw_transform.Translate(8.0, 6.0);
618 expected_surface_draw_transform.PreconcatTransform(rotation_about_z);
619 gfx::Transform expected_grand_child_transform;
620 gfx::Transform expected_great_grand_child_transform;
621 ASSERT_TRUE(grand_child->render_surface());
622 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
623 child->draw_transform());
624 EXPECT_TRANSFORMATION_MATRIX_EQ(
625 expected_surface_draw_transform,
626 grand_child->render_surface()->draw_transform());
627 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
628 grand_child->draw_transform());
629 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
630 great_grand_child->draw_transform());
632 // Case 2: scroll delta of 10, 30
633 child->SetScrollDelta(gfx::Vector2d(10, 30));
634 ExecuteCalculateDrawProperties(root_.get());
636 // Here the grand_child remains unchanged, because it scrolls along with the
637 // render surface, and the translation is actually in the render surface. But,
638 // the fixed position great_grand_child is more awkward: its actually being
639 // drawn with respect to the render surface, but it needs to remain fixed with
640 // resepct to a container beyond that surface. So, the net result is that,
641 // unlike previous tests where the fixed position layer's transform remains
642 // unchanged, here the fixed position layer's transform explicitly contains
643 // the translation that cancels out the scroll.
644 expected_child_transform.MakeIdentity();
645 expected_child_transform.Translate(-10.0, -30.0); // scroll delta
647 expected_surface_draw_transform.MakeIdentity();
648 expected_surface_draw_transform.Translate(-10.0, -30.0); // scroll delta
649 expected_surface_draw_transform.Translate(8.0, 6.0);
650 expected_surface_draw_transform.PreconcatTransform(rotation_about_z);
652 // The rotation and its inverse are needed to place the scroll delta
653 // compensation in the correct space. This test will fail if the
654 // rotation/inverse are backwards, too, so it requires perfect order of
655 // operations.
656 expected_great_grand_child_transform.MakeIdentity();
657 expected_great_grand_child_transform.PreconcatTransform(
658 Inverse(rotation_about_z));
659 // explicit canceling out the scroll delta that gets embedded in the fixed
660 // position layer's surface.
661 expected_great_grand_child_transform.Translate(10.0, 30.0);
662 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
664 ASSERT_TRUE(grand_child->render_surface());
665 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
666 child->draw_transform());
667 EXPECT_TRANSFORMATION_MATRIX_EQ(
668 expected_surface_draw_transform,
669 grand_child->render_surface()->draw_transform());
670 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
671 grand_child->draw_transform());
672 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
673 great_grand_child->draw_transform());
675 // Case 3: fixed-container size delta of 20, 20
676 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
677 ExecuteCalculateDrawProperties(root_.get());
679 // Top-left fixed-position layer should not be affected by container size.
680 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
681 child->draw_transform());
682 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
683 grand_child->draw_transform());
684 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
685 great_grand_child->draw_transform());
687 // Case 4: Bottom-right fixed-position layer.
688 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
689 ExecuteCalculateDrawProperties(root_.get());
691 // Bottom-right fixed-position layer moves as container resizes.
692 expected_great_grand_child_transform.MakeIdentity();
693 // The rotation and its inverse are needed to place the scroll delta
694 // compensation in the correct space. This test will fail if the
695 // rotation/inverse are backwards, too, so it requires perfect order of
696 // operations.
697 expected_great_grand_child_transform.PreconcatTransform(
698 Inverse(rotation_about_z));
699 // explicit canceling out the scroll delta that gets embedded in the fixed
700 // position layer's surface.
701 expected_great_grand_child_transform.Translate(10.0, 30.0);
702 // Also apply size delta in the child(container) layer space.
703 expected_great_grand_child_transform.Translate(20.0, 20.0);
704 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
706 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
707 child->draw_transform());
708 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
709 grand_child->draw_transform());
710 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
711 great_grand_child->draw_transform());
714 TEST_F(LayerPositionConstraintTest,
715 ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces) {
716 // This test checks for correct scroll compensation when the fixed-position
717 // container contributes to a different render surface than the fixed-position
718 // layer, with additional render surfaces in-between. This checks that the
719 // conversion to ancestor surfaces is accumulated properly in the final matrix
720 // transform.
721 LayerImpl* child = scroll_->children()[0];
722 LayerImpl* grand_child = child->children()[0];
723 LayerImpl* great_grand_child = grand_child->children()[0];
725 // Add one more layer to the test tree for this scenario.
727 gfx::Transform identity;
728 scoped_ptr<LayerImpl> fixed_position_child =
729 LayerImpl::Create(host_impl_.active_tree(), 5);
730 SetLayerPropertiesForTesting(fixed_position_child.get(),
731 identity,
732 gfx::Point3F(),
733 gfx::PointF(),
734 gfx::Size(100, 100),
735 true);
736 great_grand_child->AddChild(fixed_position_child.Pass());
738 LayerImpl* fixed_position_child = great_grand_child->children()[0];
740 // Actually set up the scenario here.
741 child->SetIsContainerForFixedPositionLayers(true);
742 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
743 grand_child->SetHasRenderSurface(true);
744 great_grand_child->SetPosition(gfx::PointF(40.f, 60.f));
745 great_grand_child->SetHasRenderSurface(true);
746 fixed_position_child->SetPositionConstraint(fixed_to_top_left_);
747 fixed_position_child->SetDrawsContent(true);
749 // The additional rotations, which are non-commutative with translations, help
750 // to verify that we have correct order-of-operations in the final scroll
751 // compensation. Note that rotating about the center of the layer ensures we
752 // do not accidentally clip away layers that we want to test.
753 gfx::Transform rotation_about_z;
754 rotation_about_z.Translate(50.0, 50.0);
755 rotation_about_z.RotateAboutZAxis(90.0);
756 rotation_about_z.Translate(-50.0, -50.0);
757 grand_child->SetTransform(rotation_about_z);
758 great_grand_child->SetTransform(rotation_about_z);
760 // Case 1: scroll delta of 0, 0
761 child->SetScrollDelta(gfx::Vector2d(0, 0));
762 ExecuteCalculateDrawProperties(root_.get());
764 gfx::Transform expected_child_transform;
766 gfx::Transform expected_grand_child_surface_draw_transform;
767 expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
768 expected_grand_child_surface_draw_transform.PreconcatTransform(
769 rotation_about_z);
771 gfx::Transform expected_grand_child_transform;
773 gfx::Transform expected_great_grand_child_surface_draw_transform;
774 expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0);
775 expected_great_grand_child_surface_draw_transform.PreconcatTransform(
776 rotation_about_z);
778 gfx::Transform expected_great_grand_child_transform;
780 gfx::Transform expected_fixed_position_child_transform;
782 ASSERT_TRUE(grand_child->render_surface());
783 ASSERT_TRUE(great_grand_child->render_surface());
784 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
785 child->draw_transform());
786 EXPECT_TRANSFORMATION_MATRIX_EQ(
787 expected_grand_child_surface_draw_transform,
788 grand_child->render_surface()->draw_transform());
789 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
790 grand_child->draw_transform());
791 EXPECT_TRANSFORMATION_MATRIX_EQ(
792 expected_great_grand_child_surface_draw_transform,
793 great_grand_child->render_surface()->draw_transform());
794 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
795 great_grand_child->draw_transform());
796 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
797 fixed_position_child->draw_transform());
799 // Case 2: scroll delta of 10, 30
800 child->SetScrollDelta(gfx::Vector2d(10, 30));
801 ExecuteCalculateDrawProperties(root_.get());
803 expected_child_transform.MakeIdentity();
804 expected_child_transform.Translate(-10.0, -30.0); // scroll delta
806 expected_grand_child_surface_draw_transform.MakeIdentity();
807 expected_grand_child_surface_draw_transform.Translate(-10.0,
808 -30.0); // scroll delta
809 expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
810 expected_grand_child_surface_draw_transform.PreconcatTransform(
811 rotation_about_z);
813 // grand_child, great_grand_child, and great_grand_child's surface are not
814 // expected to change, since they are all not fixed, and they are all drawn
815 // with respect to grand_child's surface that already has the scroll delta
816 // accounted for.
818 // But the great-great grandchild, "fixed_position_child", should have a
819 // transform that explicitly cancels out the scroll delta. The expected
820 // transform is: compound_draw_transform.Inverse() * translate(positive scroll
821 // delta) * compound_origin_transform from great_grand_childSurface's origin
822 // to the root surface.
823 gfx::Transform compound_draw_transform;
824 compound_draw_transform.Translate(8.0,
825 6.0); // origin translation of grand_child
826 compound_draw_transform.PreconcatTransform(
827 rotation_about_z); // rotation of grand_child
828 compound_draw_transform.Translate(
829 40.0, 60.0); // origin translation of great_grand_child
830 compound_draw_transform.PreconcatTransform(
831 rotation_about_z); // rotation of great_grand_child
833 expected_fixed_position_child_transform.MakeIdentity();
834 expected_fixed_position_child_transform.PreconcatTransform(
835 Inverse(compound_draw_transform));
836 // explicit canceling out the scroll delta that gets embedded in the fixed
837 // position layer's surface.
838 expected_fixed_position_child_transform.Translate(10.0, 30.0);
839 expected_fixed_position_child_transform.PreconcatTransform(
840 compound_draw_transform);
842 ASSERT_TRUE(grand_child->render_surface());
843 ASSERT_TRUE(great_grand_child->render_surface());
844 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
845 child->draw_transform());
846 EXPECT_TRANSFORMATION_MATRIX_EQ(
847 expected_grand_child_surface_draw_transform,
848 grand_child->render_surface()->draw_transform());
849 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
850 grand_child->draw_transform());
851 EXPECT_TRANSFORMATION_MATRIX_EQ(
852 expected_great_grand_child_surface_draw_transform,
853 great_grand_child->render_surface()->draw_transform());
854 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
855 great_grand_child->draw_transform());
856 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
857 fixed_position_child->draw_transform());
860 // Case 3: fixed-container size delta of 20, 20
861 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
862 ExecuteCalculateDrawProperties(root_.get());
864 // Top-left fixed-position layer should not be affected by container size.
865 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
866 child->draw_transform());
867 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
868 grand_child->draw_transform());
869 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
870 great_grand_child->draw_transform());
871 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
872 fixed_position_child->draw_transform());
874 // Case 4: Bottom-right fixed-position layer.
875 fixed_position_child->SetPositionConstraint(fixed_to_bottom_right_);
876 ExecuteCalculateDrawProperties(root_.get());
878 // Bottom-right fixed-position layer moves as container resizes.
879 expected_fixed_position_child_transform.MakeIdentity();
880 expected_fixed_position_child_transform.PreconcatTransform(
881 Inverse(compound_draw_transform));
882 // explicit canceling out the scroll delta that gets embedded in the fixed
883 // position layer's surface.
884 expected_fixed_position_child_transform.Translate(10.0, 30.0);
885 // Also apply size delta in the child(container) layer space.
886 expected_fixed_position_child_transform.Translate(20.0, 20.0);
887 expected_fixed_position_child_transform.PreconcatTransform(
888 compound_draw_transform);
890 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
891 child->draw_transform());
892 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
893 grand_child->draw_transform());
894 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
895 great_grand_child->draw_transform());
896 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
897 fixed_position_child->draw_transform());
900 TEST_F(LayerPositionConstraintTest,
901 ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface) {
902 // This test checks for correct scroll compensation when the fixed-position
903 // container itself has a render surface. In this case, the container layer
904 // should be treated like a layer that contributes to a render target, and
905 // that render target is completely irrelevant; it should not affect the
906 // scroll compensation.
907 LayerImpl* child = scroll_->children()[0];
908 LayerImpl* grand_child = child->children()[0];
910 child->SetIsContainerForFixedPositionLayers(true);
911 child->SetHasRenderSurface(true);
912 grand_child->SetPositionConstraint(fixed_to_top_left_);
913 grand_child->SetDrawsContent(true);
915 // Case 1: scroll delta of 0, 0
916 child->SetScrollDelta(gfx::Vector2d(0, 0));
917 ExecuteCalculateDrawProperties(root_.get());
919 gfx::Transform expected_surface_draw_transform;
920 expected_surface_draw_transform.Translate(0.0, 0.0);
921 gfx::Transform expected_child_transform;
922 gfx::Transform expected_grand_child_transform;
923 ASSERT_TRUE(child->render_surface());
924 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
925 child->render_surface()->draw_transform());
926 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
927 child->draw_transform());
928 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
929 grand_child->draw_transform());
931 // Case 2: scroll delta of 10, 10
932 child->SetScrollDelta(gfx::Vector2d(10, 10));
933 ExecuteCalculateDrawProperties(root_.get());
935 // The surface is translated by scroll delta, the child transform doesn't
936 // change because it scrolls along with the surface, but the fixed position
937 // grand_child needs to compensate for the scroll translation.
938 expected_surface_draw_transform.MakeIdentity();
939 expected_surface_draw_transform.Translate(-10.0, -10.0);
940 expected_grand_child_transform.MakeIdentity();
941 expected_grand_child_transform.Translate(10.0, 10.0);
943 ASSERT_TRUE(child->render_surface());
944 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
945 child->render_surface()->draw_transform());
946 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
947 child->draw_transform());
948 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
949 grand_child->draw_transform());
951 // Case 3: fixed-container size delta of 20, 20
952 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
953 ExecuteCalculateDrawProperties(root_.get());
955 // Top-left fixed-position layer should not be affected by container size.
956 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
957 child->draw_transform());
958 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
959 grand_child->draw_transform());
961 // Case 4: Bottom-right fixed-position layer.
962 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
963 ExecuteCalculateDrawProperties(root_.get());
965 // Bottom-right fixed-position layer moves as container resizes.
966 expected_grand_child_transform.MakeIdentity();
967 // The surface is translated by scroll delta, the child transform doesn't
968 // change because it scrolls along with the surface, but the fixed position
969 // grand_child needs to compensate for the scroll translation.
970 expected_grand_child_transform.Translate(10.0, 10.0);
971 // Apply size delta from the child(container) layer.
972 expected_grand_child_transform.Translate(20.0, 20.0);
974 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
975 child->draw_transform());
976 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
977 grand_child->draw_transform());
980 TEST_F(LayerPositionConstraintTest,
981 ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer) {
982 // This test checks the scenario where a fixed-position layer also happens to
983 // be a container itself for a descendant fixed position layer. In particular,
984 // the layer should not accidentally be fixed to itself.
985 LayerImpl* child = scroll_->children()[0];
986 LayerImpl* grand_child = child->children()[0];
988 child->SetIsContainerForFixedPositionLayers(true);
989 grand_child->SetPositionConstraint(fixed_to_top_left_);
991 // This should not confuse the grand_child. If correct, the grand_child would
992 // still be considered fixed to its container (i.e. "child").
993 grand_child->SetIsContainerForFixedPositionLayers(true);
995 // Case 1: scroll delta of 0, 0
996 child->SetScrollDelta(gfx::Vector2d(0, 0));
997 ExecuteCalculateDrawProperties(root_.get());
999 gfx::Transform expected_child_transform;
1000 gfx::Transform expected_grand_child_transform;
1001 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1002 child->draw_transform());
1003 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1004 grand_child->draw_transform());
1006 // Case 2: scroll delta of 10, 10
1007 child->SetScrollDelta(gfx::Vector2d(10, 10));
1008 ExecuteCalculateDrawProperties(root_.get());
1010 // Here the child is affected by scroll delta, but the fixed position
1011 // grand_child should not be affected.
1012 expected_child_transform.MakeIdentity();
1013 expected_child_transform.Translate(-10.0, -10.0);
1014 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1015 child->draw_transform());
1016 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1017 grand_child->draw_transform());
1019 // Case 3: fixed-container size delta of 20, 20
1020 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
1021 ExecuteCalculateDrawProperties(root_.get());
1023 // Top-left fixed-position layer should not be affected by container size.
1024 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1025 child->draw_transform());
1026 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1027 grand_child->draw_transform());
1029 // Case 4: Bottom-right fixed-position layer.
1030 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
1031 ExecuteCalculateDrawProperties(root_.get());
1033 // Bottom-right fixed-position layer moves as container resizes.
1034 expected_grand_child_transform.MakeIdentity();
1035 // Apply size delta from the child(container) layer.
1036 expected_grand_child_transform.Translate(20.0, 20.0);
1038 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1039 child->draw_transform());
1040 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1041 grand_child->draw_transform());
1044 TEST_F(LayerPositionConstraintTest,
1045 ScrollCompensationForFixedWithinFixedWithSameContainer) {
1046 // This test checks scroll compensation for a fixed-position layer that is
1047 // inside of another fixed-position layer and both share the same container.
1048 // In this situation, the parent fixed-position layer will receive
1049 // the scroll compensation, and the child fixed-position layer does not
1050 // need to compensate further.
1052 LayerImpl* child = scroll_->children()[0];
1053 LayerImpl* grand_child = child->children()[0];
1054 LayerImpl* great_grand_child = grand_child->children()[0];
1056 child->SetIsContainerForFixedPositionLayers(true);
1057 grand_child->SetPositionConstraint(fixed_to_top_left_);
1059 // Note carefully - great_grand_child is fixed to bottom right, to test
1060 // sizeDelta being applied correctly; the compensation skips the grand_child
1061 // because it is fixed to top left.
1062 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
1064 // Case 1: scrollDelta
1065 child->SetScrollDelta(gfx::Vector2d(10, 10));
1066 ExecuteCalculateDrawProperties(root_.get());
1068 // Here the child is affected by scroll delta, but the fixed position
1069 // grand_child should not be affected.
1070 gfx::Transform expected_child_transform;
1071 expected_child_transform.Translate(-10.0, -10.0);
1073 gfx::Transform expected_grand_child_transform;
1074 gfx::Transform expected_great_grand_child_transform;
1076 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1077 child->draw_transform());
1078 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1079 grand_child->draw_transform());
1080 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
1081 great_grand_child->draw_transform());
1083 // Case 2: sizeDelta
1084 child->SetScrollDelta(gfx::Vector2d(0, 0));
1085 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
1086 ExecuteCalculateDrawProperties(root_.get());
1088 expected_child_transform.MakeIdentity();
1090 expected_grand_child_transform.MakeIdentity();
1092 // Fixed to bottom-right, size-delta compensation is applied.
1093 expected_great_grand_child_transform.MakeIdentity();
1094 expected_great_grand_child_transform.Translate(20.0, 20.0);
1096 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1097 child->draw_transform());
1098 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1099 grand_child->draw_transform());
1100 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
1101 great_grand_child->draw_transform());
1104 TEST_F(LayerPositionConstraintTest,
1105 ScrollCompensationForFixedWithinFixedWithInterveningContainer) {
1106 // This test checks scroll compensation for a fixed-position layer that is
1107 // inside of another fixed-position layer, but they have different fixed
1108 // position containers. In this situation, the child fixed-position element
1109 // would still have to compensate with respect to its container.
1111 LayerImpl* container1 = scroll_->children()[0];
1112 LayerImpl* fixed_to_container1 = container1->children()[0];
1113 LayerImpl* container2 = fixed_to_container1->children()[0];
1116 // Add one more layer to the hierarchy for this test.
1117 scoped_ptr<LayerImpl> fixed_to_container2_ptr =
1118 LayerImpl::Create(host_impl_.active_tree(), 5);
1119 container2->AddChild(fixed_to_container2_ptr.Pass());
1122 LayerImpl* fixed_to_container2 = container2->children()[0];
1124 container1->SetIsContainerForFixedPositionLayers(true);
1125 fixed_to_container1->SetPositionConstraint(fixed_to_top_left_);
1126 container2->SetIsContainerForFixedPositionLayers(true);
1127 fixed_to_container2->SetPositionConstraint(fixed_to_top_left_);
1129 container1->SetScrollDelta(gfx::Vector2d(0, 15));
1130 container2->SetScrollDelta(gfx::Vector2d(30, 0));
1131 ExecuteCalculateDrawProperties(root_.get());
1133 gfx::Transform expected_container1_transform;
1134 expected_container1_transform.Translate(0.0, -15.0);
1136 gfx::Transform expected_fixed_to_container1_transform;
1138 // Since the container is a descendant of the fixed layer above,
1139 // the expected draw transform for container2 would not
1140 // include the scrollDelta that was applied to container1.
1141 gfx::Transform expected_container2_transform;
1142 expected_container2_transform.Translate(-30.0, 0.0);
1144 gfx::Transform expected_fixed_to_container2_transform;
1146 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform,
1147 container1->draw_transform());
1149 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform,
1150 fixed_to_container1->draw_transform());
1152 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform,
1153 container2->draw_transform());
1155 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform,
1156 fixed_to_container2->draw_transform());
1158 } // namespace
1159 } // namespace cc