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::Point3F
& transform_origin
,
23 const gfx::PointF
& position
,
24 const gfx::Size
& bounds
,
25 bool flatten_transform
) {
26 layer
->SetTransform(transform
);
27 layer
->SetTransformOrigin(transform_origin
);
28 layer
->SetPosition(position
);
29 layer
->SetBounds(bounds
);
30 layer
->SetShouldFlattenTransform(flatten_transform
);
31 layer
->SetContentBounds(bounds
);
34 void ExecuteCalculateDrawProperties(LayerImpl
* root_layer
,
35 float device_scale_factor
,
36 float page_scale_factor
,
37 LayerImpl
* page_scale_application_layer
,
38 bool can_use_lcd_text
) {
39 gfx::Transform identity_matrix
;
40 std::vector
<LayerImpl
*> dummy_render_surface_layer_list
;
41 LayerImpl
* scroll_layer
= root_layer
->children()[0];
42 gfx::Size device_viewport_size
=
43 gfx::Size(root_layer
->bounds().width() * device_scale_factor
,
44 root_layer
->bounds().height() * device_scale_factor
);
46 // We are probably not testing what is intended if the scroll_layer bounds are
48 DCHECK(!scroll_layer
->bounds().IsEmpty());
49 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
50 root_layer
, device_viewport_size
, &dummy_render_surface_layer_list
);
51 inputs
.device_scale_factor
= device_scale_factor
;
52 inputs
.page_scale_factor
= page_scale_factor
;
53 inputs
.page_scale_application_layer
= page_scale_application_layer
;
54 inputs
.can_use_lcd_text
= can_use_lcd_text
;
55 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
58 void ExecuteCalculateDrawProperties(LayerImpl
* root_layer
) {
59 LayerImpl
* page_scale_application_layer
= NULL
;
60 ExecuteCalculateDrawProperties(
61 root_layer
, 1.f
, 1.f
, page_scale_application_layer
, false);
64 class LayerPositionConstraintTest
: public testing::Test
{
66 LayerPositionConstraintTest() : host_impl_(&proxy_
, &shared_bitmap_manager_
) {
67 root_
= CreateTreeForTest();
68 scroll_
= root_
->children()[0];
69 fixed_to_top_left_
.set_is_fixed_position(true);
70 fixed_to_bottom_right_
.set_is_fixed_position(true);
71 fixed_to_bottom_right_
.set_is_fixed_to_right_edge(true);
72 fixed_to_bottom_right_
.set_is_fixed_to_bottom_edge(true);
75 scoped_ptr
<LayerImpl
> CreateTreeForTest() {
76 scoped_ptr
<LayerImpl
> root
=
77 LayerImpl::Create(host_impl_
.active_tree(), 42);
78 scoped_ptr
<LayerImpl
> scroll_layer
=
79 LayerImpl::Create(host_impl_
.active_tree(), 1);
80 scoped_ptr
<LayerImpl
> child
=
81 LayerImpl::Create(host_impl_
.active_tree(), 2);
82 scoped_ptr
<LayerImpl
> grand_child
=
83 LayerImpl::Create(host_impl_
.active_tree(), 3);
84 scoped_ptr
<LayerImpl
> great_grand_child
=
85 LayerImpl::Create(host_impl_
.active_tree(), 4);
87 gfx::Transform IdentityMatrix
;
88 gfx::Point3F transform_origin
;
90 gfx::Size
bounds(200, 200);
91 gfx::Size
clip_bounds(100, 100);
92 SetLayerPropertiesForTesting(scroll_layer
.get(),
98 SetLayerPropertiesForTesting(
99 child
.get(), IdentityMatrix
, transform_origin
, position
, bounds
, true);
100 SetLayerPropertiesForTesting(grand_child
.get(),
106 SetLayerPropertiesForTesting(great_grand_child
.get(),
113 root
->SetBounds(clip_bounds
);
114 scroll_layer
->SetScrollClipLayer(root
->id());
115 child
->SetScrollClipLayer(root
->id());
116 grand_child
->SetScrollClipLayer(root
->id());
118 grand_child
->AddChild(great_grand_child
.Pass());
119 child
->AddChild(grand_child
.Pass());
120 scroll_layer
->AddChild(child
.Pass());
121 root
->AddChild(scroll_layer
.Pass());
127 FakeImplProxy proxy_
;
128 TestSharedBitmapManager shared_bitmap_manager_
;
129 FakeLayerTreeHostImpl host_impl_
;
130 scoped_ptr
<LayerImpl
> root_
;
133 LayerPositionConstraint fixed_to_top_left_
;
134 LayerPositionConstraint fixed_to_bottom_right_
;
139 void SetFixedContainerSizeDelta(LayerImpl
* scroll_layer
,
140 const gfx::Vector2d
& delta
) {
141 DCHECK(scroll_layer
);
142 DCHECK(scroll_layer
->scrollable());
144 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
145 gfx::Size
container_size(container_layer
->bounds());
146 gfx::Size
new_container_size(container_size
.width() + delta
.x(),
147 container_size
.height() + delta
.y());
148 container_layer
->SetTemporaryImplBounds(new_container_size
);
152 TEST_F(LayerPositionConstraintTest
,
153 ScrollCompensationForFixedPositionLayerWithDirectContainer
) {
154 // This test checks for correct scroll compensation when the fixed-position
155 // container is the direct parent of the fixed-position layer.
156 LayerImpl
* child
= scroll_
->children()[0];
157 LayerImpl
* grand_child
= child
->children()[0];
159 child
->SetIsContainerForFixedPositionLayers(true);
160 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
162 // Case 1: scroll delta of 0, 0
163 child
->SetScrollDelta(gfx::Vector2d(0, 0));
164 ExecuteCalculateDrawProperties(root_
.get());
166 gfx::Transform expected_child_transform
;
167 gfx::Transform expected_grand_child_transform
= expected_child_transform
;
169 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
170 child
->draw_transform());
171 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
172 grand_child
->draw_transform());
174 // Case 2: scroll delta of 10, 10
175 child
->SetScrollDelta(gfx::Vector2d(10, 10));
176 ExecuteCalculateDrawProperties(root_
.get());
178 // Here the child is affected by scroll delta, but the fixed position
179 // grand_child should not be affected.
180 expected_child_transform
.MakeIdentity();
181 expected_child_transform
.Translate(-10.0, -10.0);
183 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
184 child
->draw_transform());
185 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
186 grand_child
->draw_transform());
188 // Case 3: fixed-container size delta of 20, 20
189 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
190 ExecuteCalculateDrawProperties(root_
.get());
192 // Top-left fixed-position layer should not be affected by container size.
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 4: Bottom-right fixed-position layer.
199 grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
200 ExecuteCalculateDrawProperties(root_
.get());
202 // Bottom-right fixed-position layer moves as container resizes.
203 expected_grand_child_transform
.MakeIdentity();
204 // Apply size delta from the child(container) layer.
205 expected_grand_child_transform
.Translate(20.0, 20.0);
207 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
208 child
->draw_transform());
209 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
210 grand_child
->draw_transform());
213 TEST_F(LayerPositionConstraintTest
,
214 ScrollCompensationForFixedPositionLayerWithTransformedDirectContainer
) {
215 // This test checks for correct scroll compensation when the fixed-position
216 // container is the direct parent of the fixed-position layer, but that
217 // container is transformed. In this case, the fixed position element
218 // inherits the container's transform, but the scroll delta that has to be
219 // undone should not be affected by that transform.
221 // Transforms are in general non-commutative; using something like a
222 // non-uniform scale helps to verify that translations and non-uniform scales
223 // are applied in the correct order.
224 LayerImpl
* child
= scroll_
->children()[0];
225 LayerImpl
* grand_child
= child
->children()[0];
227 // This scale will cause child and grand_child to be effectively 200 x 800
228 // with respect to the render target.
229 gfx::Transform non_uniform_scale
;
230 non_uniform_scale
.Scale(2.0, 8.0);
231 child
->SetTransform(non_uniform_scale
);
233 child
->SetIsContainerForFixedPositionLayers(true);
234 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
236 // Case 1: scroll delta of 0, 0
237 child
->SetScrollDelta(gfx::Vector2d(0, 0));
238 ExecuteCalculateDrawProperties(root_
.get());
240 gfx::Transform expected_child_transform
;
241 expected_child_transform
.PreconcatTransform(non_uniform_scale
);
243 gfx::Transform expected_grand_child_transform
= expected_child_transform
;
245 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
246 child
->draw_transform());
247 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
248 grand_child
->draw_transform());
250 // Case 2: scroll delta of 10, 20
251 child
->SetScrollDelta(gfx::Vector2d(10, 20));
252 ExecuteCalculateDrawProperties(root_
.get());
254 // The child should be affected by scroll delta, but the fixed position
255 // grand_child should not be affected.
256 expected_child_transform
.MakeIdentity();
257 expected_child_transform
.Translate(-10.0, -20.0); // scroll delta
258 expected_child_transform
.PreconcatTransform(non_uniform_scale
);
260 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
261 child
->draw_transform());
262 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
263 grand_child
->draw_transform());
265 // Case 3: fixed-container size delta of 20, 20
266 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
267 ExecuteCalculateDrawProperties(root_
.get());
269 // Top-left fixed-position layer should not be affected by container size.
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 4: Bottom-right fixed-position layer.
276 grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
277 ExecuteCalculateDrawProperties(root_
.get());
279 // Bottom-right fixed-position layer moves as container resizes.
280 expected_grand_child_transform
.MakeIdentity();
281 // Apply child layer transform.
282 expected_grand_child_transform
.PreconcatTransform(non_uniform_scale
);
283 // Apply size delta from the child(container) layer.
284 expected_grand_child_transform
.Translate(20.0, 20.0);
286 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
287 child
->draw_transform());
288 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
289 grand_child
->draw_transform());
292 TEST_F(LayerPositionConstraintTest
,
293 ScrollCompensationForFixedPositionLayerWithDistantContainer
) {
294 // This test checks for correct scroll compensation when the fixed-position
295 // container is NOT the direct parent of the fixed-position layer.
296 LayerImpl
* child
= scroll_
->children()[0];
297 LayerImpl
* grand_child
= child
->children()[0];
298 LayerImpl
* great_grand_child
= grand_child
->children()[0];
300 child
->SetIsContainerForFixedPositionLayers(true);
301 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
302 great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
304 // Case 1: scroll delta of 0, 0
305 child
->SetScrollDelta(gfx::Vector2d(0, 0));
306 ExecuteCalculateDrawProperties(root_
.get());
308 gfx::Transform expected_child_transform
;
309 gfx::Transform expected_grand_child_transform
;
310 expected_grand_child_transform
.Translate(8.0, 6.0);
312 gfx::Transform expected_great_grand_child_transform
=
313 expected_grand_child_transform
;
315 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
316 child
->draw_transform());
317 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
318 grand_child
->draw_transform());
319 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
320 great_grand_child
->draw_transform());
322 // Case 2: scroll delta of 10, 10
323 child
->SetScrollDelta(gfx::Vector2d(10, 10));
324 ExecuteCalculateDrawProperties(root_
.get());
326 // Here the child and grand_child are affected by scroll delta, but the fixed
327 // position great_grand_child should not be affected.
328 expected_child_transform
.MakeIdentity();
329 expected_child_transform
.Translate(-10.0, -10.0);
330 expected_grand_child_transform
.MakeIdentity();
331 expected_grand_child_transform
.Translate(-2.0, -4.0);
332 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
333 child
->draw_transform());
334 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
335 grand_child
->draw_transform());
336 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
337 great_grand_child
->draw_transform());
339 // Case 3: fixed-container size delta of 20, 20
340 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
341 ExecuteCalculateDrawProperties(root_
.get());
343 // Top-left fixed-position layer should not be affected by container size.
344 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
345 child
->draw_transform());
346 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
347 grand_child
->draw_transform());
348 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
349 great_grand_child
->draw_transform());
351 // Case 4: Bottom-right fixed-position layer.
352 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
353 ExecuteCalculateDrawProperties(root_
.get());
355 // Bottom-right fixed-position layer moves as container resizes.
356 expected_great_grand_child_transform
.MakeIdentity();
357 // Apply size delta from the child(container) layer.
358 expected_great_grand_child_transform
.Translate(20.0, 20.0);
359 // Apply layer position from the grand child layer.
360 expected_great_grand_child_transform
.Translate(8.0, 6.0);
362 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
363 child
->draw_transform());
364 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
365 grand_child
->draw_transform());
366 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
367 great_grand_child
->draw_transform());
370 TEST_F(LayerPositionConstraintTest
,
371 ScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms
) {
372 // This test checks for correct scroll compensation when the fixed-position
373 // container is NOT the direct parent of the fixed-position layer, and the
374 // hierarchy has various transforms that have to be processed in the correct
376 LayerImpl
* child
= scroll_
->children()[0];
377 LayerImpl
* grand_child
= child
->children()[0];
378 LayerImpl
* great_grand_child
= grand_child
->children()[0];
380 gfx::Transform rotation_about_z
;
381 rotation_about_z
.RotateAboutZAxis(90.0);
383 child
->SetIsContainerForFixedPositionLayers(true);
384 child
->SetTransform(rotation_about_z
);
385 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
386 grand_child
->SetTransform(rotation_about_z
);
387 // great_grand_child is positioned upside-down with respect to the render
389 great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
391 // Case 1: scroll delta of 0, 0
392 child
->SetScrollDelta(gfx::Vector2d(0, 0));
393 ExecuteCalculateDrawProperties(root_
.get());
395 gfx::Transform expected_child_transform
;
396 expected_child_transform
.PreconcatTransform(rotation_about_z
);
398 gfx::Transform expected_grand_child_transform
;
399 expected_grand_child_transform
.PreconcatTransform(
400 rotation_about_z
); // child's local transform is inherited
401 // translation because of position occurs before layer's local transform.
402 expected_grand_child_transform
.Translate(8.0, 6.0);
403 expected_grand_child_transform
.PreconcatTransform(
404 rotation_about_z
); // grand_child's local transform
406 gfx::Transform expected_great_grand_child_transform
=
407 expected_grand_child_transform
;
409 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
410 child
->draw_transform());
411 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
412 grand_child
->draw_transform());
413 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
414 great_grand_child
->draw_transform());
416 // Case 2: scroll delta of 10, 20
417 child
->SetScrollDelta(gfx::Vector2d(10, 20));
418 ExecuteCalculateDrawProperties(root_
.get());
420 // Here the child and grand_child are affected by scroll delta, but the fixed
421 // position great_grand_child should not be affected.
422 expected_child_transform
.MakeIdentity();
423 expected_child_transform
.Translate(-10.0, -20.0); // scroll delta
424 expected_child_transform
.PreconcatTransform(rotation_about_z
);
426 expected_grand_child_transform
.MakeIdentity();
427 expected_grand_child_transform
.Translate(
428 -10.0, -20.0); // child's scroll delta is inherited
429 expected_grand_child_transform
.PreconcatTransform(
430 rotation_about_z
); // child's local transform is inherited
431 // translation because of position occurs before layer's local transform.
432 expected_grand_child_transform
.Translate(8.0, 6.0);
433 expected_grand_child_transform
.PreconcatTransform(
434 rotation_about_z
); // grand_child's local transform
436 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
437 child
->draw_transform());
438 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
439 grand_child
->draw_transform());
440 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
441 great_grand_child
->draw_transform());
443 // Case 3: fixed-container size delta of 20, 20
444 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
445 ExecuteCalculateDrawProperties(root_
.get());
447 // Top-left fixed-position layer should not be affected by container size.
448 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
449 child
->draw_transform());
450 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
451 grand_child
->draw_transform());
452 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
453 great_grand_child
->draw_transform());
455 // Case 4: Bottom-right fixed-position layer.
456 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
457 ExecuteCalculateDrawProperties(root_
.get());
459 // Bottom-right fixed-position layer moves as container resizes.
460 expected_great_grand_child_transform
.MakeIdentity();
461 // Apply child layer transform.
462 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
463 // Apply size delta from the child(container) layer.
464 expected_great_grand_child_transform
.Translate(20.0, 20.0);
465 // Apply layer position from the grand child layer.
466 expected_great_grand_child_transform
.Translate(8.0, 6.0);
467 // Apply grand child layer transform.
468 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
470 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
471 child
->draw_transform());
472 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
473 grand_child
->draw_transform());
474 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
475 great_grand_child
->draw_transform());
478 TEST_F(LayerPositionConstraintTest
,
479 ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas
) {
480 // This test checks for correct scroll compensation when the fixed-position
481 // container has multiple ancestors that have nonzero scroll delta before
482 // reaching the space where the layer is fixed. In this test, each scroll
483 // delta occurs in a different space because of each layer's local transform.
484 // This test checks for correct scroll compensation when the fixed-position
485 // container is NOT the direct parent of the fixed-position layer, and the
486 // hierarchy has various transforms that have to be processed in the correct
488 LayerImpl
* child
= scroll_
->children()[0];
489 LayerImpl
* grand_child
= child
->children()[0];
490 LayerImpl
* great_grand_child
= grand_child
->children()[0];
492 gfx::Transform rotation_about_z
;
493 rotation_about_z
.RotateAboutZAxis(90.0);
495 child
->SetIsContainerForFixedPositionLayers(true);
496 child
->SetTransform(rotation_about_z
);
497 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
498 grand_child
->SetTransform(rotation_about_z
);
499 // great_grand_child is positioned upside-down with respect to the render
501 great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
503 // Case 1: scroll delta of 0, 0
504 child
->SetScrollDelta(gfx::Vector2d(0, 0));
505 ExecuteCalculateDrawProperties(root_
.get());
507 gfx::Transform expected_child_transform
;
508 expected_child_transform
.PreconcatTransform(rotation_about_z
);
510 gfx::Transform expected_grand_child_transform
;
511 expected_grand_child_transform
.PreconcatTransform(
512 rotation_about_z
); // child's local transform is inherited
513 // translation because of position occurs before layer's local transform.
514 expected_grand_child_transform
.Translate(8.0, 6.0);
515 expected_grand_child_transform
.PreconcatTransform(
516 rotation_about_z
); // grand_child's local transform
518 gfx::Transform expected_great_grand_child_transform
=
519 expected_grand_child_transform
;
521 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
522 child
->draw_transform());
523 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
524 grand_child
->draw_transform());
525 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
526 great_grand_child
->draw_transform());
528 // Case 2: scroll delta of 10, 20
529 child
->SetScrollDelta(gfx::Vector2d(10, 0));
530 grand_child
->SetScrollDelta(gfx::Vector2d(5, 0));
531 ExecuteCalculateDrawProperties(root_
.get());
533 // Here the child and grand_child are affected by scroll delta, but the fixed
534 // position great_grand_child should not be affected.
535 expected_child_transform
.MakeIdentity();
536 expected_child_transform
.Translate(-10.0, 0.0); // scroll delta
537 expected_child_transform
.PreconcatTransform(rotation_about_z
);
539 expected_grand_child_transform
.MakeIdentity();
540 expected_grand_child_transform
.Translate(
541 -10.0, 0.0); // child's scroll delta is inherited
542 expected_grand_child_transform
.PreconcatTransform(
543 rotation_about_z
); // child's local transform is inherited
544 expected_grand_child_transform
.Translate(-5.0,
545 0.0); // grand_child's scroll delta
546 // translation because of position occurs before layer's local transform.
547 expected_grand_child_transform
.Translate(8.0, 6.0);
548 expected_grand_child_transform
.PreconcatTransform(
549 rotation_about_z
); // grand_child's local transform
551 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
552 child
->draw_transform());
553 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
554 grand_child
->draw_transform());
555 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
556 great_grand_child
->draw_transform());
558 // Case 3: fixed-container size delta of 20, 20
559 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
560 ExecuteCalculateDrawProperties(root_
.get());
562 // Top-left fixed-position layer should not be affected by container size.
563 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
564 child
->draw_transform());
565 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
566 grand_child
->draw_transform());
567 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
568 great_grand_child
->draw_transform());
570 // Case 4: Bottom-right fixed-position layer.
571 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
572 ExecuteCalculateDrawProperties(root_
.get());
574 // Bottom-right fixed-position layer moves as container resizes.
575 expected_great_grand_child_transform
.MakeIdentity();
576 // Apply child layer transform.
577 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
578 // Apply size delta from the child(container) layer.
579 expected_great_grand_child_transform
.Translate(20.0, 20.0);
580 // Apply layer position from the grand child layer.
581 expected_great_grand_child_transform
.Translate(8.0, 6.0);
582 // Apply grand child layer transform.
583 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
585 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
586 child
->draw_transform());
587 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
588 grand_child
->draw_transform());
589 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
590 great_grand_child
->draw_transform());
593 TEST_F(LayerPositionConstraintTest
,
594 ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms
) {
595 // This test checks for correct scroll compensation when the fixed-position
596 // container contributes to a different render surface than the fixed-position
597 // layer. In this case, the surface draw transforms also have to be accounted
598 // for when checking the scroll delta.
599 LayerImpl
* child
= scroll_
->children()[0];
600 LayerImpl
* grand_child
= child
->children()[0];
601 LayerImpl
* great_grand_child
= grand_child
->children()[0];
603 child
->SetIsContainerForFixedPositionLayers(true);
604 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
605 grand_child
->SetForceRenderSurface(true);
606 great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
607 great_grand_child
->SetDrawsContent(true);
609 gfx::Transform rotation_about_z
;
610 rotation_about_z
.RotateAboutZAxis(90.0);
611 grand_child
->SetTransform(rotation_about_z
);
613 // Case 1: scroll delta of 0, 0
614 child
->SetScrollDelta(gfx::Vector2d(0, 0));
615 ExecuteCalculateDrawProperties(root_
.get());
617 gfx::Transform expected_child_transform
;
618 gfx::Transform expected_surface_draw_transform
;
619 expected_surface_draw_transform
.Translate(8.0, 6.0);
620 expected_surface_draw_transform
.PreconcatTransform(rotation_about_z
);
621 gfx::Transform expected_grand_child_transform
;
622 gfx::Transform expected_great_grand_child_transform
;
623 ASSERT_TRUE(grand_child
->render_surface());
624 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
625 child
->draw_transform());
626 EXPECT_TRANSFORMATION_MATRIX_EQ(
627 expected_surface_draw_transform
,
628 grand_child
->render_surface()->draw_transform());
629 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
630 grand_child
->draw_transform());
631 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
632 great_grand_child
->draw_transform());
634 // Case 2: scroll delta of 10, 30
635 child
->SetScrollDelta(gfx::Vector2d(10, 30));
636 ExecuteCalculateDrawProperties(root_
.get());
638 // Here the grand_child remains unchanged, because it scrolls along with the
639 // render surface, and the translation is actually in the render surface. But,
640 // the fixed position great_grand_child is more awkward: its actually being
641 // drawn with respect to the render surface, but it needs to remain fixed with
642 // resepct to a container beyond that surface. So, the net result is that,
643 // unlike previous tests where the fixed position layer's transform remains
644 // unchanged, here the fixed position layer's transform explicitly contains
645 // the translation that cancels out the scroll.
646 expected_child_transform
.MakeIdentity();
647 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
649 expected_surface_draw_transform
.MakeIdentity();
650 expected_surface_draw_transform
.Translate(-10.0, -30.0); // scroll delta
651 expected_surface_draw_transform
.Translate(8.0, 6.0);
652 expected_surface_draw_transform
.PreconcatTransform(rotation_about_z
);
654 // The rotation and its inverse are needed to place the scroll delta
655 // compensation in the correct space. This test will fail if the
656 // rotation/inverse are backwards, too, so it requires perfect order of
658 expected_great_grand_child_transform
.MakeIdentity();
659 expected_great_grand_child_transform
.PreconcatTransform(
660 Inverse(rotation_about_z
));
661 // explicit canceling out the scroll delta that gets embedded in the fixed
662 // position layer's surface.
663 expected_great_grand_child_transform
.Translate(10.0, 30.0);
664 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
666 ASSERT_TRUE(grand_child
->render_surface());
667 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
668 child
->draw_transform());
669 EXPECT_TRANSFORMATION_MATRIX_EQ(
670 expected_surface_draw_transform
,
671 grand_child
->render_surface()->draw_transform());
672 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
673 grand_child
->draw_transform());
674 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
675 great_grand_child
->draw_transform());
677 // Case 3: fixed-container size delta of 20, 20
678 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
679 ExecuteCalculateDrawProperties(root_
.get());
681 // Top-left fixed-position layer should not be affected by container size.
682 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
683 child
->draw_transform());
684 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
685 grand_child
->draw_transform());
686 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
687 great_grand_child
->draw_transform());
689 // Case 4: Bottom-right fixed-position layer.
690 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
691 ExecuteCalculateDrawProperties(root_
.get());
693 // Bottom-right fixed-position layer moves as container resizes.
694 expected_great_grand_child_transform
.MakeIdentity();
695 // The rotation and its inverse are needed to place the scroll delta
696 // compensation in the correct space. This test will fail if the
697 // rotation/inverse are backwards, too, so it requires perfect order of
699 expected_great_grand_child_transform
.PreconcatTransform(
700 Inverse(rotation_about_z
));
701 // explicit canceling out the scroll delta that gets embedded in the fixed
702 // position layer's surface.
703 expected_great_grand_child_transform
.Translate(10.0, 30.0);
704 // Also apply size delta in the child(container) layer space.
705 expected_great_grand_child_transform
.Translate(20.0, 20.0);
706 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
708 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
709 child
->draw_transform());
710 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
711 grand_child
->draw_transform());
712 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
713 great_grand_child
->draw_transform());
716 TEST_F(LayerPositionConstraintTest
,
717 ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces
) {
718 // This test checks for correct scroll compensation when the fixed-position
719 // container contributes to a different render surface than the fixed-position
720 // layer, with additional render surfaces in-between. This checks that the
721 // conversion to ancestor surfaces is accumulated properly in the final matrix
723 LayerImpl
* child
= scroll_
->children()[0];
724 LayerImpl
* grand_child
= child
->children()[0];
725 LayerImpl
* great_grand_child
= grand_child
->children()[0];
727 // Add one more layer to the test tree for this scenario.
729 gfx::Transform identity
;
730 scoped_ptr
<LayerImpl
> fixed_position_child
=
731 LayerImpl::Create(host_impl_
.active_tree(), 5);
732 SetLayerPropertiesForTesting(fixed_position_child
.get(),
738 great_grand_child
->AddChild(fixed_position_child
.Pass());
740 LayerImpl
* fixed_position_child
= great_grand_child
->children()[0];
742 // Actually set up the scenario here.
743 child
->SetIsContainerForFixedPositionLayers(true);
744 grand_child
->SetPosition(gfx::PointF(8.f
, 6.f
));
745 grand_child
->SetForceRenderSurface(true);
746 great_grand_child
->SetPosition(gfx::PointF(40.f
, 60.f
));
747 great_grand_child
->SetForceRenderSurface(true);
748 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
749 fixed_position_child
->SetDrawsContent(true);
751 // The additional rotations, which are non-commutative with translations, help
752 // to verify that we have correct order-of-operations in the final scroll
753 // compensation. Note that rotating about the center of the layer ensures we
754 // do not accidentally clip away layers that we want to test.
755 gfx::Transform rotation_about_z
;
756 rotation_about_z
.Translate(50.0, 50.0);
757 rotation_about_z
.RotateAboutZAxis(90.0);
758 rotation_about_z
.Translate(-50.0, -50.0);
759 grand_child
->SetTransform(rotation_about_z
);
760 great_grand_child
->SetTransform(rotation_about_z
);
762 // Case 1: scroll delta of 0, 0
763 child
->SetScrollDelta(gfx::Vector2d(0, 0));
764 ExecuteCalculateDrawProperties(root_
.get());
766 gfx::Transform expected_child_transform
;
768 gfx::Transform expected_grand_child_surface_draw_transform
;
769 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
770 expected_grand_child_surface_draw_transform
.PreconcatTransform(
773 gfx::Transform expected_grand_child_transform
;
775 gfx::Transform expected_great_grand_child_surface_draw_transform
;
776 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
777 expected_great_grand_child_surface_draw_transform
.PreconcatTransform(
780 gfx::Transform expected_great_grand_child_transform
;
782 gfx::Transform expected_fixed_position_child_transform
;
784 ASSERT_TRUE(grand_child
->render_surface());
785 ASSERT_TRUE(great_grand_child
->render_surface());
786 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
787 child
->draw_transform());
788 EXPECT_TRANSFORMATION_MATRIX_EQ(
789 expected_grand_child_surface_draw_transform
,
790 grand_child
->render_surface()->draw_transform());
791 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
792 grand_child
->draw_transform());
793 EXPECT_TRANSFORMATION_MATRIX_EQ(
794 expected_great_grand_child_surface_draw_transform
,
795 great_grand_child
->render_surface()->draw_transform());
796 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
797 great_grand_child
->draw_transform());
798 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
799 fixed_position_child
->draw_transform());
801 // Case 2: scroll delta of 10, 30
802 child
->SetScrollDelta(gfx::Vector2d(10, 30));
803 ExecuteCalculateDrawProperties(root_
.get());
805 expected_child_transform
.MakeIdentity();
806 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
808 expected_grand_child_surface_draw_transform
.MakeIdentity();
809 expected_grand_child_surface_draw_transform
.Translate(-10.0,
810 -30.0); // scroll delta
811 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
812 expected_grand_child_surface_draw_transform
.PreconcatTransform(
815 // grand_child, great_grand_child, and great_grand_child's surface are not
816 // expected to change, since they are all not fixed, and they are all drawn
817 // with respect to grand_child's surface that already has the scroll delta
820 // But the great-great grandchild, "fixed_position_child", should have a
821 // transform that explicitly cancels out the scroll delta. The expected
822 // transform is: compound_draw_transform.Inverse() * translate(positive scroll
823 // delta) * compound_origin_transform from great_grand_childSurface's origin
824 // to the root surface.
825 gfx::Transform compound_draw_transform
;
826 compound_draw_transform
.Translate(8.0,
827 6.0); // origin translation of grand_child
828 compound_draw_transform
.PreconcatTransform(
829 rotation_about_z
); // rotation of grand_child
830 compound_draw_transform
.Translate(
831 40.0, 60.0); // origin translation of great_grand_child
832 compound_draw_transform
.PreconcatTransform(
833 rotation_about_z
); // rotation of great_grand_child
835 expected_fixed_position_child_transform
.MakeIdentity();
836 expected_fixed_position_child_transform
.PreconcatTransform(
837 Inverse(compound_draw_transform
));
838 // explicit canceling out the scroll delta that gets embedded in the fixed
839 // position layer's surface.
840 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
841 expected_fixed_position_child_transform
.PreconcatTransform(
842 compound_draw_transform
);
844 ASSERT_TRUE(grand_child
->render_surface());
845 ASSERT_TRUE(great_grand_child
->render_surface());
846 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
847 child
->draw_transform());
848 EXPECT_TRANSFORMATION_MATRIX_EQ(
849 expected_grand_child_surface_draw_transform
,
850 grand_child
->render_surface()->draw_transform());
851 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
852 grand_child
->draw_transform());
853 EXPECT_TRANSFORMATION_MATRIX_EQ(
854 expected_great_grand_child_surface_draw_transform
,
855 great_grand_child
->render_surface()->draw_transform());
856 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
857 great_grand_child
->draw_transform());
858 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
859 fixed_position_child
->draw_transform());
862 // Case 3: fixed-container size delta of 20, 20
863 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
864 ExecuteCalculateDrawProperties(root_
.get());
866 // Top-left fixed-position layer should not be affected by container size.
867 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
868 child
->draw_transform());
869 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
870 grand_child
->draw_transform());
871 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
872 great_grand_child
->draw_transform());
873 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
874 fixed_position_child
->draw_transform());
876 // Case 4: Bottom-right fixed-position layer.
877 fixed_position_child
->SetPositionConstraint(fixed_to_bottom_right_
);
878 ExecuteCalculateDrawProperties(root_
.get());
880 // Bottom-right fixed-position layer moves as container resizes.
881 expected_fixed_position_child_transform
.MakeIdentity();
882 expected_fixed_position_child_transform
.PreconcatTransform(
883 Inverse(compound_draw_transform
));
884 // explicit canceling out the scroll delta that gets embedded in the fixed
885 // position layer's surface.
886 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
887 // Also apply size delta in the child(container) layer space.
888 expected_fixed_position_child_transform
.Translate(20.0, 20.0);
889 expected_fixed_position_child_transform
.PreconcatTransform(
890 compound_draw_transform
);
892 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
893 child
->draw_transform());
894 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
895 grand_child
->draw_transform());
896 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
897 great_grand_child
->draw_transform());
898 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
899 fixed_position_child
->draw_transform());
902 TEST_F(LayerPositionConstraintTest
,
903 ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface
) {
904 // This test checks for correct scroll compensation when the fixed-position
905 // container itself has a render surface. In this case, the container layer
906 // should be treated like a layer that contributes to a render target, and
907 // that render target is completely irrelevant; it should not affect the
908 // scroll compensation.
909 LayerImpl
* child
= scroll_
->children()[0];
910 LayerImpl
* grand_child
= child
->children()[0];
912 child
->SetIsContainerForFixedPositionLayers(true);
913 child
->SetForceRenderSurface(true);
914 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
915 grand_child
->SetDrawsContent(true);
917 // Case 1: scroll delta of 0, 0
918 child
->SetScrollDelta(gfx::Vector2d(0, 0));
919 ExecuteCalculateDrawProperties(root_
.get());
921 gfx::Transform expected_surface_draw_transform
;
922 expected_surface_draw_transform
.Translate(0.0, 0.0);
923 gfx::Transform expected_child_transform
;
924 gfx::Transform expected_grand_child_transform
;
925 ASSERT_TRUE(child
->render_surface());
926 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform
,
927 child
->render_surface()->draw_transform());
928 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
929 child
->draw_transform());
930 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
931 grand_child
->draw_transform());
933 // Case 2: scroll delta of 10, 10
934 child
->SetScrollDelta(gfx::Vector2d(10, 10));
935 ExecuteCalculateDrawProperties(root_
.get());
937 // The surface is translated by scroll delta, the child transform doesn't
938 // change because it scrolls along with the surface, but the fixed position
939 // grand_child needs to compensate for the scroll translation.
940 expected_surface_draw_transform
.MakeIdentity();
941 expected_surface_draw_transform
.Translate(-10.0, -10.0);
942 expected_grand_child_transform
.MakeIdentity();
943 expected_grand_child_transform
.Translate(10.0, 10.0);
945 ASSERT_TRUE(child
->render_surface());
946 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform
,
947 child
->render_surface()->draw_transform());
948 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
949 child
->draw_transform());
950 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
951 grand_child
->draw_transform());
953 // Case 3: fixed-container size delta of 20, 20
954 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
955 ExecuteCalculateDrawProperties(root_
.get());
957 // Top-left fixed-position layer should not be affected by container size.
958 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
959 child
->draw_transform());
960 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
961 grand_child
->draw_transform());
963 // Case 4: Bottom-right fixed-position layer.
964 grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
965 ExecuteCalculateDrawProperties(root_
.get());
967 // Bottom-right fixed-position layer moves as container resizes.
968 expected_grand_child_transform
.MakeIdentity();
969 // The surface is translated by scroll delta, the child transform doesn't
970 // change because it scrolls along with the surface, but the fixed position
971 // grand_child needs to compensate for the scroll translation.
972 expected_grand_child_transform
.Translate(10.0, 10.0);
973 // Apply size delta from the child(container) layer.
974 expected_grand_child_transform
.Translate(20.0, 20.0);
976 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
977 child
->draw_transform());
978 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
979 grand_child
->draw_transform());
982 TEST_F(LayerPositionConstraintTest
,
983 ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer
) {
984 // This test checks the scenario where a fixed-position layer also happens to
985 // be a container itself for a descendant fixed position layer. In particular,
986 // the layer should not accidentally be fixed to itself.
987 LayerImpl
* child
= scroll_
->children()[0];
988 LayerImpl
* grand_child
= child
->children()[0];
990 child
->SetIsContainerForFixedPositionLayers(true);
991 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
993 // This should not confuse the grand_child. If correct, the grand_child would
994 // still be considered fixed to its container (i.e. "child").
995 grand_child
->SetIsContainerForFixedPositionLayers(true);
997 // Case 1: scroll delta of 0, 0
998 child
->SetScrollDelta(gfx::Vector2d(0, 0));
999 ExecuteCalculateDrawProperties(root_
.get());
1001 gfx::Transform expected_child_transform
;
1002 gfx::Transform expected_grand_child_transform
;
1003 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1004 child
->draw_transform());
1005 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1006 grand_child
->draw_transform());
1008 // Case 2: scroll delta of 10, 10
1009 child
->SetScrollDelta(gfx::Vector2d(10, 10));
1010 ExecuteCalculateDrawProperties(root_
.get());
1012 // Here the child is affected by scroll delta, but the fixed position
1013 // grand_child should not be affected.
1014 expected_child_transform
.MakeIdentity();
1015 expected_child_transform
.Translate(-10.0, -10.0);
1016 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1017 child
->draw_transform());
1018 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1019 grand_child
->draw_transform());
1021 // Case 3: fixed-container size delta of 20, 20
1022 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
1023 ExecuteCalculateDrawProperties(root_
.get());
1025 // Top-left fixed-position layer should not be affected by container size.
1026 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1027 child
->draw_transform());
1028 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1029 grand_child
->draw_transform());
1031 // Case 4: Bottom-right fixed-position layer.
1032 grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
1033 ExecuteCalculateDrawProperties(root_
.get());
1035 // Bottom-right fixed-position layer moves as container resizes.
1036 expected_grand_child_transform
.MakeIdentity();
1037 // Apply size delta from the child(container) layer.
1038 expected_grand_child_transform
.Translate(20.0, 20.0);
1040 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1041 child
->draw_transform());
1042 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1043 grand_child
->draw_transform());
1046 TEST_F(LayerPositionConstraintTest
,
1047 ScrollCompensationForFixedWithinFixedWithSameContainer
) {
1048 // This test checks scroll compensation for a fixed-position layer that is
1049 // inside of another fixed-position layer and both share the same container.
1050 // In this situation, the parent fixed-position layer will receive
1051 // the scroll compensation, and the child fixed-position layer does not
1052 // need to compensate further.
1054 LayerImpl
* child
= scroll_
->children()[0];
1055 LayerImpl
* grand_child
= child
->children()[0];
1056 LayerImpl
* great_grand_child
= grand_child
->children()[0];
1058 child
->SetIsContainerForFixedPositionLayers(true);
1059 grand_child
->SetPositionConstraint(fixed_to_top_left_
);
1061 // Note carefully - great_grand_child is fixed to bottom right, to test
1062 // sizeDelta being applied correctly; the compensation skips the grand_child
1063 // because it is fixed to top left.
1064 great_grand_child
->SetPositionConstraint(fixed_to_bottom_right_
);
1066 // Case 1: scrollDelta
1067 child
->SetScrollDelta(gfx::Vector2d(10, 10));
1068 ExecuteCalculateDrawProperties(root_
.get());
1070 // Here the child is affected by scroll delta, but the fixed position
1071 // grand_child should not be affected.
1072 gfx::Transform expected_child_transform
;
1073 expected_child_transform
.Translate(-10.0, -10.0);
1075 gfx::Transform expected_grand_child_transform
;
1076 gfx::Transform expected_great_grand_child_transform
;
1078 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1079 child
->draw_transform());
1080 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1081 grand_child
->draw_transform());
1082 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
1083 great_grand_child
->draw_transform());
1085 // Case 2: sizeDelta
1086 child
->SetScrollDelta(gfx::Vector2d(0, 0));
1087 SetFixedContainerSizeDelta(child
, gfx::Vector2d(20, 20));
1088 ExecuteCalculateDrawProperties(root_
.get());
1090 expected_child_transform
.MakeIdentity();
1092 expected_grand_child_transform
.MakeIdentity();
1094 // Fixed to bottom-right, size-delta compensation is applied.
1095 expected_great_grand_child_transform
.MakeIdentity();
1096 expected_great_grand_child_transform
.Translate(20.0, 20.0);
1098 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1099 child
->draw_transform());
1100 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1101 grand_child
->draw_transform());
1102 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
1103 great_grand_child
->draw_transform());
1106 TEST_F(LayerPositionConstraintTest
,
1107 ScrollCompensationForFixedWithinFixedWithInterveningContainer
) {
1108 // This test checks scroll compensation for a fixed-position layer that is
1109 // inside of another fixed-position layer, but they have different fixed
1110 // position containers. In this situation, the child fixed-position element
1111 // would still have to compensate with respect to its container.
1113 LayerImpl
* container1
= scroll_
->children()[0];
1114 LayerImpl
* fixed_to_container1
= container1
->children()[0];
1115 LayerImpl
* container2
= fixed_to_container1
->children()[0];
1118 // Add one more layer to the hierarchy for this test.
1119 scoped_ptr
<LayerImpl
> fixed_to_container2_ptr
=
1120 LayerImpl::Create(host_impl_
.active_tree(), 5);
1121 container2
->AddChild(fixed_to_container2_ptr
.Pass());
1124 LayerImpl
* fixed_to_container2
= container2
->children()[0];
1126 container1
->SetIsContainerForFixedPositionLayers(true);
1127 fixed_to_container1
->SetPositionConstraint(fixed_to_top_left_
);
1128 container2
->SetIsContainerForFixedPositionLayers(true);
1129 fixed_to_container2
->SetPositionConstraint(fixed_to_top_left_
);
1131 container1
->SetScrollDelta(gfx::Vector2d(0, 15));
1132 container2
->SetScrollDelta(gfx::Vector2d(30, 0));
1133 ExecuteCalculateDrawProperties(root_
.get());
1135 gfx::Transform expected_container1_transform
;
1136 expected_container1_transform
.Translate(0.0, -15.0);
1138 gfx::Transform expected_fixed_to_container1_transform
;
1140 // Since the container is a descendant of the fixed layer above,
1141 // the expected draw transform for container2 would not
1142 // include the scrollDelta that was applied to container1.
1143 gfx::Transform expected_container2_transform
;
1144 expected_container2_transform
.Translate(-30.0, 0.0);
1146 gfx::Transform expected_fixed_to_container2_transform
;
1148 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform
,
1149 container1
->draw_transform());
1151 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform
,
1152 fixed_to_container1
->draw_transform());
1154 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform
,
1155 container2
->draw_transform());
1157 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform
,
1158 fixed_to_container2
->draw_transform());