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.h"
10 #include "cc/layers/layer_impl.h"
11 #include "cc/test/fake_layer_tree_host.h"
12 #include "cc/test/geometry_test_utils.h"
13 #include "cc/test/test_task_graph_runner.h"
14 #include "cc/trees/layer_tree_host_common.h"
15 #include "testing/gtest/include/gtest/gtest.h"
20 class LayerWithForcedDrawsContent
: public Layer
{
22 explicit LayerWithForcedDrawsContent(const LayerSettings
& settings
)
25 bool DrawsContent() const override
;
28 ~LayerWithForcedDrawsContent() override
{}
31 bool LayerWithForcedDrawsContent::DrawsContent() const {
35 void SetLayerPropertiesForTesting(Layer
* layer
,
36 const gfx::Transform
& transform
,
37 const gfx::Point3F
& transform_origin
,
38 const gfx::PointF
& position
,
39 const gfx::Size
& bounds
,
40 bool flatten_transform
) {
41 layer
->SetTransform(transform
);
42 layer
->SetTransformOrigin(transform_origin
);
43 layer
->SetPosition(position
);
44 layer
->SetBounds(bounds
);
45 layer
->SetShouldFlattenTransform(flatten_transform
);
48 void ExecuteCalculateDrawProperties(LayerImpl
* root_layer
) {
49 std::vector
<LayerImpl
*> dummy_render_surface_layer_list
;
50 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
51 root_layer
, root_layer
->bounds(), &dummy_render_surface_layer_list
);
52 inputs
.inner_viewport_scroll_layer
=
53 root_layer
->layer_tree_impl()->InnerViewportScrollLayer();
54 inputs
.outer_viewport_scroll_layer
=
55 root_layer
->layer_tree_impl()->OuterViewportScrollLayer();
56 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
59 class LayerPositionConstraintTest
: public testing::Test
{
61 LayerPositionConstraintTest()
62 : fake_client_(FakeLayerTreeHostClient::DIRECT_3D
),
64 FakeLayerTreeHost::Create(&fake_client_
, &task_graph_runner_
)),
66 inner_viewport_container_layer_impl_(nullptr),
67 scroll_layer_impl_(nullptr),
68 outer_viewport_container_layer_impl_(nullptr),
69 child_transform_layer_impl_(nullptr),
71 grand_child_impl_(nullptr),
72 great_grand_child_impl_(nullptr) {
73 layer_tree_host_
->InitializeForTesting(scoped_ptr
<Proxy
>(new FakeProxy
));
75 fixed_to_top_left_
.set_is_fixed_position(true);
76 fixed_to_bottom_right_
.set_is_fixed_position(true);
77 fixed_to_bottom_right_
.set_is_fixed_to_right_edge(true);
78 fixed_to_bottom_right_
.set_is_fixed_to_bottom_edge(true);
81 void CreateTreeForTest() {
82 // scroll_layer_ is the inner viewport scroll layer and child_ is the outer
83 // viewport scroll layer.
84 root_
= Layer::Create(layer_settings_
);
85 inner_viewport_container_layer_
= Layer::Create(layer_settings_
);
86 scroll_layer_
= Layer::Create(layer_settings_
);
87 outer_viewport_container_layer_
= Layer::Create(layer_settings_
);
88 child_transform_layer_
= Layer::Create(layer_settings_
);
89 child_
= Layer::Create(layer_settings_
);
91 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
93 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
95 gfx::Transform IdentityMatrix
;
96 gfx::Point3F transform_origin
;
98 gfx::Size
bounds(200, 200);
99 gfx::Size
clip_bounds(100, 100);
100 SetLayerPropertiesForTesting(inner_viewport_container_layer_
.get(),
101 IdentityMatrix
, transform_origin
, position
,
103 SetLayerPropertiesForTesting(scroll_layer_
.get(), IdentityMatrix
,
104 transform_origin
, position
, bounds
, true);
105 SetLayerPropertiesForTesting(outer_viewport_container_layer_
.get(),
106 IdentityMatrix
, transform_origin
, position
,
108 SetLayerPropertiesForTesting(child_
.get(), IdentityMatrix
, transform_origin
,
109 position
, bounds
, true);
110 SetLayerPropertiesForTesting(grand_child_
.get(), IdentityMatrix
,
111 transform_origin
, position
, bounds
, true);
112 SetLayerPropertiesForTesting(great_grand_child_
.get(), IdentityMatrix
,
113 transform_origin
, position
, bounds
, true);
115 root_
->SetBounds(clip_bounds
);
117 inner_viewport_container_layer_
->SetMasksToBounds(true);
118 scroll_layer_
->SetScrollClipLayerId(inner_viewport_container_layer_
->id());
119 scroll_layer_
->SetIsContainerForFixedPositionLayers(true);
121 outer_viewport_container_layer_
->SetMasksToBounds(true);
122 child_
->SetScrollClipLayerId(outer_viewport_container_layer_
->id());
123 grand_child_
->SetScrollClipLayerId(outer_viewport_container_layer_
->id());
125 grand_child_
->AddChild(great_grand_child_
);
126 child_
->AddChild(grand_child_
);
127 child_transform_layer_
->AddChild(child_
);
128 outer_viewport_container_layer_
->AddChild(child_transform_layer_
);
129 scroll_layer_
->AddChild(outer_viewport_container_layer_
);
130 inner_viewport_container_layer_
->AddChild(scroll_layer_
);
131 root_
->AddChild(inner_viewport_container_layer_
);
133 layer_tree_host_
->SetRootLayer(root_
);
134 layer_tree_host_
->RegisterViewportLayers(nullptr, root_
, scroll_layer_
,
138 void CommitAndUpdateImplPointers() {
139 LayerTreeHostCommon::CalcDrawPropsMainInputs
inputs(root_
.get(),
141 inputs
.inner_viewport_scroll_layer
=
142 layer_tree_host_
->inner_viewport_scroll_layer();
143 inputs
.outer_viewport_scroll_layer
=
144 layer_tree_host_
->outer_viewport_scroll_layer();
145 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
147 // Since scroll deltas aren't sent back to the main thread in this test
148 // setup, clear them to maintain consistent state.
150 scroll_layer_impl_
->SetScrollDelta(gfx::Vector2dF());
151 child_impl_
->SetScrollDelta(gfx::Vector2dF());
152 grand_child_impl_
->SetScrollDelta(gfx::Vector2dF());
154 root_impl_
= layer_tree_host_
->CommitAndCreateLayerImplTree();
155 inner_viewport_container_layer_impl_
= root_impl_
->children()[0];
156 scroll_layer_impl_
= inner_viewport_container_layer_impl_
->children()[0];
157 outer_viewport_container_layer_impl_
= scroll_layer_impl_
->children()[0];
158 child_transform_layer_impl_
=
159 outer_viewport_container_layer_impl_
->children()[0];
160 child_impl_
= child_transform_layer_impl_
->children()[0];
161 grand_child_impl_
= child_impl_
->children()[0];
162 great_grand_child_impl_
= grand_child_impl_
->children()[0];
166 FakeLayerTreeHostClient fake_client_
;
167 TestTaskGraphRunner task_graph_runner_
;
168 scoped_ptr
<FakeLayerTreeHost
> layer_tree_host_
;
169 LayerSettings layer_settings_
;
170 scoped_refptr
<Layer
> root_
;
171 scoped_refptr
<Layer
> inner_viewport_container_layer_
;
172 scoped_refptr
<Layer
> scroll_layer_
;
173 scoped_refptr
<Layer
> outer_viewport_container_layer_
;
174 scoped_refptr
<Layer
> child_transform_layer_
;
175 scoped_refptr
<Layer
> child_
;
176 scoped_refptr
<Layer
> grand_child_
;
177 scoped_refptr
<Layer
> great_grand_child_
;
178 LayerImpl
* root_impl_
;
179 LayerImpl
* inner_viewport_container_layer_impl_
;
180 LayerImpl
* scroll_layer_impl_
;
181 LayerImpl
* outer_viewport_container_layer_impl_
;
182 LayerImpl
* child_transform_layer_impl_
;
183 LayerImpl
* child_impl_
;
184 LayerImpl
* grand_child_impl_
;
185 LayerImpl
* great_grand_child_impl_
;
187 LayerPositionConstraint fixed_to_top_left_
;
188 LayerPositionConstraint fixed_to_bottom_right_
;
193 void SetFixedContainerSizeDelta(LayerImpl
* scroll_layer
,
194 const gfx::Vector2d
& delta
) {
195 DCHECK(scroll_layer
);
196 DCHECK(scroll_layer
->scrollable());
198 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
199 container_layer
->SetBoundsDelta(delta
);
203 TEST_F(LayerPositionConstraintTest
,
204 ScrollCompensationForFixedPositionLayerWithDirectContainer
) {
205 // This test checks for correct scroll compensation when the fixed-position
206 // container is the direct parent of the fixed-position layer.
207 child_
->SetIsContainerForFixedPositionLayers(true);
208 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
210 CommitAndUpdateImplPointers();
212 // Case 1: scroll delta of 0, 0
213 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
214 ExecuteCalculateDrawProperties(root_impl_
);
216 gfx::Transform expected_child_transform
;
217 gfx::Transform expected_grand_child_transform
= expected_child_transform
;
219 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
220 child_impl_
->draw_transform());
221 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
222 grand_child_impl_
->draw_transform());
224 // Case 2: scroll delta of 10, 10
225 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
226 ExecuteCalculateDrawProperties(root_impl_
);
228 // Here the child is affected by scroll delta, but the fixed position
229 // grand_child should not be affected.
230 expected_child_transform
.MakeIdentity();
231 expected_child_transform
.Translate(-10.0, -10.0);
233 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
234 child_impl_
->draw_transform());
235 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
236 grand_child_impl_
->draw_transform());
238 // Case 3: fixed-container size delta of 20, 20
239 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
240 ExecuteCalculateDrawProperties(root_impl_
);
242 // Top-left fixed-position layer should not be affected by container size.
243 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
244 child_impl_
->draw_transform());
245 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
246 grand_child_impl_
->draw_transform());
248 // Case 4: Bottom-right fixed-position layer.
249 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
250 CommitAndUpdateImplPointers();
252 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
253 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
254 ExecuteCalculateDrawProperties(root_impl_
);
256 // Bottom-right fixed-position layer moves as container resizes.
257 expected_grand_child_transform
.MakeIdentity();
258 // Apply size delta from the child(container) layer.
259 expected_grand_child_transform
.Translate(20.0, 20.0);
261 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
262 child_impl_
->draw_transform());
263 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
264 grand_child_impl_
->draw_transform());
267 TEST_F(LayerPositionConstraintTest
,
268 ScrollCompensationForFixedPositionLayerWithDistantContainer
) {
269 // This test checks for correct scroll compensation when the fixed-position
270 // container is NOT the direct parent of the fixed-position layer.
271 child_
->SetIsContainerForFixedPositionLayers(true);
272 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
273 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
275 CommitAndUpdateImplPointers();
277 // Case 1: scroll delta of 0, 0
278 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
279 ExecuteCalculateDrawProperties(root_impl_
);
281 gfx::Transform expected_child_transform
;
282 gfx::Transform expected_grand_child_transform
;
283 expected_grand_child_transform
.Translate(8.0, 6.0);
285 gfx::Transform expected_great_grand_child_transform
=
286 expected_grand_child_transform
;
288 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
289 child_impl_
->draw_transform());
290 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
291 grand_child_impl_
->draw_transform());
292 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
293 great_grand_child_impl_
->draw_transform());
295 // Case 2: scroll delta of 10, 10
296 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
297 ExecuteCalculateDrawProperties(root_impl_
);
299 // Here the child and grand_child are affected by scroll delta, but the fixed
300 // position great_grand_child should not be affected.
301 expected_child_transform
.MakeIdentity();
302 expected_child_transform
.Translate(-10.0, -10.0);
303 expected_grand_child_transform
.MakeIdentity();
304 expected_grand_child_transform
.Translate(-2.0, -4.0);
305 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
306 child_impl_
->draw_transform());
307 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
308 grand_child_impl_
->draw_transform());
309 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
310 great_grand_child_impl_
->draw_transform());
312 // Case 3: fixed-container size delta of 20, 20
313 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
314 ExecuteCalculateDrawProperties(root_impl_
);
316 // Top-left fixed-position layer should not be affected by container size.
317 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
318 child_impl_
->draw_transform());
319 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
320 grand_child_impl_
->draw_transform());
321 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
322 great_grand_child_impl_
->draw_transform());
324 // Case 4: Bottom-right fixed-position layer.
325 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
326 CommitAndUpdateImplPointers();
327 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
328 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
329 ExecuteCalculateDrawProperties(root_impl_
);
331 // Bottom-right fixed-position layer moves as container resizes.
332 expected_great_grand_child_transform
.MakeIdentity();
333 // Apply size delta from the child(container) layer.
334 expected_great_grand_child_transform
.Translate(20.0, 20.0);
335 // Apply layer position from the grand child layer.
336 expected_great_grand_child_transform
.Translate(8.0, 6.0);
338 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
339 child_impl_
->draw_transform());
340 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
341 grand_child_impl_
->draw_transform());
342 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
343 great_grand_child_impl_
->draw_transform());
346 TEST_F(LayerPositionConstraintTest
,
347 ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas
) {
348 // This test checks for correct scroll compensation when the fixed-position
349 // container has multiple ancestors that have nonzero scroll delta before
350 // reaching the space where the layer is fixed.
351 gfx::Transform rotation_about_z
;
352 rotation_about_z
.RotateAboutZAxis(90.0);
354 child_transform_layer_
->SetIsContainerForFixedPositionLayers(true);
355 child_transform_layer_
->SetTransform(rotation_about_z
);
356 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
357 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
359 CommitAndUpdateImplPointers();
361 // Case 1: scroll delta of 0, 0
362 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
363 ExecuteCalculateDrawProperties(root_impl_
);
365 gfx::Transform expected_child_transform
;
366 expected_child_transform
.PreconcatTransform(rotation_about_z
);
368 gfx::Transform expected_grand_child_transform
;
369 expected_grand_child_transform
.PreconcatTransform(
370 rotation_about_z
); // child's local transform is inherited
371 // translation because of position occurs before layer's local transform.
372 expected_grand_child_transform
.Translate(8.0, 6.0);
374 gfx::Transform expected_great_grand_child_transform
=
375 expected_grand_child_transform
;
377 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
378 child_impl_
->draw_transform());
379 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
380 grand_child_impl_
->draw_transform());
381 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
382 great_grand_child_impl_
->draw_transform());
384 // Case 2: scroll delta of 10, 20
385 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 0));
386 grand_child_impl_
->SetScrollDelta(gfx::Vector2d(5, 0));
387 ExecuteCalculateDrawProperties(root_impl_
);
389 // Here the child and grand_child are affected by scroll delta, but the fixed
390 // position great_grand_child should not be affected.
391 expected_child_transform
.MakeIdentity();
392 expected_child_transform
.PreconcatTransform(rotation_about_z
);
393 expected_child_transform
.Translate(-10.0, 0.0); // scroll delta
395 expected_grand_child_transform
.MakeIdentity();
396 expected_grand_child_transform
.PreconcatTransform(
397 rotation_about_z
); // child's local transform is inherited
398 expected_grand_child_transform
.Translate(
399 -10.0, 0.0); // child's scroll delta is inherited
400 expected_grand_child_transform
.Translate(-5.0,
401 0.0); // grand_child's scroll delta
402 // translation because of position
403 expected_grand_child_transform
.Translate(8.0, 6.0);
405 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
406 child_impl_
->draw_transform());
407 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
408 grand_child_impl_
->draw_transform());
409 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
410 great_grand_child_impl_
->draw_transform());
413 TEST_F(LayerPositionConstraintTest
,
414 ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms
) {
415 // This test checks for correct scroll compensation when the fixed-position
416 // container contributes to a different render surface than the fixed-position
417 // layer. In this case, the surface draw transforms also have to be accounted
418 // for when checking the scroll delta.
419 child_
->SetIsContainerForFixedPositionLayers(true);
420 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
421 grand_child_
->SetForceRenderSurface(true);
422 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
424 gfx::Transform rotation_about_z
;
425 rotation_about_z
.RotateAboutZAxis(90.0);
426 great_grand_child_
->SetTransform(rotation_about_z
);
428 CommitAndUpdateImplPointers();
430 // Case 1: scroll delta of 0, 0
431 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
432 ExecuteCalculateDrawProperties(root_impl_
);
434 gfx::Transform expected_child_transform
;
435 gfx::Transform expected_surface_draw_transform
;
436 expected_surface_draw_transform
.Translate(8.0, 6.0);
437 gfx::Transform expected_grand_child_transform
;
438 gfx::Transform expected_great_grand_child_transform
;
439 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
440 EXPECT_TRUE(grand_child_impl_
->render_surface());
441 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
442 child_impl_
->draw_transform());
443 EXPECT_TRANSFORMATION_MATRIX_EQ(
444 expected_surface_draw_transform
,
445 grand_child_impl_
->render_surface()->draw_transform());
446 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
447 grand_child_impl_
->draw_transform());
448 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
449 great_grand_child_impl_
->draw_transform());
451 // Case 2: scroll delta of 10, 30
452 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
453 ExecuteCalculateDrawProperties(root_impl_
);
455 // Here the grand_child remains unchanged, because it scrolls along with the
456 // render surface, and the translation is actually in the render surface. But,
457 // the fixed position great_grand_child is more awkward: its actually being
458 // drawn with respect to the render surface, but it needs to remain fixed with
459 // resepct to a container beyond that surface. So, the net result is that,
460 // unlike previous tests where the fixed position layer's transform remains
461 // unchanged, here the fixed position layer's transform explicitly contains
462 // the translation that cancels out the scroll.
463 expected_child_transform
.MakeIdentity();
464 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
466 expected_surface_draw_transform
.MakeIdentity();
467 expected_surface_draw_transform
.Translate(-10.0, -30.0); // scroll delta
468 expected_surface_draw_transform
.Translate(8.0, 6.0);
470 expected_great_grand_child_transform
.MakeIdentity();
471 // explicit canceling out the scroll delta that gets embedded in the fixed
472 // position layer's surface.
473 expected_great_grand_child_transform
.Translate(10.0, 30.0);
474 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
476 EXPECT_TRUE(grand_child_impl_
->render_surface());
477 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
478 child_impl_
->draw_transform());
479 EXPECT_TRANSFORMATION_MATRIX_EQ(
480 expected_surface_draw_transform
,
481 grand_child_impl_
->render_surface()->draw_transform());
482 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
483 grand_child_impl_
->draw_transform());
484 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
485 great_grand_child_impl_
->draw_transform());
487 // Case 3: fixed-container size delta of 20, 20
488 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
489 ExecuteCalculateDrawProperties(root_impl_
);
491 // Top-left fixed-position layer should not be affected by container size.
492 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
493 child_impl_
->draw_transform());
494 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
495 grand_child_impl_
->draw_transform());
496 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
497 great_grand_child_impl_
->draw_transform());
499 // Case 4: Bottom-right fixed-position layer.
500 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
502 CommitAndUpdateImplPointers();
503 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
504 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
506 ExecuteCalculateDrawProperties(root_impl_
);
508 // Bottom-right fixed-position layer moves as container resizes.
509 expected_great_grand_child_transform
.MakeIdentity();
510 // explicit canceling out the scroll delta that gets embedded in the fixed
511 // position layer's surface.
512 expected_great_grand_child_transform
.Translate(10.0, 30.0);
513 // Also apply size delta in the child(container) layer space.
514 expected_great_grand_child_transform
.Translate(20.0, 20.0);
515 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
517 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
518 child_impl_
->draw_transform());
519 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
520 grand_child_impl_
->draw_transform());
521 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
522 great_grand_child_impl_
->draw_transform());
525 TEST_F(LayerPositionConstraintTest
,
526 ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces
) {
527 // This test checks for correct scroll compensation when the fixed-position
528 // container contributes to a different render surface than the fixed-position
529 // layer, with additional render surfaces in-between. This checks that the
530 // conversion to ancestor surfaces is accumulated properly in the final matrix
533 // Add one more layer to the test tree for this scenario.
534 scoped_refptr
<Layer
> fixed_position_child
=
535 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
536 SetLayerPropertiesForTesting(fixed_position_child
.get(), gfx::Transform(),
537 gfx::Point3F(), gfx::PointF(),
538 gfx::Size(100, 100), true);
539 great_grand_child_
->AddChild(fixed_position_child
);
541 // Actually set up the scenario here.
542 child_
->SetIsContainerForFixedPositionLayers(true);
543 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
544 grand_child_
->SetForceRenderSurface(true);
545 great_grand_child_
->SetPosition(gfx::PointF(40.f
, 60.f
));
546 great_grand_child_
->SetForceRenderSurface(true);
547 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
549 // The additional rotation, which is non-commutative with translations, helps
550 // to verify that we have correct order-of-operations in the final scroll
551 // compensation. Note that rotating about the center of the layer ensures we
552 // do not accidentally clip away layers that we want to test.
553 gfx::Transform rotation_about_z
;
554 rotation_about_z
.Translate(50.0, 50.0);
555 rotation_about_z
.RotateAboutZAxis(90.0);
556 rotation_about_z
.Translate(-50.0, -50.0);
557 fixed_position_child
->SetTransform(rotation_about_z
);
559 CommitAndUpdateImplPointers();
560 LayerImpl
* fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
562 // Case 1: scroll delta of 0, 0
563 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
564 ExecuteCalculateDrawProperties(root_impl_
);
566 gfx::Transform expected_child_transform
;
568 gfx::Transform expected_grand_child_surface_draw_transform
;
569 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
571 gfx::Transform expected_grand_child_transform
;
573 gfx::Transform expected_great_grand_child_surface_draw_transform
;
574 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
576 gfx::Transform expected_great_grand_child_transform
;
578 gfx::Transform expected_fixed_position_child_transform
;
579 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
581 EXPECT_TRUE(grand_child_impl_
->render_surface());
582 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
583 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
584 child_impl_
->draw_transform());
585 EXPECT_TRANSFORMATION_MATRIX_EQ(
586 expected_grand_child_surface_draw_transform
,
587 grand_child_impl_
->render_surface()->draw_transform());
588 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
589 grand_child_impl_
->draw_transform());
590 EXPECT_TRANSFORMATION_MATRIX_EQ(
591 expected_great_grand_child_surface_draw_transform
,
592 great_grand_child_impl_
->render_surface()->draw_transform());
593 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
594 great_grand_child_impl_
->draw_transform());
595 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
596 fixed_position_child_impl
->draw_transform());
598 // Case 2: scroll delta of 10, 30
599 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
600 ExecuteCalculateDrawProperties(root_impl_
);
602 expected_child_transform
.MakeIdentity();
603 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
605 expected_grand_child_surface_draw_transform
.MakeIdentity();
606 expected_grand_child_surface_draw_transform
.Translate(-10.0,
607 -30.0); // scroll delta
608 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
610 // grand_child, great_grand_child, and great_grand_child's surface are not
611 // expected to change, since they are all not fixed, and they are all drawn
612 // with respect to grand_child's surface that already has the scroll delta
615 // But the great-great grandchild, "fixed_position_child", should have a
616 // transform that explicitly cancels out the scroll delta.
617 expected_fixed_position_child_transform
.MakeIdentity();
618 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
619 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
621 EXPECT_TRUE(grand_child_impl_
->render_surface());
622 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
623 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
624 child_impl_
->draw_transform());
625 EXPECT_TRANSFORMATION_MATRIX_EQ(
626 expected_grand_child_surface_draw_transform
,
627 grand_child_impl_
->render_surface()->draw_transform());
628 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
629 grand_child_impl_
->draw_transform());
630 EXPECT_TRANSFORMATION_MATRIX_EQ(
631 expected_great_grand_child_surface_draw_transform
,
632 great_grand_child_impl_
->render_surface()->draw_transform());
633 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
634 great_grand_child_impl_
->draw_transform());
635 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
636 fixed_position_child_impl
->draw_transform());
638 // Case 3: fixed-container size delta of 20, 20
639 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
640 ExecuteCalculateDrawProperties(root_impl_
);
642 // Top-left fixed-position layer should not be affected by container size.
643 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
644 child_impl_
->draw_transform());
645 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
646 grand_child_impl_
->draw_transform());
647 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
648 great_grand_child_impl_
->draw_transform());
649 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
650 fixed_position_child_impl
->draw_transform());
652 // Case 4: Bottom-right fixed-position layer.
653 fixed_position_child
->SetPositionConstraint(fixed_to_bottom_right_
);
654 CommitAndUpdateImplPointers();
655 fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
656 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
657 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
658 ExecuteCalculateDrawProperties(root_impl_
);
660 // Bottom-right fixed-position layer moves as container resizes.
661 expected_fixed_position_child_transform
.MakeIdentity();
662 // explicit canceling out the scroll delta that gets embedded in the fixed
663 // position layer's surface.
664 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
665 // Also apply size delta in the child(container) layer space.
666 expected_fixed_position_child_transform
.Translate(20.0, 20.0);
667 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
669 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
670 child_impl_
->draw_transform());
671 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
672 grand_child_impl_
->draw_transform());
673 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
674 great_grand_child_impl_
->draw_transform());
675 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
676 fixed_position_child_impl
->draw_transform());
680 LayerPositionConstraintTest
,
681 ScrollCompensationForFixedPositionLayerWithMultipleSurfacesAndTransforms
) {
682 // This test checks for correct scroll compensation when the fixed-position
683 // container contributes to a different render surface than the fixed-position
684 // layer, with additional render surfaces in-between, and the fixed-position
685 // container is transformed. This checks that the conversion to ancestor
686 // surfaces is accumulated properly in the final matrix transform.
688 // Add one more layer to the test tree for this scenario.
689 scoped_refptr
<Layer
> fixed_position_child
=
690 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
691 SetLayerPropertiesForTesting(fixed_position_child
.get(), gfx::Transform(),
692 gfx::Point3F(), gfx::PointF(),
693 gfx::Size(100, 100), true);
694 great_grand_child_
->AddChild(fixed_position_child
);
696 // Actually set up the scenario here.
697 child_transform_layer_
->SetIsContainerForFixedPositionLayers(true);
698 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
699 grand_child_
->SetForceRenderSurface(true);
700 great_grand_child_
->SetPosition(gfx::PointF(40.f
, 60.f
));
701 great_grand_child_
->SetForceRenderSurface(true);
702 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
704 // The additional rotations, which are non-commutative with translations, help
705 // to verify that we have correct order-of-operations in the final scroll
706 // compensation. Note that rotating about the center of the layer ensures we
707 // do not accidentally clip away layers that we want to test.
708 gfx::Transform rotation_about_z
;
709 rotation_about_z
.Translate(50.0, 50.0);
710 rotation_about_z
.RotateAboutZAxis(90.0);
711 rotation_about_z
.Translate(-50.0, -50.0);
712 child_transform_layer_
->SetTransform(rotation_about_z
);
713 fixed_position_child
->SetTransform(rotation_about_z
);
715 CommitAndUpdateImplPointers();
716 LayerImpl
* fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
718 // Case 1: scroll delta of 0, 0
719 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
720 ExecuteCalculateDrawProperties(root_impl_
);
722 gfx::Transform expected_child_transform
;
723 expected_child_transform
.PreconcatTransform(rotation_about_z
);
725 gfx::Transform expected_grand_child_surface_draw_transform
;
726 expected_grand_child_surface_draw_transform
.PreconcatTransform(
728 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
730 gfx::Transform expected_grand_child_transform
;
732 gfx::Transform expected_great_grand_child_surface_draw_transform
;
733 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
735 gfx::Transform expected_great_grand_child_transform
;
737 gfx::Transform expected_fixed_position_child_transform
;
738 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
740 EXPECT_TRUE(grand_child_impl_
->render_surface());
741 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
742 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
743 child_impl_
->draw_transform());
744 EXPECT_TRANSFORMATION_MATRIX_EQ(
745 expected_grand_child_surface_draw_transform
,
746 grand_child_impl_
->render_surface()->draw_transform());
747 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
748 grand_child_impl_
->draw_transform());
749 EXPECT_TRANSFORMATION_MATRIX_EQ(
750 expected_great_grand_child_surface_draw_transform
,
751 great_grand_child_impl_
->render_surface()->draw_transform());
752 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
753 great_grand_child_impl_
->draw_transform());
754 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
755 fixed_position_child_impl
->draw_transform());
757 // Case 2: scroll delta of 10, 30
758 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
759 ExecuteCalculateDrawProperties(root_impl_
);
761 expected_child_transform
.MakeIdentity();
762 expected_child_transform
.PreconcatTransform(rotation_about_z
);
763 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
765 expected_grand_child_surface_draw_transform
.MakeIdentity();
766 expected_grand_child_surface_draw_transform
.PreconcatTransform(
768 expected_grand_child_surface_draw_transform
.Translate(-10.0,
769 -30.0); // scroll delta
770 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
772 // grand_child, great_grand_child, and great_grand_child's surface are not
773 // expected to change, since they are all not fixed, and they are all drawn
774 // with respect to grand_child's surface that already has the scroll delta
777 // But the great-great grandchild, "fixed_position_child", should have a
778 // transform that explicitly cancels out the scroll delta.
779 expected_fixed_position_child_transform
.MakeIdentity();
780 // explicit canceling out the scroll delta that gets embedded in the fixed
781 // position layer's surface.
782 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
783 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
785 EXPECT_TRUE(grand_child_impl_
->render_surface());
786 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
787 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
788 child_impl_
->draw_transform());
789 EXPECT_TRANSFORMATION_MATRIX_EQ(
790 expected_grand_child_surface_draw_transform
,
791 grand_child_impl_
->render_surface()->draw_transform());
792 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
793 grand_child_impl_
->draw_transform());
794 EXPECT_TRANSFORMATION_MATRIX_EQ(
795 expected_great_grand_child_surface_draw_transform
,
796 great_grand_child_impl_
->render_surface()->draw_transform());
797 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
798 great_grand_child_impl_
->draw_transform());
799 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
800 fixed_position_child_impl
->draw_transform());
803 TEST_F(LayerPositionConstraintTest
,
804 ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface
) {
805 // This test checks for correct scroll compensation when the fixed-position
806 // container itself has a render surface. In this case, the container layer
807 // should be treated like a layer that contributes to a render target, and
808 // that render target is completely irrelevant; it should not affect the
809 // scroll compensation.
810 child_
->SetIsContainerForFixedPositionLayers(true);
811 child_
->SetForceRenderSurface(true);
812 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
814 CommitAndUpdateImplPointers();
816 // Case 1: scroll delta of 0, 0
817 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
818 ExecuteCalculateDrawProperties(root_impl_
);
820 gfx::Transform expected_surface_draw_transform
;
821 gfx::Transform expected_child_transform
;
822 gfx::Transform expected_grand_child_transform
;
823 EXPECT_TRUE(child_impl_
->render_surface());
824 EXPECT_TRANSFORMATION_MATRIX_EQ(
825 expected_surface_draw_transform
,
826 child_impl_
->render_surface()->draw_transform());
827 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
828 child_impl_
->draw_transform());
829 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
830 grand_child_impl_
->draw_transform());
832 // Case 2: scroll delta of 10, 10
833 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
834 ExecuteCalculateDrawProperties(root_impl_
);
836 // The surface is translated by scroll delta, the child transform doesn't
837 // change because it scrolls along with the surface, but the fixed position
838 // grand_child needs to compensate for the scroll translation.
839 expected_surface_draw_transform
.MakeIdentity();
840 expected_surface_draw_transform
.Translate(-10.0, -10.0);
841 expected_grand_child_transform
.MakeIdentity();
842 expected_grand_child_transform
.Translate(10.0, 10.0);
844 EXPECT_TRUE(child_impl_
->render_surface());
845 EXPECT_TRANSFORMATION_MATRIX_EQ(
846 expected_surface_draw_transform
,
847 child_impl_
->render_surface()->draw_transform());
848 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
849 child_impl_
->draw_transform());
850 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
851 grand_child_impl_
->draw_transform());
853 // Case 3: fixed-container size delta of 20, 20
854 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
855 ExecuteCalculateDrawProperties(root_impl_
);
857 // Top-left fixed-position layer should not be affected by container size.
858 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
859 child_impl_
->draw_transform());
860 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
861 grand_child_impl_
->draw_transform());
863 // Case 4: Bottom-right fixed-position layer.
864 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
865 CommitAndUpdateImplPointers();
866 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
867 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
868 ExecuteCalculateDrawProperties(root_impl_
);
870 // Bottom-right fixed-position layer moves as container resizes.
871 expected_grand_child_transform
.MakeIdentity();
872 // The surface is translated by scroll delta, the child transform doesn't
873 // change because it scrolls along with the surface, but the fixed position
874 // grand_child needs to compensate for the scroll translation.
875 expected_grand_child_transform
.Translate(10.0, 10.0);
876 // Apply size delta from the child(container) layer.
877 expected_grand_child_transform
.Translate(20.0, 20.0);
879 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
880 child_impl_
->draw_transform());
881 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
882 grand_child_impl_
->draw_transform());
885 TEST_F(LayerPositionConstraintTest
,
886 ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer
) {
887 // This test checks the scenario where a fixed-position layer also happens to
888 // be a container itself for a descendant fixed position layer. In particular,
889 // the layer should not accidentally be fixed to itself.
890 child_
->SetIsContainerForFixedPositionLayers(true);
891 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
893 // This should not confuse the grand_child. If correct, the grand_child would
894 // still be considered fixed to its container (i.e. "child").
895 grand_child_
->SetIsContainerForFixedPositionLayers(true);
897 CommitAndUpdateImplPointers();
899 // Case 1: scroll delta of 0, 0
900 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
901 ExecuteCalculateDrawProperties(root_impl_
);
903 gfx::Transform expected_child_transform
;
904 gfx::Transform expected_grand_child_transform
;
905 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
906 child_impl_
->draw_transform());
907 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
908 grand_child_impl_
->draw_transform());
910 // Case 2: scroll delta of 10, 10
911 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
912 ExecuteCalculateDrawProperties(root_impl_
);
914 // Here the child is affected by scroll delta, but the fixed position
915 // grand_child should not be affected.
916 expected_child_transform
.MakeIdentity();
917 expected_child_transform
.Translate(-10.0, -10.0);
918 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
919 child_impl_
->draw_transform());
920 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
921 grand_child_impl_
->draw_transform());
923 // Case 3: fixed-container size delta of 20, 20
924 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
925 ExecuteCalculateDrawProperties(root_impl_
);
927 // Top-left fixed-position layer should not be affected by container size.
928 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
929 child_impl_
->draw_transform());
930 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
931 grand_child_impl_
->draw_transform());
933 // Case 4: Bottom-right fixed-position layer.
934 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
935 CommitAndUpdateImplPointers();
936 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
937 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
939 ExecuteCalculateDrawProperties(root_impl_
);
941 // Bottom-right fixed-position layer moves as container resizes.
942 expected_grand_child_transform
.MakeIdentity();
943 // Apply size delta from the child(container) layer.
944 expected_grand_child_transform
.Translate(20.0, 20.0);
946 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
947 child_impl_
->draw_transform());
948 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
949 grand_child_impl_
->draw_transform());
952 TEST_F(LayerPositionConstraintTest
,
953 ScrollCompensationForFixedWithinFixedWithSameContainer
) {
954 // This test checks scroll compensation for a fixed-position layer that is
955 // inside of another fixed-position layer and both share the same container.
956 // In this situation, the parent fixed-position layer will receive
957 // the scroll compensation, and the child fixed-position layer does not
958 // need to compensate further.
959 child_
->SetIsContainerForFixedPositionLayers(true);
960 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
962 // Note carefully - great_grand_child is fixed to bottom right, to test
963 // sizeDelta being applied correctly; the compensation skips the grand_child
964 // because it is fixed to top left.
965 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
967 CommitAndUpdateImplPointers();
969 // Case 1: scrollDelta
970 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
971 ExecuteCalculateDrawProperties(root_impl_
);
973 // Here the child is affected by scroll delta, but the fixed position
974 // grand_child should not be affected.
975 gfx::Transform expected_child_transform
;
976 expected_child_transform
.Translate(-10.0, -10.0);
978 gfx::Transform expected_grand_child_transform
;
979 gfx::Transform expected_great_grand_child_transform
;
981 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
982 child_impl_
->draw_transform());
983 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
984 grand_child_impl_
->draw_transform());
985 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
986 great_grand_child_impl_
->draw_transform());
989 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
990 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
991 ExecuteCalculateDrawProperties(root_impl_
);
993 expected_child_transform
.MakeIdentity();
995 expected_grand_child_transform
.MakeIdentity();
997 // Fixed to bottom-right, size-delta compensation is applied.
998 expected_great_grand_child_transform
.MakeIdentity();
999 expected_great_grand_child_transform
.Translate(20.0, 20.0);
1001 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1002 child_impl_
->draw_transform());
1003 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1004 grand_child_impl_
->draw_transform());
1005 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
1006 great_grand_child_impl_
->draw_transform());
1009 TEST_F(LayerPositionConstraintTest
,
1010 ScrollCompensationForFixedWithinFixedWithInterveningContainer
) {
1011 // This test checks scroll compensation for a fixed-position layer that is
1012 // inside of another fixed-position layer, but they have different fixed
1013 // position containers. In this situation, the child fixed-position element
1014 // would still have to compensate with respect to its container.
1016 // Add one more layer to the hierarchy for this test.
1017 scoped_refptr
<Layer
> great_great_grand_child
=
1018 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
1019 great_grand_child_
->AddChild(great_great_grand_child
);
1021 child_
->SetIsContainerForFixedPositionLayers(true);
1022 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
1023 great_grand_child_
->SetIsContainerForFixedPositionLayers(true);
1024 great_grand_child_
->SetScrollClipLayerId(root_
->id());
1025 great_great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
1027 CommitAndUpdateImplPointers();
1029 LayerImpl
* container1
= child_impl_
;
1030 LayerImpl
* fixed_to_container1
= grand_child_impl_
;
1031 LayerImpl
* container2
= great_grand_child_impl_
;
1032 LayerImpl
* fixed_to_container2
= container2
->children()[0];
1034 container1
->SetScrollDelta(gfx::Vector2d(0, 15));
1035 container2
->SetScrollDelta(gfx::Vector2d(30, 0));
1036 ExecuteCalculateDrawProperties(root_impl_
);
1038 gfx::Transform expected_container1_transform
;
1039 expected_container1_transform
.Translate(0.0, -15.0);
1041 gfx::Transform expected_fixed_to_container1_transform
;
1043 // Since the container is a descendant of the fixed layer above,
1044 // the expected draw transform for container2 would not
1045 // include the scrollDelta that was applied to container1.
1046 gfx::Transform expected_container2_transform
;
1047 expected_container2_transform
.Translate(-30.0, 0.0);
1049 gfx::Transform expected_fixed_to_container2_transform
;
1051 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform
,
1052 container1
->draw_transform());
1054 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform
,
1055 fixed_to_container1
->draw_transform());
1057 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform
,
1058 container2
->draw_transform());
1060 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform
,
1061 fixed_to_container2
->draw_transform());
1064 TEST_F(LayerPositionConstraintTest
,
1065 ScrollCompensationForInnerViewportBoundsDelta
) {
1066 // This test checks for correct scroll compensation when the fixed-position
1067 // container is the inner viewport scroll layer and has non-zero bounds delta.
1068 scoped_refptr
<Layer
> fixed_child
=
1069 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
1070 fixed_child
->SetBounds(gfx::Size(300, 300));
1071 scroll_layer_
->AddChild(fixed_child
);
1072 fixed_child
->SetPositionConstraint(fixed_to_top_left_
);
1074 CommitAndUpdateImplPointers();
1076 LayerImpl
* fixed_child_impl
=
1077 root_impl_
->layer_tree_impl()->FindActiveTreeLayerById(fixed_child
->id());
1079 // Case 1: fixed-container size delta of 20, 20
1080 scroll_layer_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
1081 SetFixedContainerSizeDelta(scroll_layer_impl_
, gfx::Vector2d(20, 20));
1082 gfx::Transform expected_scroll_layer_transform
;
1083 expected_scroll_layer_transform
.Translate(-10.0, -10.0);
1084 gfx::Transform expected_fixed_child_transform
;
1086 ExecuteCalculateDrawProperties(root_impl_
);
1088 // Top-left fixed-position layer should not be affected by container size.
1089 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform
,
1090 scroll_layer_impl_
->draw_transform());
1091 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform
,
1092 fixed_child_impl
->draw_transform());
1094 // Case 2: Bottom-right fixed-position layer.
1095 fixed_child
->SetPositionConstraint(fixed_to_bottom_right_
);
1096 CommitAndUpdateImplPointers();
1098 root_impl_
->layer_tree_impl()->FindActiveTreeLayerById(fixed_child
->id());
1100 scroll_layer_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
1101 SetFixedContainerSizeDelta(scroll_layer_impl_
, gfx::Vector2d(20, 20));
1102 ExecuteCalculateDrawProperties(root_impl_
);
1104 // Bottom-right fixed-position layer moves as container resizes.
1105 expected_fixed_child_transform
.MakeIdentity();
1106 // Apply size delta.
1107 expected_fixed_child_transform
.Translate(20.0, 20.0);
1109 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform
,
1110 scroll_layer_impl_
->draw_transform());
1111 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform
,
1112 fixed_child_impl
->draw_transform());