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/test/test_shared_bitmap_manager.h"
14 #include "cc/trees/layer_tree_host_common.h"
15 #include "testing/gtest/include/gtest/gtest.h"
20 void SetLayerPropertiesForTesting(LayerImpl
* layer
,
21 const gfx::Transform
& transform
,
22 const gfx::PointF
& anchor
,
23 const gfx::PointF
& position
,
24 const gfx::Size
& bounds
,
25 bool flatten_transform
,
27 layer
->SetTransform(transform
);
28 layer
->SetAnchorPoint(anchor
);
29 layer
->SetPosition(position
);
30 layer
->SetBounds(bounds
);
31 layer
->SetShouldFlattenTransform(flatten_transform
);
32 layer
->SetIs3dSorted(is_3d_sorted
);
33 layer
->SetContentBounds(bounds
);
36 void ExecuteCalculateDrawProperties(LayerImpl
* root_layer
,
37 float device_scale_factor
,
38 float page_scale_factor
,
39 LayerImpl
* page_scale_application_layer
,
40 bool can_use_lcd_text
) {
41 gfx::Transform identity_matrix
;
42 std::vector
<LayerImpl
*> dummy_render_surface_layer_list
;
43 LayerImpl
* scroll_layer
= root_layer
->children()[0];
44 gfx::Size device_viewport_size
=
45 gfx::Size(root_layer
->bounds().width() * device_scale_factor
,
46 root_layer
->bounds().height() * device_scale_factor
);
48 // We are probably not testing what is intended if the scroll_layer bounds are
50 DCHECK(!scroll_layer
->bounds().IsEmpty());
51 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
52 root_layer
, device_viewport_size
, &dummy_render_surface_layer_list
);
53 inputs
.device_scale_factor
= device_scale_factor
;
54 inputs
.page_scale_factor
= page_scale_factor
;
55 inputs
.page_scale_application_layer
= page_scale_application_layer
;
56 inputs
.can_use_lcd_text
= can_use_lcd_text
;
57 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
60 void ExecuteCalculateDrawProperties(LayerImpl
* root_layer
) {
61 LayerImpl
* page_scale_application_layer
= NULL
;
62 ExecuteCalculateDrawProperties(
63 root_layer
, 1.f
, 1.f
, page_scale_application_layer
, false);
66 class LayerPositionConstraintTest
: public testing::Test
{
68 LayerPositionConstraintTest() : host_impl_(&proxy_
, &shared_bitmap_manager_
) {
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 TestSharedBitmapManager shared_bitmap_manager_
;
139 FakeLayerTreeHostImpl host_impl_
;
140 scoped_ptr
<LayerImpl
> root_
;
143 LayerPositionConstraint fixed_to_top_left_
;
144 LayerPositionConstraint fixed_to_bottom_right_
;
149 void SetFixedContainerSizeDelta(LayerImpl
* scroll_layer
,
150 const gfx::Vector2d
& delta
) {
151 DCHECK(scroll_layer
);
152 DCHECK(scroll_layer
->scrollable());
154 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
155 gfx::Size
container_size(container_layer
->bounds());
156 gfx::Size
new_container_size(container_size
.width() + delta
.x(),
157 container_size
.height() + delta
.y());
158 container_layer
->SetTemporaryImplBounds(new_container_size
);
162 TEST_F(LayerPositionConstraintTest
,
163 ScrollCompensationForFixedPositionLayerWithDirectContainer
) {
164 // This test checks for correct scroll compensation when the fixed-position
165 // container is the direct parent of the fixed-position layer.
166 LayerImpl
* child
= scroll_
->children()[0];
167 LayerImpl
* grand_child
= child
->children()[0];
169 child
->SetIsContainerForFixedPositionLayers(true);
170 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
172 // Case 1: scroll delta of 0, 0
173 child
->SetScrollDelta(gfx::Vector2d(0, 0));
174 ExecuteCalculateDrawProperties(root_
.get());
176 gfx::Transform expected_child_transform
;
177 gfx::Transform expected_grand_child_transform
= expected_child_transform
;
179 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
180 child
->draw_transform());
181 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
182 grand_child
->draw_transform());
184 // Case 2: scroll delta of 10, 10
185 child
->SetScrollDelta(gfx::Vector2d(10, 10));
186 ExecuteCalculateDrawProperties(root_
.get());
188 // Here the child is affected by scroll delta, but the fixed position
189 // grand_child should not be affected.
190 expected_child_transform
.MakeIdentity();
191 expected_child_transform
.Translate(-10.0, -10.0);
193 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
194 child
->draw_transform());
195 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
196 grand_child
->draw_transform());
198 // Case 3: fixed-container size delta of 20, 20
199 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
200 ExecuteCalculateDrawProperties(root_
.get());
202 // Top-left fixed-position layer should not be affected by container size.
203 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
204 child
->draw_transform());
205 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
206 grand_child
->draw_transform());
208 // Case 4: Bottom-right fixed-position layer.
209 grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
210 ExecuteCalculateDrawProperties(root_
.get());
212 // Bottom-right fixed-position layer moves as container resizes.
213 expected_grand_child_transform
.MakeIdentity();
214 // Apply size delta from the child(container) layer.
215 expected_grand_child_transform
.Translate(20.0, 20.0);
217 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
218 child
->draw_transform());
219 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
220 grand_child
->draw_transform());
223 TEST_F(LayerPositionConstraintTest
,
224 ScrollCompensationForFixedPositionLayerWithTransformedDirectContainer
) {
225 // This test checks for correct scroll compensation when the fixed-position
226 // container is the direct parent of the fixed-position layer, but that
227 // container is transformed. In this case, the fixed position element
228 // inherits the container's transform, but the scroll delta that has to be
229 // undone should not be affected by that transform.
231 // Transforms are in general non-commutative; using something like a
232 // non-uniform scale helps to verify that translations and non-uniform scales
233 // are applied in the correct order.
234 LayerImpl
* child
= scroll_
->children()[0];
235 LayerImpl
* grand_child
= child
->children()[0];
237 // This scale will cause child and grand_child to be effectively 200 x 800
238 // with respect to the render target.
239 gfx::Transform non_uniform_scale
;
240 non_uniform_scale
.Scale(2.0, 8.0);
241 child
->SetTransform(non_uniform_scale
);
243 child
->SetIsContainerForFixedPositionLayers(true);
244 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
246 // Case 1: scroll delta of 0, 0
247 child
->SetScrollDelta(gfx::Vector2d(0, 0));
248 ExecuteCalculateDrawProperties(root_
.get());
250 gfx::Transform expected_child_transform
;
251 expected_child_transform
.PreconcatTransform(non_uniform_scale
);
253 gfx::Transform expected_grand_child_transform
= expected_child_transform
;
255 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
256 child
->draw_transform());
257 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
258 grand_child
->draw_transform());
260 // Case 2: scroll delta of 10, 20
261 child
->SetScrollDelta(gfx::Vector2d(10, 20));
262 ExecuteCalculateDrawProperties(root_
.get());
264 // The child should be affected by scroll delta, but the fixed position
265 // grand_child should not be affected.
266 expected_child_transform
.MakeIdentity();
267 expected_child_transform
.Translate(-10.0, -20.0); // scroll delta
268 expected_child_transform
.PreconcatTransform(non_uniform_scale
);
270 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
271 child
->draw_transform());
272 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
273 grand_child
->draw_transform());
275 // Case 3: fixed-container size delta of 20, 20
276 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
277 ExecuteCalculateDrawProperties(root_
.get());
279 // Top-left fixed-position layer should not be affected by container size.
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());
285 // Case 4: Bottom-right fixed-position layer.
286 grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
287 ExecuteCalculateDrawProperties(root_
.get());
289 // Bottom-right fixed-position layer moves as container resizes.
290 expected_grand_child_transform
.MakeIdentity();
291 // Apply child layer transform.
292 expected_grand_child_transform
.PreconcatTransform(non_uniform_scale
);
293 // Apply size delta from the child(container) layer.
294 expected_grand_child_transform
.Translate(20.0, 20.0);
296 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
297 child
->draw_transform());
298 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
299 grand_child
->draw_transform());
302 TEST_F(LayerPositionConstraintTest
,
303 ScrollCompensationForFixedPositionLayerWithDistantContainer
) {
304 // This test checks for correct scroll compensation when the fixed-position
305 // container is NOT the direct parent of the fixed-position layer.
306 LayerImpl
* child
= scroll_
->children()[0];
307 LayerImpl
* grand_child
= child
->children()[0];
308 LayerImpl
* great_grand_child
= grand_child
->children()[0];
310 child
->SetIsContainerForFixedPositionLayers(true);
311 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
312 great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
314 // Case 1: scroll delta of 0, 0
315 child
->SetScrollDelta(gfx::Vector2d(0, 0));
316 ExecuteCalculateDrawProperties(root_
.get());
318 gfx::Transform expected_child_transform
;
319 gfx::Transform expected_grand_child_transform
;
320 expected_grand_child_transform
.Translate(8.0, 6.0);
322 gfx::Transform expected_great_grand_child_transform
=
323 expected_grand_child_transform
;
325 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
326 child
->draw_transform());
327 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
328 grand_child
->draw_transform());
329 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
330 great_grand_child
->draw_transform());
332 // Case 2: scroll delta of 10, 10
333 child
->SetScrollDelta(gfx::Vector2d(10, 10));
334 ExecuteCalculateDrawProperties(root_
.get());
336 // Here the child and grand_child are affected by scroll delta, but the fixed
337 // position great_grand_child should not be affected.
338 expected_child_transform
.MakeIdentity();
339 expected_child_transform
.Translate(-10.0, -10.0);
340 expected_grand_child_transform
.MakeIdentity();
341 expected_grand_child_transform
.Translate(-2.0, -4.0);
342 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
343 child
->draw_transform());
344 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
345 grand_child
->draw_transform());
346 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
347 great_grand_child
->draw_transform());
349 // Case 3: fixed-container size delta of 20, 20
350 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
351 ExecuteCalculateDrawProperties(root_
.get());
353 // Top-left fixed-position layer should not be affected by container size.
354 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
355 child
->draw_transform());
356 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
357 grand_child
->draw_transform());
358 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
359 great_grand_child
->draw_transform());
361 // Case 4: Bottom-right fixed-position layer.
362 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
363 ExecuteCalculateDrawProperties(root_
.get());
365 // Bottom-right fixed-position layer moves as container resizes.
366 expected_great_grand_child_transform
.MakeIdentity();
367 // Apply size delta from the child(container) layer.
368 expected_great_grand_child_transform
.Translate(20.0, 20.0);
369 // Apply layer position from the grand child layer.
370 expected_great_grand_child_transform
.Translate(8.0, 6.0);
372 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
373 child
->draw_transform());
374 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
375 grand_child
->draw_transform());
376 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
377 great_grand_child
->draw_transform());
380 TEST_F(LayerPositionConstraintTest
,
381 ScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms
) {
382 // This test checks for correct scroll compensation when the fixed-position
383 // container is NOT the direct parent of the fixed-position layer, and the
384 // hierarchy has various transforms that have to be processed in the correct
386 LayerImpl
* child
= scroll_
->children()[0];
387 LayerImpl
* grand_child
= child
->children()[0];
388 LayerImpl
* great_grand_child
= grand_child
->children()[0];
390 gfx::Transform rotation_about_z
;
391 rotation_about_z
.RotateAboutZAxis(90.0);
393 child
->SetIsContainerForFixedPositionLayers(true);
394 child
->SetTransform(rotation_about_z
);
395 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
396 grand_child
->SetTransform(rotation_about_z
);
397 // great_grand_child is positioned upside-down with respect to the render
399 great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
401 // Case 1: scroll delta of 0, 0
402 child
->SetScrollDelta(gfx::Vector2d(0, 0));
403 ExecuteCalculateDrawProperties(root_
.get());
405 gfx::Transform expected_child_transform
;
406 expected_child_transform
.PreconcatTransform(rotation_about_z
);
408 gfx::Transform expected_grand_child_transform
;
409 expected_grand_child_transform
.PreconcatTransform(
410 rotation_about_z
); // child's local transform is inherited
411 // translation because of position occurs before layer's local transform.
412 expected_grand_child_transform
.Translate(8.0, 6.0);
413 expected_grand_child_transform
.PreconcatTransform(
414 rotation_about_z
); // grand_child's local transform
416 gfx::Transform expected_great_grand_child_transform
=
417 expected_grand_child_transform
;
419 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
420 child
->draw_transform());
421 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
422 grand_child
->draw_transform());
423 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
424 great_grand_child
->draw_transform());
426 // Case 2: scroll delta of 10, 20
427 child
->SetScrollDelta(gfx::Vector2d(10, 20));
428 ExecuteCalculateDrawProperties(root_
.get());
430 // Here the child and grand_child are affected by scroll delta, but the fixed
431 // position great_grand_child should not be affected.
432 expected_child_transform
.MakeIdentity();
433 expected_child_transform
.Translate(-10.0, -20.0); // scroll delta
434 expected_child_transform
.PreconcatTransform(rotation_about_z
);
436 expected_grand_child_transform
.MakeIdentity();
437 expected_grand_child_transform
.Translate(
438 -10.0, -20.0); // child's scroll delta is inherited
439 expected_grand_child_transform
.PreconcatTransform(
440 rotation_about_z
); // child's local transform is inherited
441 // translation because of position occurs before layer's local transform.
442 expected_grand_child_transform
.Translate(8.0, 6.0);
443 expected_grand_child_transform
.PreconcatTransform(
444 rotation_about_z
); // grand_child's local transform
446 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
447 child
->draw_transform());
448 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
449 grand_child
->draw_transform());
450 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
451 great_grand_child
->draw_transform());
453 // Case 3: fixed-container size delta of 20, 20
454 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
455 ExecuteCalculateDrawProperties(root_
.get());
457 // Top-left fixed-position layer should not be affected by container size.
458 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
459 child
->draw_transform());
460 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
461 grand_child
->draw_transform());
462 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
463 great_grand_child
->draw_transform());
465 // Case 4: Bottom-right fixed-position layer.
466 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
467 ExecuteCalculateDrawProperties(root_
.get());
469 // Bottom-right fixed-position layer moves as container resizes.
470 expected_great_grand_child_transform
.MakeIdentity();
471 // Apply child layer transform.
472 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
473 // Apply size delta from the child(container) layer.
474 expected_great_grand_child_transform
.Translate(20.0, 20.0);
475 // Apply layer position from the grand child layer.
476 expected_great_grand_child_transform
.Translate(8.0, 6.0);
477 // Apply grand child layer transform.
478 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
480 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
481 child
->draw_transform());
482 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
483 grand_child
->draw_transform());
484 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
485 great_grand_child
->draw_transform());
488 TEST_F(LayerPositionConstraintTest
,
489 ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas
) {
490 // This test checks for correct scroll compensation when the fixed-position
491 // container has multiple ancestors that have nonzero scroll delta before
492 // reaching the space where the layer is fixed. In this test, each scroll
493 // delta occurs in a different space because of each layer's local transform.
494 // This test checks for correct scroll compensation when the fixed-position
495 // container is NOT the direct parent of the fixed-position layer, and the
496 // hierarchy has various transforms that have to be processed in the correct
498 LayerImpl
* child
= scroll_
->children()[0];
499 LayerImpl
* grand_child
= child
->children()[0];
500 LayerImpl
* great_grand_child
= grand_child
->children()[0];
502 gfx::Transform rotation_about_z
;
503 rotation_about_z
.RotateAboutZAxis(90.0);
505 child
->SetIsContainerForFixedPositionLayers(true);
506 child
->SetTransform(rotation_about_z
);
507 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
508 grand_child
->SetTransform(rotation_about_z
);
509 // great_grand_child is positioned upside-down with respect to the render
511 great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
513 // Case 1: scroll delta of 0, 0
514 child
->SetScrollDelta(gfx::Vector2d(0, 0));
515 ExecuteCalculateDrawProperties(root_
.get());
517 gfx::Transform expected_child_transform
;
518 expected_child_transform
.PreconcatTransform(rotation_about_z
);
520 gfx::Transform expected_grand_child_transform
;
521 expected_grand_child_transform
.PreconcatTransform(
522 rotation_about_z
); // child's local transform is inherited
523 // translation because of position occurs before layer's local transform.
524 expected_grand_child_transform
.Translate(8.0, 6.0);
525 expected_grand_child_transform
.PreconcatTransform(
526 rotation_about_z
); // grand_child's local transform
528 gfx::Transform expected_great_grand_child_transform
=
529 expected_grand_child_transform
;
531 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
532 child
->draw_transform());
533 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
534 grand_child
->draw_transform());
535 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
536 great_grand_child
->draw_transform());
538 // Case 2: scroll delta of 10, 20
539 child
->SetScrollDelta(gfx::Vector2d(10, 0));
540 grand_child
->SetScrollDelta(gfx::Vector2d(5, 0));
541 ExecuteCalculateDrawProperties(root_
.get());
543 // Here the child and grand_child are affected by scroll delta, but the fixed
544 // position great_grand_child should not be affected.
545 expected_child_transform
.MakeIdentity();
546 expected_child_transform
.Translate(-10.0, 0.0); // scroll delta
547 expected_child_transform
.PreconcatTransform(rotation_about_z
);
549 expected_grand_child_transform
.MakeIdentity();
550 expected_grand_child_transform
.Translate(
551 -10.0, 0.0); // child's scroll delta is inherited
552 expected_grand_child_transform
.PreconcatTransform(
553 rotation_about_z
); // child's local transform is inherited
554 expected_grand_child_transform
.Translate(-5.0,
555 0.0); // grand_child's scroll delta
556 // translation because of position occurs before layer's local transform.
557 expected_grand_child_transform
.Translate(8.0, 6.0);
558 expected_grand_child_transform
.PreconcatTransform(
559 rotation_about_z
); // grand_child's local transform
561 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
562 child
->draw_transform());
563 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
564 grand_child
->draw_transform());
565 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
566 great_grand_child
->draw_transform());
568 // Case 3: fixed-container size delta of 20, 20
569 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
570 ExecuteCalculateDrawProperties(root_
.get());
572 // Top-left fixed-position layer should not be affected by container size.
573 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
574 child
->draw_transform());
575 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
576 grand_child
->draw_transform());
577 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
578 great_grand_child
->draw_transform());
580 // Case 4: Bottom-right fixed-position layer.
581 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
582 ExecuteCalculateDrawProperties(root_
.get());
584 // Bottom-right fixed-position layer moves as container resizes.
585 expected_great_grand_child_transform
.MakeIdentity();
586 // Apply child layer transform.
587 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
588 // Apply size delta from the child(container) layer.
589 expected_great_grand_child_transform
.Translate(20.0, 20.0);
590 // Apply layer position from the grand child layer.
591 expected_great_grand_child_transform
.Translate(8.0, 6.0);
592 // Apply grand child layer transform.
593 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
595 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
596 child
->draw_transform());
597 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
598 grand_child
->draw_transform());
599 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
600 great_grand_child
->draw_transform());
603 TEST_F(LayerPositionConstraintTest
,
604 ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms
) {
605 // This test checks for correct scroll compensation when the fixed-position
606 // container contributes to a different render surface than the fixed-position
607 // layer. In this case, the surface draw transforms also have to be accounted
608 // for when checking the scroll delta.
609 LayerImpl
* child
= scroll_
->children()[0];
610 LayerImpl
* grand_child
= child
->children()[0];
611 LayerImpl
* great_grand_child
= grand_child
->children()[0];
613 child
->SetIsContainerForFixedPositionLayers(true);
614 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
615 grand_child
->SetForceRenderSurface(true);
616 great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
617 great_grand_child
->SetDrawsContent(true);
619 gfx::Transform rotation_about_z
;
620 rotation_about_z
.RotateAboutZAxis(90.0);
621 grand_child
->SetTransform(rotation_about_z
);
623 // Case 1: scroll delta of 0, 0
624 child
->SetScrollDelta(gfx::Vector2d(0, 0));
625 ExecuteCalculateDrawProperties(root_
.get());
627 gfx::Transform expected_child_transform
;
628 gfx::Transform expected_surface_draw_transform
;
629 expected_surface_draw_transform
.Translate(8.0, 6.0);
630 expected_surface_draw_transform
.PreconcatTransform(rotation_about_z
);
631 gfx::Transform expected_grand_child_transform
;
632 gfx::Transform expected_great_grand_child_transform
;
633 ASSERT_TRUE(grand_child
->render_surface());
634 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
635 child
->draw_transform());
636 EXPECT_TRANSFORMATION_MATRIX_EQ(
637 expected_surface_draw_transform
,
638 grand_child
->render_surface()->draw_transform());
639 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
640 grand_child
->draw_transform());
641 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
642 great_grand_child
->draw_transform());
644 // Case 2: scroll delta of 10, 30
645 child
->SetScrollDelta(gfx::Vector2d(10, 30));
646 ExecuteCalculateDrawProperties(root_
.get());
648 // Here the grand_child remains unchanged, because it scrolls along with the
649 // render surface, and the translation is actually in the render surface. But,
650 // the fixed position great_grand_child is more awkward: its actually being
651 // drawn with respect to the render surface, but it needs to remain fixed with
652 // resepct to a container beyond that surface. So, the net result is that,
653 // unlike previous tests where the fixed position layer's transform remains
654 // unchanged, here the fixed position layer's transform explicitly contains
655 // the translation that cancels out the scroll.
656 expected_child_transform
.MakeIdentity();
657 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
659 expected_surface_draw_transform
.MakeIdentity();
660 expected_surface_draw_transform
.Translate(-10.0, -30.0); // scroll delta
661 expected_surface_draw_transform
.Translate(8.0, 6.0);
662 expected_surface_draw_transform
.PreconcatTransform(rotation_about_z
);
664 // The rotation and its inverse are needed to place the scroll delta
665 // compensation in the correct space. This test will fail if the
666 // rotation/inverse are backwards, too, so it requires perfect order of
668 expected_great_grand_child_transform
.MakeIdentity();
669 expected_great_grand_child_transform
.PreconcatTransform(
670 Inverse(rotation_about_z
));
671 // explicit canceling out the scroll delta that gets embedded in the fixed
672 // position layer's surface.
673 expected_great_grand_child_transform
.Translate(10.0, 30.0);
674 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
676 ASSERT_TRUE(grand_child
->render_surface());
677 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
678 child
->draw_transform());
679 EXPECT_TRANSFORMATION_MATRIX_EQ(
680 expected_surface_draw_transform
,
681 grand_child
->render_surface()->draw_transform());
682 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
683 grand_child
->draw_transform());
684 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
685 great_grand_child
->draw_transform());
687 // Case 3: fixed-container size delta of 20, 20
688 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
689 ExecuteCalculateDrawProperties(root_
.get());
691 // Top-left fixed-position layer should not be affected by container size.
692 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
693 child
->draw_transform());
694 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
695 grand_child
->draw_transform());
696 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
697 great_grand_child
->draw_transform());
699 // Case 4: Bottom-right fixed-position layer.
700 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
701 ExecuteCalculateDrawProperties(root_
.get());
703 // Bottom-right fixed-position layer moves as container resizes.
704 expected_great_grand_child_transform
.MakeIdentity();
705 // The rotation and its inverse are needed to place the scroll delta
706 // compensation in the correct space. This test will fail if the
707 // rotation/inverse are backwards, too, so it requires perfect order of
709 expected_great_grand_child_transform
.PreconcatTransform(
710 Inverse(rotation_about_z
));
711 // explicit canceling out the scroll delta that gets embedded in the fixed
712 // position layer's surface.
713 expected_great_grand_child_transform
.Translate(10.0, 30.0);
714 // Also apply size delta in the child(container) layer space.
715 expected_great_grand_child_transform
.Translate(20.0, 20.0);
716 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
718 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
719 child
->draw_transform());
720 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
721 grand_child
->draw_transform());
722 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
723 great_grand_child
->draw_transform());
726 TEST_F(LayerPositionConstraintTest
,
727 ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces
) {
728 // This test checks for correct scroll compensation when the fixed-position
729 // container contributes to a different render surface than the fixed-position
730 // layer, with additional render surfaces in-between. This checks that the
731 // conversion to ancestor surfaces is accumulated properly in the final matrix
733 LayerImpl
* child
= scroll_
->children()[0];
734 LayerImpl
* grand_child
= child
->children()[0];
735 LayerImpl
* great_grand_child
= grand_child
->children()[0];
737 // Add one more layer to the test tree for this scenario.
739 gfx::Transform identity
;
740 scoped_ptr
<LayerImpl
> fixed_position_child
=
741 LayerImpl::Create(host_impl_
.active_tree(), 5);
742 SetLayerPropertiesForTesting(fixed_position_child
.get(),
749 great_grand_child
->AddChild(fixed_position_child
.Pass());
751 LayerImpl
* fixed_position_child
= great_grand_child
->children()[0];
753 // Actually set up the scenario here.
754 child
->SetIsContainerForFixedPositionLayers(true);
755 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
756 grand_child
->SetForceRenderSurface(true);
757 great_grand_child
->SetPosition(gfx::PointF(40.f
, 60.f
));
758 great_grand_child
->SetForceRenderSurface(true);
759 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
760 fixed_position_child
->SetDrawsContent(true);
762 // The additional rotations, which are non-commutative with translations, help
763 // to verify that we have correct order-of-operations in the final scroll
764 // compensation. Note that rotating about the center of the layer ensures we
765 // do not accidentally clip away layers that we want to test.
766 gfx::Transform rotation_about_z
;
767 rotation_about_z
.Translate(50.0, 50.0);
768 rotation_about_z
.RotateAboutZAxis(90.0);
769 rotation_about_z
.Translate(-50.0, -50.0);
770 grand_child
->SetTransform(rotation_about_z
);
771 great_grand_child
->SetTransform(rotation_about_z
);
773 // Case 1: scroll delta of 0, 0
774 child
->SetScrollDelta(gfx::Vector2d(0, 0));
775 ExecuteCalculateDrawProperties(root_
.get());
777 gfx::Transform expected_child_transform
;
779 gfx::Transform expected_grand_child_surface_draw_transform
;
780 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
781 expected_grand_child_surface_draw_transform
.PreconcatTransform(
784 gfx::Transform expected_grand_child_transform
;
786 gfx::Transform expected_great_grand_child_surface_draw_transform
;
787 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
788 expected_great_grand_child_surface_draw_transform
.PreconcatTransform(
791 gfx::Transform expected_great_grand_child_transform
;
793 gfx::Transform expected_fixed_position_child_transform
;
795 ASSERT_TRUE(grand_child
->render_surface());
796 ASSERT_TRUE(great_grand_child
->render_surface());
797 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
798 child
->draw_transform());
799 EXPECT_TRANSFORMATION_MATRIX_EQ(
800 expected_grand_child_surface_draw_transform
,
801 grand_child
->render_surface()->draw_transform());
802 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
803 grand_child
->draw_transform());
804 EXPECT_TRANSFORMATION_MATRIX_EQ(
805 expected_great_grand_child_surface_draw_transform
,
806 great_grand_child
->render_surface()->draw_transform());
807 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
808 great_grand_child
->draw_transform());
809 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
810 fixed_position_child
->draw_transform());
812 // Case 2: scroll delta of 10, 30
813 child
->SetScrollDelta(gfx::Vector2d(10, 30));
814 ExecuteCalculateDrawProperties(root_
.get());
816 expected_child_transform
.MakeIdentity();
817 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
819 expected_grand_child_surface_draw_transform
.MakeIdentity();
820 expected_grand_child_surface_draw_transform
.Translate(-10.0,
821 -30.0); // scroll delta
822 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
823 expected_grand_child_surface_draw_transform
.PreconcatTransform(
826 // grand_child, great_grand_child, and great_grand_child's surface are not
827 // expected to change, since they are all not fixed, and they are all drawn
828 // with respect to grand_child's surface that already has the scroll delta
831 // But the great-great grandchild, "fixed_position_child", should have a
832 // transform that explicitly cancels out the scroll delta. The expected
833 // transform is: compound_draw_transform.Inverse() * translate(positive scroll
834 // delta) * compound_origin_transform from great_grand_childSurface's origin
835 // to the root surface.
836 gfx::Transform compound_draw_transform
;
837 compound_draw_transform
.Translate(8.0,
838 6.0); // origin translation of grand_child
839 compound_draw_transform
.PreconcatTransform(
840 rotation_about_z
); // rotation of grand_child
841 compound_draw_transform
.Translate(
842 40.0, 60.0); // origin translation of great_grand_child
843 compound_draw_transform
.PreconcatTransform(
844 rotation_about_z
); // rotation of great_grand_child
846 expected_fixed_position_child_transform
.MakeIdentity();
847 expected_fixed_position_child_transform
.PreconcatTransform(
848 Inverse(compound_draw_transform
));
849 // explicit canceling out the scroll delta that gets embedded in the fixed
850 // position layer's surface.
851 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
852 expected_fixed_position_child_transform
.PreconcatTransform(
853 compound_draw_transform
);
855 ASSERT_TRUE(grand_child
->render_surface());
856 ASSERT_TRUE(great_grand_child
->render_surface());
857 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
858 child
->draw_transform());
859 EXPECT_TRANSFORMATION_MATRIX_EQ(
860 expected_grand_child_surface_draw_transform
,
861 grand_child
->render_surface()->draw_transform());
862 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
863 grand_child
->draw_transform());
864 EXPECT_TRANSFORMATION_MATRIX_EQ(
865 expected_great_grand_child_surface_draw_transform
,
866 great_grand_child
->render_surface()->draw_transform());
867 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
868 great_grand_child
->draw_transform());
869 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
870 fixed_position_child
->draw_transform());
873 // Case 3: fixed-container size delta of 20, 20
874 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
875 ExecuteCalculateDrawProperties(root_
.get());
877 // Top-left fixed-position layer should not be affected by container size.
878 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
879 child
->draw_transform());
880 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
881 grand_child
->draw_transform());
882 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
883 great_grand_child
->draw_transform());
884 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
885 fixed_position_child
->draw_transform());
887 // Case 4: Bottom-right fixed-position layer.
888 fixed_position_child
->SetPositionConstraint(fixed_to_bottom_right_
);
889 ExecuteCalculateDrawProperties(root_
.get());
891 // Bottom-right fixed-position layer moves as container resizes.
892 expected_fixed_position_child_transform
.MakeIdentity();
893 expected_fixed_position_child_transform
.PreconcatTransform(
894 Inverse(compound_draw_transform
));
895 // explicit canceling out the scroll delta that gets embedded in the fixed
896 // position layer's surface.
897 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
898 // Also apply size delta in the child(container) layer space.
899 expected_fixed_position_child_transform
.Translate(20.0, 20.0);
900 expected_fixed_position_child_transform
.PreconcatTransform(
901 compound_draw_transform
);
903 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
904 child
->draw_transform());
905 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
906 grand_child
->draw_transform());
907 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
908 great_grand_child
->draw_transform());
909 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
910 fixed_position_child
->draw_transform());
913 TEST_F(LayerPositionConstraintTest
,
914 ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface
) {
915 // This test checks for correct scroll compensation when the fixed-position
916 // container itself has a render surface. In this case, the container layer
917 // should be treated like a layer that contributes to a render target, and
918 // that render target is completely irrelevant; it should not affect the
919 // scroll compensation.
920 LayerImpl
* child
= scroll_
->children()[0];
921 LayerImpl
* grand_child
= child
->children()[0];
923 child
->SetIsContainerForFixedPositionLayers(true);
924 child
->SetForceRenderSurface(true);
925 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
926 grand_child
->SetDrawsContent(true);
928 // Case 1: scroll delta of 0, 0
929 child
->SetScrollDelta(gfx::Vector2d(0, 0));
930 ExecuteCalculateDrawProperties(root_
.get());
932 gfx::Transform expected_surface_draw_transform
;
933 expected_surface_draw_transform
.Translate(0.0, 0.0);
934 gfx::Transform expected_child_transform
;
935 gfx::Transform expected_grand_child_transform
;
936 ASSERT_TRUE(child
->render_surface());
937 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform
,
938 child
->render_surface()->draw_transform());
939 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
940 child
->draw_transform());
941 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
942 grand_child
->draw_transform());
944 // Case 2: scroll delta of 10, 10
945 child
->SetScrollDelta(gfx::Vector2d(10, 10));
946 ExecuteCalculateDrawProperties(root_
.get());
948 // The surface is translated by scroll delta, the child transform doesn't
949 // change because it scrolls along with the surface, but the fixed position
950 // grand_child needs to compensate for the scroll translation.
951 expected_surface_draw_transform
.MakeIdentity();
952 expected_surface_draw_transform
.Translate(-10.0, -10.0);
953 expected_grand_child_transform
.MakeIdentity();
954 expected_grand_child_transform
.Translate(10.0, 10.0);
956 ASSERT_TRUE(child
->render_surface());
957 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform
,
958 child
->render_surface()->draw_transform());
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 3: fixed-container size delta of 20, 20
965 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
966 ExecuteCalculateDrawProperties(root_
.get());
968 // Top-left fixed-position layer should not be affected by container size.
969 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
970 child
->draw_transform());
971 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
972 grand_child
->draw_transform());
974 // Case 4: Bottom-right fixed-position layer.
975 grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
976 ExecuteCalculateDrawProperties(root_
.get());
978 // Bottom-right fixed-position layer moves as container resizes.
979 expected_grand_child_transform
.MakeIdentity();
980 // The surface is translated by scroll delta, the child transform doesn't
981 // change because it scrolls along with the surface, but the fixed position
982 // grand_child needs to compensate for the scroll translation.
983 expected_grand_child_transform
.Translate(10.0, 10.0);
984 // Apply size delta from the child(container) layer.
985 expected_grand_child_transform
.Translate(20.0, 20.0);
987 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
988 child
->draw_transform());
989 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
990 grand_child
->draw_transform());
993 TEST_F(LayerPositionConstraintTest
,
994 ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer
) {
995 // This test checks the scenario where a fixed-position layer also happens to
996 // be a container itself for a descendant fixed position layer. In particular,
997 // the layer should not accidentally be fixed to itself.
998 LayerImpl
* child
= scroll_
->children()[0];
999 LayerImpl
* grand_child
= child
->children()[0];
1001 child
->SetIsContainerForFixedPositionLayers(true);
1002 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
1004 // This should not confuse the grand_child. If correct, the grand_child would
1005 // still be considered fixed to its container (i.e. "child").
1006 grand_child
->SetIsContainerForFixedPositionLayers(true);
1008 // Case 1: scroll delta of 0, 0
1009 child
->SetScrollDelta(gfx::Vector2d(0, 0));
1010 ExecuteCalculateDrawProperties(root_
.get());
1012 gfx::Transform expected_child_transform
;
1013 gfx::Transform expected_grand_child_transform
;
1014 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1015 child
->draw_transform());
1016 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1017 grand_child
->draw_transform());
1019 // Case 2: scroll delta of 10, 10
1020 child
->SetScrollDelta(gfx::Vector2d(10, 10));
1021 ExecuteCalculateDrawProperties(root_
.get());
1023 // Here the child is affected by scroll delta, but the fixed position
1024 // grand_child should not be affected.
1025 expected_child_transform
.MakeIdentity();
1026 expected_child_transform
.Translate(-10.0, -10.0);
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 3: fixed-container size delta of 20, 20
1033 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
1034 ExecuteCalculateDrawProperties(root_
.get());
1036 // Top-left fixed-position layer should not be affected by container size.
1037 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1038 child
->draw_transform());
1039 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1040 grand_child
->draw_transform());
1042 // Case 4: Bottom-right fixed-position layer.
1043 grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
1044 ExecuteCalculateDrawProperties(root_
.get());
1046 // Bottom-right fixed-position layer moves as container resizes.
1047 expected_grand_child_transform
.MakeIdentity();
1048 // Apply size delta from the child(container) layer.
1049 expected_grand_child_transform
.Translate(20.0, 20.0);
1051 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1052 child
->draw_transform());
1053 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1054 grand_child
->draw_transform());
1057 TEST_F(LayerPositionConstraintTest
,
1058 ScrollCompensationForFixedWithinFixedWithSameContainer
) {
1059 // This test checks scroll compensation for a fixed-position layer that is
1060 // inside of another fixed-position layer and both share the same container.
1061 // In this situation, the parent fixed-position layer will receive
1062 // the scroll compensation, and the child fixed-position layer does not
1063 // need to compensate further.
1065 LayerImpl
* child
= scroll_
->children()[0];
1066 LayerImpl
* grand_child
= child
->children()[0];
1067 LayerImpl
* great_grand_child
= grand_child
->children()[0];
1069 child
->SetIsContainerForFixedPositionLayers(true);
1070 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
1072 // Note carefully - great_grand_child is fixed to bottom right, to test
1073 // sizeDelta being applied correctly; the compensation skips the grand_child
1074 // because it is fixed to top left.
1075 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
1077 // Case 1: scrollDelta
1078 child
->SetScrollDelta(gfx::Vector2d(10, 10));
1079 ExecuteCalculateDrawProperties(root_
.get());
1081 // Here the child is affected by scroll delta, but the fixed position
1082 // grand_child should not be affected.
1083 gfx::Transform expected_child_transform
;
1084 expected_child_transform
.Translate(-10.0, -10.0);
1086 gfx::Transform expected_grand_child_transform
;
1087 gfx::Transform expected_great_grand_child_transform
;
1089 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1090 child
->draw_transform());
1091 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1092 grand_child
->draw_transform());
1093 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
1094 great_grand_child
->draw_transform());
1096 // Case 2: sizeDelta
1097 child
->SetScrollDelta(gfx::Vector2d(0, 0));
1098 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
1099 ExecuteCalculateDrawProperties(root_
.get());
1101 expected_child_transform
.MakeIdentity();
1103 expected_grand_child_transform
.MakeIdentity();
1105 // Fixed to bottom-right, size-delta compensation is applied.
1106 expected_great_grand_child_transform
.MakeIdentity();
1107 expected_great_grand_child_transform
.Translate(20.0, 20.0);
1109 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1110 child
->draw_transform());
1111 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1112 grand_child
->draw_transform());
1113 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
1114 great_grand_child
->draw_transform());
1117 TEST_F(LayerPositionConstraintTest
,
1118 ScrollCompensationForFixedWithinFixedWithInterveningContainer
) {
1119 // This test checks scroll compensation for a fixed-position layer that is
1120 // inside of another fixed-position layer, but they have different fixed
1121 // position containers. In this situation, the child fixed-position element
1122 // would still have to compensate with respect to its container.
1124 LayerImpl
* container1
= scroll_
->children()[0];
1125 LayerImpl
* fixed_to_container1
= container1
->children()[0];
1126 LayerImpl
* container2
= fixed_to_container1
->children()[0];
1129 // Add one more layer to the hierarchy for this test.
1130 scoped_ptr
<LayerImpl
> fixed_to_container2_ptr
=
1131 LayerImpl::Create(host_impl_
.active_tree(), 5);
1132 container2
->AddChild(fixed_to_container2_ptr
.Pass());
1135 LayerImpl
* fixed_to_container2
= container2
->children()[0];
1137 container1
->SetIsContainerForFixedPositionLayers(true);
1138 fixed_to_container1
->SetPositionConstraint(fixed_to_top_left_
);
1139 container2
->SetIsContainerForFixedPositionLayers(true);
1140 fixed_to_container2
->SetPositionConstraint(fixed_to_top_left_
);
1142 container1
->SetScrollDelta(gfx::Vector2d(0, 15));
1143 container2
->SetScrollDelta(gfx::Vector2d(30, 0));
1144 ExecuteCalculateDrawProperties(root_
.get());
1146 gfx::Transform expected_container1_transform
;
1147 expected_container1_transform
.Translate(0.0, -15.0);
1149 gfx::Transform expected_fixed_to_container1_transform
;
1151 // Since the container is a descendant of the fixed layer above,
1152 // the expected draw transform for container2 would not
1153 // include the scrollDelta that was applied to container1.
1154 gfx::Transform expected_container2_transform
;
1155 expected_container2_transform
.Translate(-30.0, 0.0);
1157 gfx::Transform expected_fixed_to_container2_transform
;
1159 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform
,
1160 container1
->draw_transform());
1162 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform
,
1163 fixed_to_container1
->draw_transform());
1165 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform
,
1166 container2
->draw_transform());
1168 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform
,
1169 fixed_to_container2
->draw_transform());