Use multiline attribute to check for IA2_STATE_MULTILINE.
[chromium-blink-merge.git] / cc / layers / layer_position_constraint_unittest.cc
blob1eea9c98b44e383bb0c80e825a05a5bb6c99d097
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/test/test_task_graph_runner.h"
15 #include "cc/trees/layer_tree_host_common.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace cc {
19 namespace {
21 void SetLayerPropertiesForTesting(LayerImpl* layer,
22 const gfx::Transform& transform,
23 const gfx::Point3F& transform_origin,
24 const gfx::PointF& position,
25 const gfx::Size& bounds,
26 bool flatten_transform) {
27 layer->SetTransform(transform);
28 layer->SetTransformOrigin(transform_origin);
29 layer->SetPosition(position);
30 layer->SetBounds(bounds);
31 layer->SetShouldFlattenTransform(flatten_transform);
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 = nullptr;
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_, &shared_bitmap_manager_, &task_graph_runner_) {
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 root->SetHasRenderSurface(true);
90 gfx::Transform IdentityMatrix;
91 gfx::Point3F transform_origin;
92 gfx::PointF position;
93 gfx::Size bounds(200, 200);
94 gfx::Size clip_bounds(100, 100);
95 SetLayerPropertiesForTesting(scroll_layer.get(),
96 IdentityMatrix,
97 transform_origin,
98 position,
99 bounds,
100 true);
101 SetLayerPropertiesForTesting(
102 child.get(), IdentityMatrix, transform_origin, position, bounds, true);
103 SetLayerPropertiesForTesting(grand_child.get(),
104 IdentityMatrix,
105 transform_origin,
106 position,
107 bounds,
108 true);
109 SetLayerPropertiesForTesting(great_grand_child.get(),
110 IdentityMatrix,
111 transform_origin,
112 position,
113 bounds,
114 true);
116 root->SetBounds(clip_bounds);
117 scroll_layer->SetScrollClipLayer(root->id());
118 child->SetScrollClipLayer(root->id());
119 grand_child->SetScrollClipLayer(root->id());
121 grand_child->AddChild(great_grand_child.Pass());
122 child->AddChild(grand_child.Pass());
123 scroll_layer->AddChild(child.Pass());
124 root->AddChild(scroll_layer.Pass());
126 return root.Pass();
129 protected:
130 FakeImplProxy proxy_;
131 TestSharedBitmapManager shared_bitmap_manager_;
132 TestTaskGraphRunner task_graph_runner_;
133 FakeLayerTreeHostImpl host_impl_;
134 scoped_ptr<LayerImpl> root_;
135 LayerImpl* scroll_;
137 LayerPositionConstraint fixed_to_top_left_;
138 LayerPositionConstraint fixed_to_bottom_right_;
141 namespace {
143 void SetFixedContainerSizeDelta(LayerImpl* scroll_layer,
144 const gfx::Vector2d& delta) {
145 DCHECK(scroll_layer);
146 DCHECK(scroll_layer->scrollable());
148 LayerImpl* container_layer = scroll_layer->scroll_clip_layer();
149 container_layer->SetBoundsDelta(delta);
151 } // namespace
153 TEST_F(LayerPositionConstraintTest,
154 ScrollCompensationForFixedPositionLayerWithDirectContainer) {
155 // This test checks for correct scroll compensation when the fixed-position
156 // container is the direct parent of the fixed-position layer.
157 LayerImpl* child = scroll_->children()[0];
158 LayerImpl* grand_child = child->children()[0];
160 child->SetIsContainerForFixedPositionLayers(true);
161 grand_child->SetPositionConstraint(fixed_to_top_left_);
163 // Case 1: scroll delta of 0, 0
164 child->SetScrollDelta(gfx::Vector2d(0, 0));
165 ExecuteCalculateDrawProperties(root_.get());
167 gfx::Transform expected_child_transform;
168 gfx::Transform expected_grand_child_transform = expected_child_transform;
170 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
171 child->draw_transform());
172 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
173 grand_child->draw_transform());
175 // Case 2: scroll delta of 10, 10
176 child->SetScrollDelta(gfx::Vector2d(10, 10));
177 ExecuteCalculateDrawProperties(root_.get());
179 // Here the child is affected by scroll delta, but the fixed position
180 // grand_child should not be affected.
181 expected_child_transform.MakeIdentity();
182 expected_child_transform.Translate(-10.0, -10.0);
184 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
185 child->draw_transform());
186 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
187 grand_child->draw_transform());
189 // Case 3: fixed-container size delta of 20, 20
190 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
191 ExecuteCalculateDrawProperties(root_.get());
193 // Top-left fixed-position layer should not be affected by container size.
194 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
195 child->draw_transform());
196 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
197 grand_child->draw_transform());
199 // Case 4: Bottom-right fixed-position layer.
200 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
201 ExecuteCalculateDrawProperties(root_.get());
203 // Bottom-right fixed-position layer moves as container resizes.
204 expected_grand_child_transform.MakeIdentity();
205 // Apply size delta from the child(container) layer.
206 expected_grand_child_transform.Translate(20.0, 20.0);
208 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
209 child->draw_transform());
210 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
211 grand_child->draw_transform());
214 TEST_F(LayerPositionConstraintTest,
215 ScrollCompensationForFixedPositionLayerWithTransformedDirectContainer) {
216 // This test checks for correct scroll compensation when the fixed-position
217 // container is the direct parent of the fixed-position layer, but that
218 // container is transformed. In this case, the fixed position element
219 // inherits the container's transform, but the scroll delta that has to be
220 // undone should not be affected by that transform.
222 // Transforms are in general non-commutative; using something like a
223 // non-uniform scale helps to verify that translations and non-uniform scales
224 // are applied in the correct order.
225 LayerImpl* child = scroll_->children()[0];
226 LayerImpl* grand_child = child->children()[0];
228 // This scale will cause child and grand_child to be effectively 200 x 800
229 // with respect to the render target.
230 gfx::Transform non_uniform_scale;
231 non_uniform_scale.Scale(2.0, 8.0);
232 child->SetTransform(non_uniform_scale);
234 child->SetIsContainerForFixedPositionLayers(true);
235 grand_child->SetPositionConstraint(fixed_to_top_left_);
237 // Case 1: scroll delta of 0, 0
238 child->SetScrollDelta(gfx::Vector2d(0, 0));
239 ExecuteCalculateDrawProperties(root_.get());
241 gfx::Transform expected_child_transform;
242 expected_child_transform.PreconcatTransform(non_uniform_scale);
244 gfx::Transform expected_grand_child_transform = expected_child_transform;
246 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
247 child->draw_transform());
248 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
249 grand_child->draw_transform());
251 // Case 2: scroll delta of 10, 20
252 child->SetScrollDelta(gfx::Vector2d(10, 20));
253 ExecuteCalculateDrawProperties(root_.get());
255 // The child should be affected by scroll delta, but the fixed position
256 // grand_child should not be affected.
257 expected_child_transform.MakeIdentity();
258 expected_child_transform.Translate(-10.0, -20.0); // scroll delta
259 expected_child_transform.PreconcatTransform(non_uniform_scale);
261 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
262 child->draw_transform());
263 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
264 grand_child->draw_transform());
266 // Case 3: fixed-container size delta of 20, 20
267 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
268 ExecuteCalculateDrawProperties(root_.get());
270 // Top-left fixed-position layer should not be affected by container size.
271 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
272 child->draw_transform());
273 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
274 grand_child->draw_transform());
276 // Case 4: Bottom-right fixed-position layer.
277 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
278 ExecuteCalculateDrawProperties(root_.get());
280 // Bottom-right fixed-position layer moves as container resizes.
281 expected_grand_child_transform.MakeIdentity();
282 // Apply child layer transform.
283 expected_grand_child_transform.PreconcatTransform(non_uniform_scale);
284 // Apply size delta from the child(container) layer.
285 expected_grand_child_transform.Translate(20.0, 20.0);
287 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
288 child->draw_transform());
289 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
290 grand_child->draw_transform());
293 TEST_F(LayerPositionConstraintTest,
294 ScrollCompensationForFixedPositionLayerWithDistantContainer) {
295 // This test checks for correct scroll compensation when the fixed-position
296 // container is NOT the direct parent of the fixed-position layer.
297 LayerImpl* child = scroll_->children()[0];
298 LayerImpl* grand_child = child->children()[0];
299 LayerImpl* great_grand_child = grand_child->children()[0];
301 child->SetIsContainerForFixedPositionLayers(true);
302 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
303 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
305 // Case 1: scroll delta of 0, 0
306 child->SetScrollDelta(gfx::Vector2d(0, 0));
307 ExecuteCalculateDrawProperties(root_.get());
309 gfx::Transform expected_child_transform;
310 gfx::Transform expected_grand_child_transform;
311 expected_grand_child_transform.Translate(8.0, 6.0);
313 gfx::Transform expected_great_grand_child_transform =
314 expected_grand_child_transform;
316 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
317 child->draw_transform());
318 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
319 grand_child->draw_transform());
320 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
321 great_grand_child->draw_transform());
323 // Case 2: scroll delta of 10, 10
324 child->SetScrollDelta(gfx::Vector2d(10, 10));
325 ExecuteCalculateDrawProperties(root_.get());
327 // Here the child and grand_child are affected by scroll delta, but the fixed
328 // position great_grand_child should not be affected.
329 expected_child_transform.MakeIdentity();
330 expected_child_transform.Translate(-10.0, -10.0);
331 expected_grand_child_transform.MakeIdentity();
332 expected_grand_child_transform.Translate(-2.0, -4.0);
333 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
334 child->draw_transform());
335 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
336 grand_child->draw_transform());
337 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
338 great_grand_child->draw_transform());
340 // Case 3: fixed-container size delta of 20, 20
341 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
342 ExecuteCalculateDrawProperties(root_.get());
344 // Top-left fixed-position layer should not be affected by container size.
345 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
346 child->draw_transform());
347 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
348 grand_child->draw_transform());
349 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
350 great_grand_child->draw_transform());
352 // Case 4: Bottom-right fixed-position layer.
353 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
354 ExecuteCalculateDrawProperties(root_.get());
356 // Bottom-right fixed-position layer moves as container resizes.
357 expected_great_grand_child_transform.MakeIdentity();
358 // Apply size delta from the child(container) layer.
359 expected_great_grand_child_transform.Translate(20.0, 20.0);
360 // Apply layer position from the grand child layer.
361 expected_great_grand_child_transform.Translate(8.0, 6.0);
363 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
364 child->draw_transform());
365 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
366 grand_child->draw_transform());
367 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
368 great_grand_child->draw_transform());
371 TEST_F(LayerPositionConstraintTest,
372 ScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms) {
373 // This test checks for correct scroll compensation when the fixed-position
374 // container is NOT the direct parent of the fixed-position layer, and the
375 // hierarchy has various transforms that have to be processed in the correct
376 // order.
377 LayerImpl* child = scroll_->children()[0];
378 LayerImpl* grand_child = child->children()[0];
379 LayerImpl* great_grand_child = grand_child->children()[0];
381 gfx::Transform rotation_about_z;
382 rotation_about_z.RotateAboutZAxis(90.0);
384 child->SetIsContainerForFixedPositionLayers(true);
385 child->SetTransform(rotation_about_z);
386 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
387 grand_child->SetTransform(rotation_about_z);
388 // great_grand_child is positioned upside-down with respect to the render
389 // target.
390 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
392 // Case 1: scroll delta of 0, 0
393 child->SetScrollDelta(gfx::Vector2d(0, 0));
394 ExecuteCalculateDrawProperties(root_.get());
396 gfx::Transform expected_child_transform;
397 expected_child_transform.PreconcatTransform(rotation_about_z);
399 gfx::Transform expected_grand_child_transform;
400 expected_grand_child_transform.PreconcatTransform(
401 rotation_about_z); // child's local transform is inherited
402 // translation because of position occurs before layer's local transform.
403 expected_grand_child_transform.Translate(8.0, 6.0);
404 expected_grand_child_transform.PreconcatTransform(
405 rotation_about_z); // grand_child's local transform
407 gfx::Transform expected_great_grand_child_transform =
408 expected_grand_child_transform;
410 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
411 child->draw_transform());
412 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
413 grand_child->draw_transform());
414 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
415 great_grand_child->draw_transform());
417 // Case 2: scroll delta of 10, 20
418 child->SetScrollDelta(gfx::Vector2d(10, 20));
419 ExecuteCalculateDrawProperties(root_.get());
421 // Here the child and grand_child are affected by scroll delta, but the fixed
422 // position great_grand_child should not be affected.
423 expected_child_transform.MakeIdentity();
424 expected_child_transform.Translate(-10.0, -20.0); // scroll delta
425 expected_child_transform.PreconcatTransform(rotation_about_z);
427 expected_grand_child_transform.MakeIdentity();
428 expected_grand_child_transform.Translate(
429 -10.0, -20.0); // child's scroll delta is inherited
430 expected_grand_child_transform.PreconcatTransform(
431 rotation_about_z); // child's local transform is inherited
432 // translation because of position occurs before layer's local transform.
433 expected_grand_child_transform.Translate(8.0, 6.0);
434 expected_grand_child_transform.PreconcatTransform(
435 rotation_about_z); // grand_child's local transform
437 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
438 child->draw_transform());
439 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
440 grand_child->draw_transform());
441 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
442 great_grand_child->draw_transform());
444 // Case 3: fixed-container size delta of 20, 20
445 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
446 ExecuteCalculateDrawProperties(root_.get());
448 // Top-left fixed-position layer should not be affected by container size.
449 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
450 child->draw_transform());
451 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
452 grand_child->draw_transform());
453 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
454 great_grand_child->draw_transform());
456 // Case 4: Bottom-right fixed-position layer.
457 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
458 ExecuteCalculateDrawProperties(root_.get());
460 // Bottom-right fixed-position layer moves as container resizes.
461 expected_great_grand_child_transform.MakeIdentity();
462 // Apply child layer transform.
463 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
464 // Apply size delta from the child(container) layer.
465 expected_great_grand_child_transform.Translate(20.0, 20.0);
466 // Apply layer position from the grand child layer.
467 expected_great_grand_child_transform.Translate(8.0, 6.0);
468 // Apply grand child layer transform.
469 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
471 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
472 child->draw_transform());
473 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
474 grand_child->draw_transform());
475 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
476 great_grand_child->draw_transform());
479 TEST_F(LayerPositionConstraintTest,
480 ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas) {
481 // This test checks for correct scroll compensation when the fixed-position
482 // container has multiple ancestors that have nonzero scroll delta before
483 // reaching the space where the layer is fixed. In this test, each scroll
484 // delta occurs in a different space because of each layer's local transform.
485 // This test checks for correct scroll compensation when the fixed-position
486 // container is NOT the direct parent of the fixed-position layer, and the
487 // hierarchy has various transforms that have to be processed in the correct
488 // order.
489 LayerImpl* child = scroll_->children()[0];
490 LayerImpl* grand_child = child->children()[0];
491 LayerImpl* great_grand_child = grand_child->children()[0];
493 gfx::Transform rotation_about_z;
494 rotation_about_z.RotateAboutZAxis(90.0);
496 child->SetIsContainerForFixedPositionLayers(true);
497 child->SetTransform(rotation_about_z);
498 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
499 grand_child->SetTransform(rotation_about_z);
500 // great_grand_child is positioned upside-down with respect to the render
501 // target.
502 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
504 // Case 1: scroll delta of 0, 0
505 child->SetScrollDelta(gfx::Vector2d(0, 0));
506 ExecuteCalculateDrawProperties(root_.get());
508 gfx::Transform expected_child_transform;
509 expected_child_transform.PreconcatTransform(rotation_about_z);
511 gfx::Transform expected_grand_child_transform;
512 expected_grand_child_transform.PreconcatTransform(
513 rotation_about_z); // child's local transform is inherited
514 // translation because of position occurs before layer's local transform.
515 expected_grand_child_transform.Translate(8.0, 6.0);
516 expected_grand_child_transform.PreconcatTransform(
517 rotation_about_z); // grand_child's local transform
519 gfx::Transform expected_great_grand_child_transform =
520 expected_grand_child_transform;
522 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
523 child->draw_transform());
524 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
525 grand_child->draw_transform());
526 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
527 great_grand_child->draw_transform());
529 // Case 2: scroll delta of 10, 20
530 child->SetScrollDelta(gfx::Vector2d(10, 0));
531 grand_child->SetScrollDelta(gfx::Vector2d(5, 0));
532 ExecuteCalculateDrawProperties(root_.get());
534 // Here the child and grand_child are affected by scroll delta, but the fixed
535 // position great_grand_child should not be affected.
536 expected_child_transform.MakeIdentity();
537 expected_child_transform.Translate(-10.0, 0.0); // scroll delta
538 expected_child_transform.PreconcatTransform(rotation_about_z);
540 expected_grand_child_transform.MakeIdentity();
541 expected_grand_child_transform.Translate(
542 -10.0, 0.0); // child's scroll delta is inherited
543 expected_grand_child_transform.PreconcatTransform(
544 rotation_about_z); // child's local transform is inherited
545 expected_grand_child_transform.Translate(-5.0,
546 0.0); // grand_child's scroll delta
547 // translation because of position occurs before layer's local transform.
548 expected_grand_child_transform.Translate(8.0, 6.0);
549 expected_grand_child_transform.PreconcatTransform(
550 rotation_about_z); // grand_child's local transform
552 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
553 child->draw_transform());
554 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
555 grand_child->draw_transform());
556 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
557 great_grand_child->draw_transform());
559 // Case 3: fixed-container size delta of 20, 20
560 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
561 ExecuteCalculateDrawProperties(root_.get());
563 // Top-left fixed-position layer should not be affected by container size.
564 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
565 child->draw_transform());
566 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
567 grand_child->draw_transform());
568 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
569 great_grand_child->draw_transform());
571 // Case 4: Bottom-right fixed-position layer.
572 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
573 ExecuteCalculateDrawProperties(root_.get());
575 // Bottom-right fixed-position layer moves as container resizes.
576 expected_great_grand_child_transform.MakeIdentity();
577 // Apply child layer transform.
578 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
579 // Apply size delta from the child(container) layer.
580 expected_great_grand_child_transform.Translate(20.0, 20.0);
581 // Apply layer position from the grand child layer.
582 expected_great_grand_child_transform.Translate(8.0, 6.0);
583 // Apply grand child layer transform.
584 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
586 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
587 child->draw_transform());
588 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
589 grand_child->draw_transform());
590 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
591 great_grand_child->draw_transform());
594 TEST_F(LayerPositionConstraintTest,
595 ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms) {
596 // This test checks for correct scroll compensation when the fixed-position
597 // container contributes to a different render surface than the fixed-position
598 // layer. In this case, the surface draw transforms also have to be accounted
599 // for when checking the scroll delta.
600 LayerImpl* child = scroll_->children()[0];
601 LayerImpl* grand_child = child->children()[0];
602 LayerImpl* great_grand_child = grand_child->children()[0];
604 child->SetIsContainerForFixedPositionLayers(true);
605 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
606 grand_child->SetHasRenderSurface(true);
607 great_grand_child->SetPositionConstraint(fixed_to_top_left_);
608 great_grand_child->SetDrawsContent(true);
610 gfx::Transform rotation_about_z;
611 rotation_about_z.RotateAboutZAxis(90.0);
612 grand_child->SetTransform(rotation_about_z);
614 // Case 1: scroll delta of 0, 0
615 child->SetScrollDelta(gfx::Vector2d(0, 0));
616 ExecuteCalculateDrawProperties(root_.get());
618 gfx::Transform expected_child_transform;
619 gfx::Transform expected_surface_draw_transform;
620 expected_surface_draw_transform.Translate(8.0, 6.0);
621 expected_surface_draw_transform.PreconcatTransform(rotation_about_z);
622 gfx::Transform expected_grand_child_transform;
623 gfx::Transform expected_great_grand_child_transform;
624 ASSERT_TRUE(grand_child->render_surface());
625 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
626 child->draw_transform());
627 EXPECT_TRANSFORMATION_MATRIX_EQ(
628 expected_surface_draw_transform,
629 grand_child->render_surface()->draw_transform());
630 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
631 grand_child->draw_transform());
632 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
633 great_grand_child->draw_transform());
635 // Case 2: scroll delta of 10, 30
636 child->SetScrollDelta(gfx::Vector2d(10, 30));
637 ExecuteCalculateDrawProperties(root_.get());
639 // Here the grand_child remains unchanged, because it scrolls along with the
640 // render surface, and the translation is actually in the render surface. But,
641 // the fixed position great_grand_child is more awkward: its actually being
642 // drawn with respect to the render surface, but it needs to remain fixed with
643 // resepct to a container beyond that surface. So, the net result is that,
644 // unlike previous tests where the fixed position layer's transform remains
645 // unchanged, here the fixed position layer's transform explicitly contains
646 // the translation that cancels out the scroll.
647 expected_child_transform.MakeIdentity();
648 expected_child_transform.Translate(-10.0, -30.0); // scroll delta
650 expected_surface_draw_transform.MakeIdentity();
651 expected_surface_draw_transform.Translate(-10.0, -30.0); // scroll delta
652 expected_surface_draw_transform.Translate(8.0, 6.0);
653 expected_surface_draw_transform.PreconcatTransform(rotation_about_z);
655 // The rotation and its inverse are needed to place the scroll delta
656 // compensation in the correct space. This test will fail if the
657 // rotation/inverse are backwards, too, so it requires perfect order of
658 // operations.
659 expected_great_grand_child_transform.MakeIdentity();
660 expected_great_grand_child_transform.PreconcatTransform(
661 Inverse(rotation_about_z));
662 // explicit canceling out the scroll delta that gets embedded in the fixed
663 // position layer's surface.
664 expected_great_grand_child_transform.Translate(10.0, 30.0);
665 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
667 ASSERT_TRUE(grand_child->render_surface());
668 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
669 child->draw_transform());
670 EXPECT_TRANSFORMATION_MATRIX_EQ(
671 expected_surface_draw_transform,
672 grand_child->render_surface()->draw_transform());
673 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
674 grand_child->draw_transform());
675 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
676 great_grand_child->draw_transform());
678 // Case 3: fixed-container size delta of 20, 20
679 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
680 ExecuteCalculateDrawProperties(root_.get());
682 // Top-left fixed-position layer should not be affected by container size.
683 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
684 child->draw_transform());
685 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
686 grand_child->draw_transform());
687 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
688 great_grand_child->draw_transform());
690 // Case 4: Bottom-right fixed-position layer.
691 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
692 ExecuteCalculateDrawProperties(root_.get());
694 // Bottom-right fixed-position layer moves as container resizes.
695 expected_great_grand_child_transform.MakeIdentity();
696 // The rotation and its inverse are needed to place the scroll delta
697 // compensation in the correct space. This test will fail if the
698 // rotation/inverse are backwards, too, so it requires perfect order of
699 // operations.
700 expected_great_grand_child_transform.PreconcatTransform(
701 Inverse(rotation_about_z));
702 // explicit canceling out the scroll delta that gets embedded in the fixed
703 // position layer's surface.
704 expected_great_grand_child_transform.Translate(10.0, 30.0);
705 // Also apply size delta in the child(container) layer space.
706 expected_great_grand_child_transform.Translate(20.0, 20.0);
707 expected_great_grand_child_transform.PreconcatTransform(rotation_about_z);
709 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
710 child->draw_transform());
711 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
712 grand_child->draw_transform());
713 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
714 great_grand_child->draw_transform());
717 TEST_F(LayerPositionConstraintTest,
718 ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces) {
719 // This test checks for correct scroll compensation when the fixed-position
720 // container contributes to a different render surface than the fixed-position
721 // layer, with additional render surfaces in-between. This checks that the
722 // conversion to ancestor surfaces is accumulated properly in the final matrix
723 // transform.
724 LayerImpl* child = scroll_->children()[0];
725 LayerImpl* grand_child = child->children()[0];
726 LayerImpl* great_grand_child = grand_child->children()[0];
728 // Add one more layer to the test tree for this scenario.
730 gfx::Transform identity;
731 scoped_ptr<LayerImpl> fixed_position_child =
732 LayerImpl::Create(host_impl_.active_tree(), 5);
733 SetLayerPropertiesForTesting(fixed_position_child.get(),
734 identity,
735 gfx::Point3F(),
736 gfx::PointF(),
737 gfx::Size(100, 100),
738 true);
739 great_grand_child->AddChild(fixed_position_child.Pass());
741 LayerImpl* fixed_position_child = great_grand_child->children()[0];
743 // Actually set up the scenario here.
744 child->SetIsContainerForFixedPositionLayers(true);
745 grand_child->SetPosition(gfx::PointF(8.f, 6.f));
746 grand_child->SetHasRenderSurface(true);
747 great_grand_child->SetPosition(gfx::PointF(40.f, 60.f));
748 great_grand_child->SetHasRenderSurface(true);
749 fixed_position_child->SetPositionConstraint(fixed_to_top_left_);
750 fixed_position_child->SetDrawsContent(true);
752 // The additional rotations, which are non-commutative with translations, help
753 // to verify that we have correct order-of-operations in the final scroll
754 // compensation. Note that rotating about the center of the layer ensures we
755 // do not accidentally clip away layers that we want to test.
756 gfx::Transform rotation_about_z;
757 rotation_about_z.Translate(50.0, 50.0);
758 rotation_about_z.RotateAboutZAxis(90.0);
759 rotation_about_z.Translate(-50.0, -50.0);
760 grand_child->SetTransform(rotation_about_z);
761 great_grand_child->SetTransform(rotation_about_z);
763 // Case 1: scroll delta of 0, 0
764 child->SetScrollDelta(gfx::Vector2d(0, 0));
765 ExecuteCalculateDrawProperties(root_.get());
767 gfx::Transform expected_child_transform;
769 gfx::Transform expected_grand_child_surface_draw_transform;
770 expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
771 expected_grand_child_surface_draw_transform.PreconcatTransform(
772 rotation_about_z);
774 gfx::Transform expected_grand_child_transform;
776 gfx::Transform expected_great_grand_child_surface_draw_transform;
777 expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0);
778 expected_great_grand_child_surface_draw_transform.PreconcatTransform(
779 rotation_about_z);
781 gfx::Transform expected_great_grand_child_transform;
783 gfx::Transform expected_fixed_position_child_transform;
785 ASSERT_TRUE(grand_child->render_surface());
786 ASSERT_TRUE(great_grand_child->render_surface());
787 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
788 child->draw_transform());
789 EXPECT_TRANSFORMATION_MATRIX_EQ(
790 expected_grand_child_surface_draw_transform,
791 grand_child->render_surface()->draw_transform());
792 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
793 grand_child->draw_transform());
794 EXPECT_TRANSFORMATION_MATRIX_EQ(
795 expected_great_grand_child_surface_draw_transform,
796 great_grand_child->render_surface()->draw_transform());
797 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
798 great_grand_child->draw_transform());
799 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
800 fixed_position_child->draw_transform());
802 // Case 2: scroll delta of 10, 30
803 child->SetScrollDelta(gfx::Vector2d(10, 30));
804 ExecuteCalculateDrawProperties(root_.get());
806 expected_child_transform.MakeIdentity();
807 expected_child_transform.Translate(-10.0, -30.0); // scroll delta
809 expected_grand_child_surface_draw_transform.MakeIdentity();
810 expected_grand_child_surface_draw_transform.Translate(-10.0,
811 -30.0); // scroll delta
812 expected_grand_child_surface_draw_transform.Translate(8.0, 6.0);
813 expected_grand_child_surface_draw_transform.PreconcatTransform(
814 rotation_about_z);
816 // grand_child, great_grand_child, and great_grand_child's surface are not
817 // expected to change, since they are all not fixed, and they are all drawn
818 // with respect to grand_child's surface that already has the scroll delta
819 // accounted for.
821 // But the great-great grandchild, "fixed_position_child", should have a
822 // transform that explicitly cancels out the scroll delta. The expected
823 // transform is: compound_draw_transform.Inverse() * translate(positive scroll
824 // delta) * compound_origin_transform from great_grand_childSurface's origin
825 // to the root surface.
826 gfx::Transform compound_draw_transform;
827 compound_draw_transform.Translate(8.0,
828 6.0); // origin translation of grand_child
829 compound_draw_transform.PreconcatTransform(
830 rotation_about_z); // rotation of grand_child
831 compound_draw_transform.Translate(
832 40.0, 60.0); // origin translation of great_grand_child
833 compound_draw_transform.PreconcatTransform(
834 rotation_about_z); // rotation of great_grand_child
836 expected_fixed_position_child_transform.MakeIdentity();
837 expected_fixed_position_child_transform.PreconcatTransform(
838 Inverse(compound_draw_transform));
839 // explicit canceling out the scroll delta that gets embedded in the fixed
840 // position layer's surface.
841 expected_fixed_position_child_transform.Translate(10.0, 30.0);
842 expected_fixed_position_child_transform.PreconcatTransform(
843 compound_draw_transform);
845 ASSERT_TRUE(grand_child->render_surface());
846 ASSERT_TRUE(great_grand_child->render_surface());
847 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
848 child->draw_transform());
849 EXPECT_TRANSFORMATION_MATRIX_EQ(
850 expected_grand_child_surface_draw_transform,
851 grand_child->render_surface()->draw_transform());
852 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
853 grand_child->draw_transform());
854 EXPECT_TRANSFORMATION_MATRIX_EQ(
855 expected_great_grand_child_surface_draw_transform,
856 great_grand_child->render_surface()->draw_transform());
857 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
858 great_grand_child->draw_transform());
859 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
860 fixed_position_child->draw_transform());
863 // Case 3: fixed-container size delta of 20, 20
864 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
865 ExecuteCalculateDrawProperties(root_.get());
867 // Top-left fixed-position layer should not be affected by container size.
868 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
869 child->draw_transform());
870 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
871 grand_child->draw_transform());
872 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
873 great_grand_child->draw_transform());
874 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
875 fixed_position_child->draw_transform());
877 // Case 4: Bottom-right fixed-position layer.
878 fixed_position_child->SetPositionConstraint(fixed_to_bottom_right_);
879 ExecuteCalculateDrawProperties(root_.get());
881 // Bottom-right fixed-position layer moves as container resizes.
882 expected_fixed_position_child_transform.MakeIdentity();
883 expected_fixed_position_child_transform.PreconcatTransform(
884 Inverse(compound_draw_transform));
885 // explicit canceling out the scroll delta that gets embedded in the fixed
886 // position layer's surface.
887 expected_fixed_position_child_transform.Translate(10.0, 30.0);
888 // Also apply size delta in the child(container) layer space.
889 expected_fixed_position_child_transform.Translate(20.0, 20.0);
890 expected_fixed_position_child_transform.PreconcatTransform(
891 compound_draw_transform);
893 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
894 child->draw_transform());
895 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
896 grand_child->draw_transform());
897 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
898 great_grand_child->draw_transform());
899 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform,
900 fixed_position_child->draw_transform());
903 TEST_F(LayerPositionConstraintTest,
904 ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface) {
905 // This test checks for correct scroll compensation when the fixed-position
906 // container itself has a render surface. In this case, the container layer
907 // should be treated like a layer that contributes to a render target, and
908 // that render target is completely irrelevant; it should not affect the
909 // scroll compensation.
910 LayerImpl* child = scroll_->children()[0];
911 LayerImpl* grand_child = child->children()[0];
913 child->SetIsContainerForFixedPositionLayers(true);
914 child->SetHasRenderSurface(true);
915 grand_child->SetPositionConstraint(fixed_to_top_left_);
916 grand_child->SetDrawsContent(true);
918 // Case 1: scroll delta of 0, 0
919 child->SetScrollDelta(gfx::Vector2d(0, 0));
920 ExecuteCalculateDrawProperties(root_.get());
922 gfx::Transform expected_surface_draw_transform;
923 expected_surface_draw_transform.Translate(0.0, 0.0);
924 gfx::Transform expected_child_transform;
925 gfx::Transform expected_grand_child_transform;
926 ASSERT_TRUE(child->render_surface());
927 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
928 child->render_surface()->draw_transform());
929 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
930 child->draw_transform());
931 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
932 grand_child->draw_transform());
934 // Case 2: scroll delta of 10, 10
935 child->SetScrollDelta(gfx::Vector2d(10, 10));
936 ExecuteCalculateDrawProperties(root_.get());
938 // The surface is translated by scroll delta, the child transform doesn't
939 // change because it scrolls along with the surface, but the fixed position
940 // grand_child needs to compensate for the scroll translation.
941 expected_surface_draw_transform.MakeIdentity();
942 expected_surface_draw_transform.Translate(-10.0, -10.0);
943 expected_grand_child_transform.MakeIdentity();
944 expected_grand_child_transform.Translate(10.0, 10.0);
946 ASSERT_TRUE(child->render_surface());
947 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
948 child->render_surface()->draw_transform());
949 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
950 child->draw_transform());
951 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
952 grand_child->draw_transform());
954 // Case 3: fixed-container size delta of 20, 20
955 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
956 ExecuteCalculateDrawProperties(root_.get());
958 // Top-left fixed-position layer should not be affected by container size.
959 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
960 child->draw_transform());
961 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
962 grand_child->draw_transform());
964 // Case 4: Bottom-right fixed-position layer.
965 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
966 ExecuteCalculateDrawProperties(root_.get());
968 // Bottom-right fixed-position layer moves as container resizes.
969 expected_grand_child_transform.MakeIdentity();
970 // The surface is translated by scroll delta, the child transform doesn't
971 // change because it scrolls along with the surface, but the fixed position
972 // grand_child needs to compensate for the scroll translation.
973 expected_grand_child_transform.Translate(10.0, 10.0);
974 // Apply size delta from the child(container) layer.
975 expected_grand_child_transform.Translate(20.0, 20.0);
977 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
978 child->draw_transform());
979 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
980 grand_child->draw_transform());
983 TEST_F(LayerPositionConstraintTest,
984 ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer) {
985 // This test checks the scenario where a fixed-position layer also happens to
986 // be a container itself for a descendant fixed position layer. In particular,
987 // the layer should not accidentally be fixed to itself.
988 LayerImpl* child = scroll_->children()[0];
989 LayerImpl* grand_child = child->children()[0];
991 child->SetIsContainerForFixedPositionLayers(true);
992 grand_child->SetPositionConstraint(fixed_to_top_left_);
994 // This should not confuse the grand_child. If correct, the grand_child would
995 // still be considered fixed to its container (i.e. "child").
996 grand_child->SetIsContainerForFixedPositionLayers(true);
998 // Case 1: scroll delta of 0, 0
999 child->SetScrollDelta(gfx::Vector2d(0, 0));
1000 ExecuteCalculateDrawProperties(root_.get());
1002 gfx::Transform expected_child_transform;
1003 gfx::Transform expected_grand_child_transform;
1004 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1005 child->draw_transform());
1006 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1007 grand_child->draw_transform());
1009 // Case 2: scroll delta of 10, 10
1010 child->SetScrollDelta(gfx::Vector2d(10, 10));
1011 ExecuteCalculateDrawProperties(root_.get());
1013 // Here the child is affected by scroll delta, but the fixed position
1014 // grand_child should not be affected.
1015 expected_child_transform.MakeIdentity();
1016 expected_child_transform.Translate(-10.0, -10.0);
1017 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1018 child->draw_transform());
1019 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1020 grand_child->draw_transform());
1022 // Case 3: fixed-container size delta of 20, 20
1023 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
1024 ExecuteCalculateDrawProperties(root_.get());
1026 // Top-left fixed-position layer should not be affected by container size.
1027 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1028 child->draw_transform());
1029 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1030 grand_child->draw_transform());
1032 // Case 4: Bottom-right fixed-position layer.
1033 grand_child->SetPositionConstraint(fixed_to_bottom_right_);
1034 ExecuteCalculateDrawProperties(root_.get());
1036 // Bottom-right fixed-position layer moves as container resizes.
1037 expected_grand_child_transform.MakeIdentity();
1038 // Apply size delta from the child(container) layer.
1039 expected_grand_child_transform.Translate(20.0, 20.0);
1041 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1042 child->draw_transform());
1043 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1044 grand_child->draw_transform());
1047 TEST_F(LayerPositionConstraintTest,
1048 ScrollCompensationForFixedWithinFixedWithSameContainer) {
1049 // This test checks scroll compensation for a fixed-position layer that is
1050 // inside of another fixed-position layer and both share the same container.
1051 // In this situation, the parent fixed-position layer will receive
1052 // the scroll compensation, and the child fixed-position layer does not
1053 // need to compensate further.
1055 LayerImpl* child = scroll_->children()[0];
1056 LayerImpl* grand_child = child->children()[0];
1057 LayerImpl* great_grand_child = grand_child->children()[0];
1059 child->SetIsContainerForFixedPositionLayers(true);
1060 grand_child->SetPositionConstraint(fixed_to_top_left_);
1062 // Note carefully - great_grand_child is fixed to bottom right, to test
1063 // sizeDelta being applied correctly; the compensation skips the grand_child
1064 // because it is fixed to top left.
1065 great_grand_child->SetPositionConstraint(fixed_to_bottom_right_);
1067 // Case 1: scrollDelta
1068 child->SetScrollDelta(gfx::Vector2d(10, 10));
1069 ExecuteCalculateDrawProperties(root_.get());
1071 // Here the child is affected by scroll delta, but the fixed position
1072 // grand_child should not be affected.
1073 gfx::Transform expected_child_transform;
1074 expected_child_transform.Translate(-10.0, -10.0);
1076 gfx::Transform expected_grand_child_transform;
1077 gfx::Transform expected_great_grand_child_transform;
1079 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1080 child->draw_transform());
1081 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1082 grand_child->draw_transform());
1083 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
1084 great_grand_child->draw_transform());
1086 // Case 2: sizeDelta
1087 child->SetScrollDelta(gfx::Vector2d(0, 0));
1088 SetFixedContainerSizeDelta(child, gfx::Vector2d(20, 20));
1089 ExecuteCalculateDrawProperties(root_.get());
1091 expected_child_transform.MakeIdentity();
1093 expected_grand_child_transform.MakeIdentity();
1095 // Fixed to bottom-right, size-delta compensation is applied.
1096 expected_great_grand_child_transform.MakeIdentity();
1097 expected_great_grand_child_transform.Translate(20.0, 20.0);
1099 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
1100 child->draw_transform());
1101 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform,
1102 grand_child->draw_transform());
1103 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform,
1104 great_grand_child->draw_transform());
1107 TEST_F(LayerPositionConstraintTest,
1108 ScrollCompensationForFixedWithinFixedWithInterveningContainer) {
1109 // This test checks scroll compensation for a fixed-position layer that is
1110 // inside of another fixed-position layer, but they have different fixed
1111 // position containers. In this situation, the child fixed-position element
1112 // would still have to compensate with respect to its container.
1114 LayerImpl* container1 = scroll_->children()[0];
1115 LayerImpl* fixed_to_container1 = container1->children()[0];
1116 LayerImpl* container2 = fixed_to_container1->children()[0];
1119 // Add one more layer to the hierarchy for this test.
1120 scoped_ptr<LayerImpl> fixed_to_container2_ptr =
1121 LayerImpl::Create(host_impl_.active_tree(), 5);
1122 container2->AddChild(fixed_to_container2_ptr.Pass());
1125 LayerImpl* fixed_to_container2 = container2->children()[0];
1127 container1->SetIsContainerForFixedPositionLayers(true);
1128 fixed_to_container1->SetPositionConstraint(fixed_to_top_left_);
1129 container2->SetIsContainerForFixedPositionLayers(true);
1130 fixed_to_container2->SetPositionConstraint(fixed_to_top_left_);
1132 container1->SetScrollDelta(gfx::Vector2d(0, 15));
1133 container2->SetScrollDelta(gfx::Vector2d(30, 0));
1134 ExecuteCalculateDrawProperties(root_.get());
1136 gfx::Transform expected_container1_transform;
1137 expected_container1_transform.Translate(0.0, -15.0);
1139 gfx::Transform expected_fixed_to_container1_transform;
1141 // Since the container is a descendant of the fixed layer above,
1142 // the expected draw transform for container2 would not
1143 // include the scrollDelta that was applied to container1.
1144 gfx::Transform expected_container2_transform;
1145 expected_container2_transform.Translate(-30.0, 0.0);
1147 gfx::Transform expected_fixed_to_container2_transform;
1149 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform,
1150 container1->draw_transform());
1152 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform,
1153 fixed_to_container1->draw_transform());
1155 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform,
1156 container2->draw_transform());
1158 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform,
1159 fixed_to_container2->draw_transform());
1161 } // namespace
1162 } // namespace cc