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