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