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 RenderSurfaceLayerList render_surface_layer_list
;
140 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
141 root_
.get(), root_
->bounds(), &render_surface_layer_list
);
142 inputs
.inner_viewport_scroll_layer
=
143 layer_tree_host_
->inner_viewport_scroll_layer();
144 inputs
.outer_viewport_scroll_layer
=
145 layer_tree_host_
->outer_viewport_scroll_layer();
146 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
148 // Since scroll deltas aren't sent back to the main thread in this test
149 // setup, clear them to maintain consistent state.
151 scroll_layer_impl_
->SetScrollDelta(gfx::Vector2dF());
152 child_impl_
->SetScrollDelta(gfx::Vector2dF());
153 grand_child_impl_
->SetScrollDelta(gfx::Vector2dF());
155 root_impl_
= layer_tree_host_
->CommitAndCreateLayerImplTree();
156 inner_viewport_container_layer_impl_
= root_impl_
->children()[0];
157 scroll_layer_impl_
= inner_viewport_container_layer_impl_
->children()[0];
158 outer_viewport_container_layer_impl_
= scroll_layer_impl_
->children()[0];
159 child_transform_layer_impl_
=
160 outer_viewport_container_layer_impl_
->children()[0];
161 child_impl_
= child_transform_layer_impl_
->children()[0];
162 grand_child_impl_
= child_impl_
->children()[0];
163 great_grand_child_impl_
= grand_child_impl_
->children()[0];
167 FakeLayerTreeHostClient fake_client_
;
168 TestTaskGraphRunner task_graph_runner_
;
169 scoped_ptr
<FakeLayerTreeHost
> layer_tree_host_
;
170 LayerSettings layer_settings_
;
171 scoped_refptr
<Layer
> root_
;
172 scoped_refptr
<Layer
> inner_viewport_container_layer_
;
173 scoped_refptr
<Layer
> scroll_layer_
;
174 scoped_refptr
<Layer
> outer_viewport_container_layer_
;
175 scoped_refptr
<Layer
> child_transform_layer_
;
176 scoped_refptr
<Layer
> child_
;
177 scoped_refptr
<Layer
> grand_child_
;
178 scoped_refptr
<Layer
> great_grand_child_
;
179 LayerImpl
* root_impl_
;
180 LayerImpl
* inner_viewport_container_layer_impl_
;
181 LayerImpl
* scroll_layer_impl_
;
182 LayerImpl
* outer_viewport_container_layer_impl_
;
183 LayerImpl
* child_transform_layer_impl_
;
184 LayerImpl
* child_impl_
;
185 LayerImpl
* grand_child_impl_
;
186 LayerImpl
* great_grand_child_impl_
;
188 LayerPositionConstraint fixed_to_top_left_
;
189 LayerPositionConstraint fixed_to_bottom_right_
;
194 void SetFixedContainerSizeDelta(LayerImpl
* scroll_layer
,
195 const gfx::Vector2d
& delta
) {
196 DCHECK(scroll_layer
);
197 DCHECK(scroll_layer
->scrollable());
199 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
200 container_layer
->SetBoundsDelta(delta
);
204 TEST_F(LayerPositionConstraintTest
,
205 ScrollCompensationForFixedPositionLayerWithDirectContainer
) {
206 // This test checks for correct scroll compensation when the fixed-position
207 // container is the direct parent of the fixed-position layer.
208 child_
->SetIsContainerForFixedPositionLayers(true);
209 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
211 CommitAndUpdateImplPointers();
213 // Case 1: scroll delta of 0, 0
214 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
215 ExecuteCalculateDrawProperties(root_impl_
);
217 gfx::Transform expected_child_transform
;
218 gfx::Transform expected_grand_child_transform
= expected_child_transform
;
220 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
221 child_impl_
->draw_transform());
222 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
223 grand_child_impl_
->draw_transform());
225 // Case 2: scroll delta of 10, 10
226 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
227 ExecuteCalculateDrawProperties(root_impl_
);
229 // Here the child is affected by scroll delta, but the fixed position
230 // grand_child should not be affected.
231 expected_child_transform
.MakeIdentity();
232 expected_child_transform
.Translate(-10.0, -10.0);
234 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
235 child_impl_
->draw_transform());
236 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
237 grand_child_impl_
->draw_transform());
239 // Case 3: fixed-container size delta of 20, 20
240 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
241 ExecuteCalculateDrawProperties(root_impl_
);
243 // Top-left fixed-position layer should not be affected by container size.
244 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
245 child_impl_
->draw_transform());
246 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
247 grand_child_impl_
->draw_transform());
249 // Case 4: Bottom-right fixed-position layer.
250 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
251 CommitAndUpdateImplPointers();
253 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
254 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
255 ExecuteCalculateDrawProperties(root_impl_
);
257 // Bottom-right fixed-position layer moves as container resizes.
258 expected_grand_child_transform
.MakeIdentity();
259 // Apply size delta from the child(container) layer.
260 expected_grand_child_transform
.Translate(20.0, 20.0);
262 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
263 child_impl_
->draw_transform());
264 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
265 grand_child_impl_
->draw_transform());
268 TEST_F(LayerPositionConstraintTest
,
269 ScrollCompensationForFixedPositionLayerWithDistantContainer
) {
270 // This test checks for correct scroll compensation when the fixed-position
271 // container is NOT the direct parent of the fixed-position layer.
272 child_
->SetIsContainerForFixedPositionLayers(true);
273 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
274 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
276 CommitAndUpdateImplPointers();
278 // Case 1: scroll delta of 0, 0
279 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
280 ExecuteCalculateDrawProperties(root_impl_
);
282 gfx::Transform expected_child_transform
;
283 gfx::Transform expected_grand_child_transform
;
284 expected_grand_child_transform
.Translate(8.0, 6.0);
286 gfx::Transform expected_great_grand_child_transform
=
287 expected_grand_child_transform
;
289 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
290 child_impl_
->draw_transform());
291 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
292 grand_child_impl_
->draw_transform());
293 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
294 great_grand_child_impl_
->draw_transform());
296 // Case 2: scroll delta of 10, 10
297 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
298 ExecuteCalculateDrawProperties(root_impl_
);
300 // Here the child and grand_child are affected by scroll delta, but the fixed
301 // position great_grand_child should not be affected.
302 expected_child_transform
.MakeIdentity();
303 expected_child_transform
.Translate(-10.0, -10.0);
304 expected_grand_child_transform
.MakeIdentity();
305 expected_grand_child_transform
.Translate(-2.0, -4.0);
306 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
307 child_impl_
->draw_transform());
308 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
309 grand_child_impl_
->draw_transform());
310 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
311 great_grand_child_impl_
->draw_transform());
313 // Case 3: fixed-container size delta of 20, 20
314 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
315 ExecuteCalculateDrawProperties(root_impl_
);
317 // Top-left fixed-position layer should not be affected by container size.
318 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
319 child_impl_
->draw_transform());
320 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
321 grand_child_impl_
->draw_transform());
322 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
323 great_grand_child_impl_
->draw_transform());
325 // Case 4: Bottom-right fixed-position layer.
326 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
327 CommitAndUpdateImplPointers();
328 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
329 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
330 ExecuteCalculateDrawProperties(root_impl_
);
332 // Bottom-right fixed-position layer moves as container resizes.
333 expected_great_grand_child_transform
.MakeIdentity();
334 // Apply size delta from the child(container) layer.
335 expected_great_grand_child_transform
.Translate(20.0, 20.0);
336 // Apply layer position from the grand child layer.
337 expected_great_grand_child_transform
.Translate(8.0, 6.0);
339 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
340 child_impl_
->draw_transform());
341 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
342 grand_child_impl_
->draw_transform());
343 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
344 great_grand_child_impl_
->draw_transform());
347 TEST_F(LayerPositionConstraintTest
,
348 ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas
) {
349 // This test checks for correct scroll compensation when the fixed-position
350 // container has multiple ancestors that have nonzero scroll delta before
351 // reaching the space where the layer is fixed.
352 gfx::Transform rotation_about_z
;
353 rotation_about_z
.RotateAboutZAxis(90.0);
355 child_transform_layer_
->SetIsContainerForFixedPositionLayers(true);
356 child_transform_layer_
->SetTransform(rotation_about_z
);
357 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
358 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
360 CommitAndUpdateImplPointers();
362 // Case 1: scroll delta of 0, 0
363 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
364 ExecuteCalculateDrawProperties(root_impl_
);
366 gfx::Transform expected_child_transform
;
367 expected_child_transform
.PreconcatTransform(rotation_about_z
);
369 gfx::Transform expected_grand_child_transform
;
370 expected_grand_child_transform
.PreconcatTransform(
371 rotation_about_z
); // child's local transform is inherited
372 // translation because of position occurs before layer's local transform.
373 expected_grand_child_transform
.Translate(8.0, 6.0);
375 gfx::Transform expected_great_grand_child_transform
=
376 expected_grand_child_transform
;
378 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
379 child_impl_
->draw_transform());
380 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
381 grand_child_impl_
->draw_transform());
382 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
383 great_grand_child_impl_
->draw_transform());
385 // Case 2: scroll delta of 10, 20
386 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 0));
387 grand_child_impl_
->SetScrollDelta(gfx::Vector2d(5, 0));
388 ExecuteCalculateDrawProperties(root_impl_
);
390 // Here the child and grand_child are affected by scroll delta, but the fixed
391 // position great_grand_child should not be affected.
392 expected_child_transform
.MakeIdentity();
393 expected_child_transform
.PreconcatTransform(rotation_about_z
);
394 expected_child_transform
.Translate(-10.0, 0.0); // scroll delta
396 expected_grand_child_transform
.MakeIdentity();
397 expected_grand_child_transform
.PreconcatTransform(
398 rotation_about_z
); // child's local transform is inherited
399 expected_grand_child_transform
.Translate(
400 -10.0, 0.0); // child's scroll delta is inherited
401 expected_grand_child_transform
.Translate(-5.0,
402 0.0); // grand_child's scroll delta
403 // translation because of position
404 expected_grand_child_transform
.Translate(8.0, 6.0);
406 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
407 child_impl_
->draw_transform());
408 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
409 grand_child_impl_
->draw_transform());
410 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
411 great_grand_child_impl_
->draw_transform());
414 TEST_F(LayerPositionConstraintTest
,
415 ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms
) {
416 // This test checks for correct scroll compensation when the fixed-position
417 // container contributes to a different render surface than the fixed-position
418 // layer. In this case, the surface draw transforms also have to be accounted
419 // for when checking the scroll delta.
420 child_
->SetIsContainerForFixedPositionLayers(true);
421 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
422 grand_child_
->SetForceRenderSurface(true);
423 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
425 gfx::Transform rotation_about_z
;
426 rotation_about_z
.RotateAboutZAxis(90.0);
427 great_grand_child_
->SetTransform(rotation_about_z
);
429 CommitAndUpdateImplPointers();
431 // Case 1: scroll delta of 0, 0
432 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
433 ExecuteCalculateDrawProperties(root_impl_
);
435 gfx::Transform expected_child_transform
;
436 gfx::Transform expected_surface_draw_transform
;
437 expected_surface_draw_transform
.Translate(8.0, 6.0);
438 gfx::Transform expected_grand_child_transform
;
439 gfx::Transform expected_great_grand_child_transform
;
440 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
441 EXPECT_TRUE(grand_child_impl_
->render_surface());
442 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
443 child_impl_
->draw_transform());
444 EXPECT_TRANSFORMATION_MATRIX_EQ(
445 expected_surface_draw_transform
,
446 grand_child_impl_
->render_surface()->draw_transform());
447 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
448 grand_child_impl_
->draw_transform());
449 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
450 great_grand_child_impl_
->draw_transform());
452 // Case 2: scroll delta of 10, 30
453 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
454 ExecuteCalculateDrawProperties(root_impl_
);
456 // Here the grand_child remains unchanged, because it scrolls along with the
457 // render surface, and the translation is actually in the render surface. But,
458 // the fixed position great_grand_child is more awkward: its actually being
459 // drawn with respect to the render surface, but it needs to remain fixed with
460 // resepct to a container beyond that surface. So, the net result is that,
461 // unlike previous tests where the fixed position layer's transform remains
462 // unchanged, here the fixed position layer's transform explicitly contains
463 // the translation that cancels out the scroll.
464 expected_child_transform
.MakeIdentity();
465 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
467 expected_surface_draw_transform
.MakeIdentity();
468 expected_surface_draw_transform
.Translate(-10.0, -30.0); // scroll delta
469 expected_surface_draw_transform
.Translate(8.0, 6.0);
471 expected_great_grand_child_transform
.MakeIdentity();
472 // explicit canceling out the scroll delta that gets embedded in the fixed
473 // position layer's surface.
474 expected_great_grand_child_transform
.Translate(10.0, 30.0);
475 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
477 EXPECT_TRUE(grand_child_impl_
->render_surface());
478 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
479 child_impl_
->draw_transform());
480 EXPECT_TRANSFORMATION_MATRIX_EQ(
481 expected_surface_draw_transform
,
482 grand_child_impl_
->render_surface()->draw_transform());
483 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
484 grand_child_impl_
->draw_transform());
485 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
486 great_grand_child_impl_
->draw_transform());
488 // Case 3: fixed-container size delta of 20, 20
489 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
490 ExecuteCalculateDrawProperties(root_impl_
);
492 // Top-left fixed-position layer should not be affected by container size.
493 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
494 child_impl_
->draw_transform());
495 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
496 grand_child_impl_
->draw_transform());
497 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
498 great_grand_child_impl_
->draw_transform());
500 // Case 4: Bottom-right fixed-position layer.
501 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
503 CommitAndUpdateImplPointers();
504 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
505 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
507 ExecuteCalculateDrawProperties(root_impl_
);
509 // Bottom-right fixed-position layer moves as container resizes.
510 expected_great_grand_child_transform
.MakeIdentity();
511 // explicit canceling out the scroll delta that gets embedded in the fixed
512 // position layer's surface.
513 expected_great_grand_child_transform
.Translate(10.0, 30.0);
514 // Also apply size delta in the child(container) layer space.
515 expected_great_grand_child_transform
.Translate(20.0, 20.0);
516 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
518 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
519 child_impl_
->draw_transform());
520 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
521 grand_child_impl_
->draw_transform());
522 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
523 great_grand_child_impl_
->draw_transform());
526 TEST_F(LayerPositionConstraintTest
,
527 ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces
) {
528 // This test checks for correct scroll compensation when the fixed-position
529 // container contributes to a different render surface than the fixed-position
530 // layer, with additional render surfaces in-between. This checks that the
531 // conversion to ancestor surfaces is accumulated properly in the final matrix
534 // Add one more layer to the test tree for this scenario.
535 scoped_refptr
<Layer
> fixed_position_child
=
536 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
537 SetLayerPropertiesForTesting(fixed_position_child
.get(), gfx::Transform(),
538 gfx::Point3F(), gfx::PointF(),
539 gfx::Size(100, 100), true);
540 great_grand_child_
->AddChild(fixed_position_child
);
542 // Actually set up the scenario here.
543 child_
->SetIsContainerForFixedPositionLayers(true);
544 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
545 grand_child_
->SetForceRenderSurface(true);
546 great_grand_child_
->SetPosition(gfx::PointF(40.f
, 60.f
));
547 great_grand_child_
->SetForceRenderSurface(true);
548 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
550 // The additional rotation, which is non-commutative with translations, helps
551 // to verify that we have correct order-of-operations in the final scroll
552 // compensation. Note that rotating about the center of the layer ensures we
553 // do not accidentally clip away layers that we want to test.
554 gfx::Transform rotation_about_z
;
555 rotation_about_z
.Translate(50.0, 50.0);
556 rotation_about_z
.RotateAboutZAxis(90.0);
557 rotation_about_z
.Translate(-50.0, -50.0);
558 fixed_position_child
->SetTransform(rotation_about_z
);
560 CommitAndUpdateImplPointers();
561 LayerImpl
* fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
563 // Case 1: scroll delta of 0, 0
564 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
565 ExecuteCalculateDrawProperties(root_impl_
);
567 gfx::Transform expected_child_transform
;
569 gfx::Transform expected_grand_child_surface_draw_transform
;
570 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
572 gfx::Transform expected_grand_child_transform
;
574 gfx::Transform expected_great_grand_child_surface_draw_transform
;
575 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
577 gfx::Transform expected_great_grand_child_transform
;
579 gfx::Transform expected_fixed_position_child_transform
;
580 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
582 EXPECT_TRUE(grand_child_impl_
->render_surface());
583 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
584 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
585 child_impl_
->draw_transform());
586 EXPECT_TRANSFORMATION_MATRIX_EQ(
587 expected_grand_child_surface_draw_transform
,
588 grand_child_impl_
->render_surface()->draw_transform());
589 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
590 grand_child_impl_
->draw_transform());
591 EXPECT_TRANSFORMATION_MATRIX_EQ(
592 expected_great_grand_child_surface_draw_transform
,
593 great_grand_child_impl_
->render_surface()->draw_transform());
594 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
595 great_grand_child_impl_
->draw_transform());
596 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
597 fixed_position_child_impl
->draw_transform());
599 // Case 2: scroll delta of 10, 30
600 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
601 ExecuteCalculateDrawProperties(root_impl_
);
603 expected_child_transform
.MakeIdentity();
604 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
606 expected_grand_child_surface_draw_transform
.MakeIdentity();
607 expected_grand_child_surface_draw_transform
.Translate(-10.0,
608 -30.0); // scroll delta
609 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
611 // grand_child, great_grand_child, and great_grand_child's surface are not
612 // expected to change, since they are all not fixed, and they are all drawn
613 // with respect to grand_child's surface that already has the scroll delta
616 // But the great-great grandchild, "fixed_position_child", should have a
617 // transform that explicitly cancels out the scroll delta.
618 expected_fixed_position_child_transform
.MakeIdentity();
619 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
620 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
622 EXPECT_TRUE(grand_child_impl_
->render_surface());
623 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
624 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
625 child_impl_
->draw_transform());
626 EXPECT_TRANSFORMATION_MATRIX_EQ(
627 expected_grand_child_surface_draw_transform
,
628 grand_child_impl_
->render_surface()->draw_transform());
629 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
630 grand_child_impl_
->draw_transform());
631 EXPECT_TRANSFORMATION_MATRIX_EQ(
632 expected_great_grand_child_surface_draw_transform
,
633 great_grand_child_impl_
->render_surface()->draw_transform());
634 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
635 great_grand_child_impl_
->draw_transform());
636 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
637 fixed_position_child_impl
->draw_transform());
639 // Case 3: fixed-container size delta of 20, 20
640 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
641 ExecuteCalculateDrawProperties(root_impl_
);
643 // Top-left fixed-position layer should not be affected by container size.
644 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
645 child_impl_
->draw_transform());
646 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
647 grand_child_impl_
->draw_transform());
648 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
649 great_grand_child_impl_
->draw_transform());
650 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
651 fixed_position_child_impl
->draw_transform());
653 // Case 4: Bottom-right fixed-position layer.
654 fixed_position_child
->SetPositionConstraint(fixed_to_bottom_right_
);
655 CommitAndUpdateImplPointers();
656 fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
657 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
658 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
659 ExecuteCalculateDrawProperties(root_impl_
);
661 // Bottom-right fixed-position layer moves as container resizes.
662 expected_fixed_position_child_transform
.MakeIdentity();
663 // explicit canceling out the scroll delta that gets embedded in the fixed
664 // position layer's surface.
665 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
666 // Also apply size delta in the child(container) layer space.
667 expected_fixed_position_child_transform
.Translate(20.0, 20.0);
668 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
670 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
671 child_impl_
->draw_transform());
672 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
673 grand_child_impl_
->draw_transform());
674 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
675 great_grand_child_impl_
->draw_transform());
676 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
677 fixed_position_child_impl
->draw_transform());
681 LayerPositionConstraintTest
,
682 ScrollCompensationForFixedPositionLayerWithMultipleSurfacesAndTransforms
) {
683 // This test checks for correct scroll compensation when the fixed-position
684 // container contributes to a different render surface than the fixed-position
685 // layer, with additional render surfaces in-between, and the fixed-position
686 // container is transformed. This checks that the conversion to ancestor
687 // surfaces is accumulated properly in the final matrix transform.
689 // Add one more layer to the test tree for this scenario.
690 scoped_refptr
<Layer
> fixed_position_child
=
691 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
692 SetLayerPropertiesForTesting(fixed_position_child
.get(), gfx::Transform(),
693 gfx::Point3F(), gfx::PointF(),
694 gfx::Size(100, 100), true);
695 great_grand_child_
->AddChild(fixed_position_child
);
697 // Actually set up the scenario here.
698 child_transform_layer_
->SetIsContainerForFixedPositionLayers(true);
699 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
700 grand_child_
->SetForceRenderSurface(true);
701 great_grand_child_
->SetPosition(gfx::PointF(40.f
, 60.f
));
702 great_grand_child_
->SetForceRenderSurface(true);
703 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
705 // The additional rotations, which are non-commutative with translations, help
706 // to verify that we have correct order-of-operations in the final scroll
707 // compensation. Note that rotating about the center of the layer ensures we
708 // do not accidentally clip away layers that we want to test.
709 gfx::Transform rotation_about_z
;
710 rotation_about_z
.Translate(50.0, 50.0);
711 rotation_about_z
.RotateAboutZAxis(90.0);
712 rotation_about_z
.Translate(-50.0, -50.0);
713 child_transform_layer_
->SetTransform(rotation_about_z
);
714 fixed_position_child
->SetTransform(rotation_about_z
);
716 CommitAndUpdateImplPointers();
717 LayerImpl
* fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
719 // Case 1: scroll delta of 0, 0
720 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
721 ExecuteCalculateDrawProperties(root_impl_
);
723 gfx::Transform expected_child_transform
;
724 expected_child_transform
.PreconcatTransform(rotation_about_z
);
726 gfx::Transform expected_grand_child_surface_draw_transform
;
727 expected_grand_child_surface_draw_transform
.PreconcatTransform(
729 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
731 gfx::Transform expected_grand_child_transform
;
733 gfx::Transform expected_great_grand_child_surface_draw_transform
;
734 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
736 gfx::Transform expected_great_grand_child_transform
;
738 gfx::Transform expected_fixed_position_child_transform
;
739 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
741 EXPECT_TRUE(grand_child_impl_
->render_surface());
742 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
743 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
744 child_impl_
->draw_transform());
745 EXPECT_TRANSFORMATION_MATRIX_EQ(
746 expected_grand_child_surface_draw_transform
,
747 grand_child_impl_
->render_surface()->draw_transform());
748 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
749 grand_child_impl_
->draw_transform());
750 EXPECT_TRANSFORMATION_MATRIX_EQ(
751 expected_great_grand_child_surface_draw_transform
,
752 great_grand_child_impl_
->render_surface()->draw_transform());
753 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
754 great_grand_child_impl_
->draw_transform());
755 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
756 fixed_position_child_impl
->draw_transform());
758 // Case 2: scroll delta of 10, 30
759 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
760 ExecuteCalculateDrawProperties(root_impl_
);
762 expected_child_transform
.MakeIdentity();
763 expected_child_transform
.PreconcatTransform(rotation_about_z
);
764 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
766 expected_grand_child_surface_draw_transform
.MakeIdentity();
767 expected_grand_child_surface_draw_transform
.PreconcatTransform(
769 expected_grand_child_surface_draw_transform
.Translate(-10.0,
770 -30.0); // scroll delta
771 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
773 // grand_child, great_grand_child, and great_grand_child's surface are not
774 // expected to change, since they are all not fixed, and they are all drawn
775 // with respect to grand_child's surface that already has the scroll delta
778 // But the great-great grandchild, "fixed_position_child", should have a
779 // transform that explicitly cancels out the scroll delta.
780 expected_fixed_position_child_transform
.MakeIdentity();
781 // explicit canceling out the scroll delta that gets embedded in the fixed
782 // position layer's surface.
783 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
784 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
786 EXPECT_TRUE(grand_child_impl_
->render_surface());
787 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
788 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
789 child_impl_
->draw_transform());
790 EXPECT_TRANSFORMATION_MATRIX_EQ(
791 expected_grand_child_surface_draw_transform
,
792 grand_child_impl_
->render_surface()->draw_transform());
793 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
794 grand_child_impl_
->draw_transform());
795 EXPECT_TRANSFORMATION_MATRIX_EQ(
796 expected_great_grand_child_surface_draw_transform
,
797 great_grand_child_impl_
->render_surface()->draw_transform());
798 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
799 great_grand_child_impl_
->draw_transform());
800 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
801 fixed_position_child_impl
->draw_transform());
804 TEST_F(LayerPositionConstraintTest
,
805 ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface
) {
806 // This test checks for correct scroll compensation when the fixed-position
807 // container itself has a render surface. In this case, the container layer
808 // should be treated like a layer that contributes to a render target, and
809 // that render target is completely irrelevant; it should not affect the
810 // scroll compensation.
811 child_
->SetIsContainerForFixedPositionLayers(true);
812 child_
->SetForceRenderSurface(true);
813 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
815 CommitAndUpdateImplPointers();
817 // Case 1: scroll delta of 0, 0
818 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
819 ExecuteCalculateDrawProperties(root_impl_
);
821 gfx::Transform expected_surface_draw_transform
;
822 gfx::Transform expected_child_transform
;
823 gfx::Transform expected_grand_child_transform
;
824 EXPECT_TRUE(child_impl_
->render_surface());
825 EXPECT_TRANSFORMATION_MATRIX_EQ(
826 expected_surface_draw_transform
,
827 child_impl_
->render_surface()->draw_transform());
828 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
829 child_impl_
->draw_transform());
830 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
831 grand_child_impl_
->draw_transform());
833 // Case 2: scroll delta of 10, 10
834 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
835 ExecuteCalculateDrawProperties(root_impl_
);
837 // The surface is translated by scroll delta, the child transform doesn't
838 // change because it scrolls along with the surface, but the fixed position
839 // grand_child needs to compensate for the scroll translation.
840 expected_surface_draw_transform
.MakeIdentity();
841 expected_surface_draw_transform
.Translate(-10.0, -10.0);
842 expected_grand_child_transform
.MakeIdentity();
843 expected_grand_child_transform
.Translate(10.0, 10.0);
845 EXPECT_TRUE(child_impl_
->render_surface());
846 EXPECT_TRANSFORMATION_MATRIX_EQ(
847 expected_surface_draw_transform
,
848 child_impl_
->render_surface()->draw_transform());
849 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
850 child_impl_
->draw_transform());
851 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
852 grand_child_impl_
->draw_transform());
854 // Case 3: fixed-container size delta of 20, 20
855 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
856 ExecuteCalculateDrawProperties(root_impl_
);
858 // Top-left fixed-position layer should not be affected by container size.
859 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
860 child_impl_
->draw_transform());
861 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
862 grand_child_impl_
->draw_transform());
864 // Case 4: Bottom-right fixed-position layer.
865 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
866 CommitAndUpdateImplPointers();
867 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
868 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
869 ExecuteCalculateDrawProperties(root_impl_
);
871 // Bottom-right fixed-position layer moves as container resizes.
872 expected_grand_child_transform
.MakeIdentity();
873 // The surface is translated by scroll delta, the child transform doesn't
874 // change because it scrolls along with the surface, but the fixed position
875 // grand_child needs to compensate for the scroll translation.
876 expected_grand_child_transform
.Translate(10.0, 10.0);
877 // Apply size delta from the child(container) layer.
878 expected_grand_child_transform
.Translate(20.0, 20.0);
880 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
881 child_impl_
->draw_transform());
882 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
883 grand_child_impl_
->draw_transform());
886 TEST_F(LayerPositionConstraintTest
,
887 ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer
) {
888 // This test checks the scenario where a fixed-position layer also happens to
889 // be a container itself for a descendant fixed position layer. In particular,
890 // the layer should not accidentally be fixed to itself.
891 child_
->SetIsContainerForFixedPositionLayers(true);
892 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
894 // This should not confuse the grand_child. If correct, the grand_child would
895 // still be considered fixed to its container (i.e. "child").
896 grand_child_
->SetIsContainerForFixedPositionLayers(true);
898 CommitAndUpdateImplPointers();
900 // Case 1: scroll delta of 0, 0
901 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
902 ExecuteCalculateDrawProperties(root_impl_
);
904 gfx::Transform expected_child_transform
;
905 gfx::Transform expected_grand_child_transform
;
906 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
907 child_impl_
->draw_transform());
908 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
909 grand_child_impl_
->draw_transform());
911 // Case 2: scroll delta of 10, 10
912 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
913 ExecuteCalculateDrawProperties(root_impl_
);
915 // Here the child is affected by scroll delta, but the fixed position
916 // grand_child should not be affected.
917 expected_child_transform
.MakeIdentity();
918 expected_child_transform
.Translate(-10.0, -10.0);
919 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
920 child_impl_
->draw_transform());
921 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
922 grand_child_impl_
->draw_transform());
924 // Case 3: fixed-container size delta of 20, 20
925 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
926 ExecuteCalculateDrawProperties(root_impl_
);
928 // Top-left fixed-position layer should not be affected by container size.
929 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
930 child_impl_
->draw_transform());
931 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
932 grand_child_impl_
->draw_transform());
934 // Case 4: Bottom-right fixed-position layer.
935 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
936 CommitAndUpdateImplPointers();
937 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
938 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
940 ExecuteCalculateDrawProperties(root_impl_
);
942 // Bottom-right fixed-position layer moves as container resizes.
943 expected_grand_child_transform
.MakeIdentity();
944 // Apply size delta from the child(container) layer.
945 expected_grand_child_transform
.Translate(20.0, 20.0);
947 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
948 child_impl_
->draw_transform());
949 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
950 grand_child_impl_
->draw_transform());
953 TEST_F(LayerPositionConstraintTest
,
954 ScrollCompensationForFixedWithinFixedWithSameContainer
) {
955 // This test checks scroll compensation for a fixed-position layer that is
956 // inside of another fixed-position layer and both share the same container.
957 // In this situation, the parent fixed-position layer will receive
958 // the scroll compensation, and the child fixed-position layer does not
959 // need to compensate further.
960 child_
->SetIsContainerForFixedPositionLayers(true);
961 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
963 // Note carefully - great_grand_child is fixed to bottom right, to test
964 // sizeDelta being applied correctly; the compensation skips the grand_child
965 // because it is fixed to top left.
966 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
968 CommitAndUpdateImplPointers();
970 // Case 1: scrollDelta
971 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
972 ExecuteCalculateDrawProperties(root_impl_
);
974 // Here the child is affected by scroll delta, but the fixed position
975 // grand_child should not be affected.
976 gfx::Transform expected_child_transform
;
977 expected_child_transform
.Translate(-10.0, -10.0);
979 gfx::Transform expected_grand_child_transform
;
980 gfx::Transform expected_great_grand_child_transform
;
982 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
983 child_impl_
->draw_transform());
984 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
985 grand_child_impl_
->draw_transform());
986 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
987 great_grand_child_impl_
->draw_transform());
990 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
991 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
992 ExecuteCalculateDrawProperties(root_impl_
);
994 expected_child_transform
.MakeIdentity();
996 expected_grand_child_transform
.MakeIdentity();
998 // Fixed to bottom-right, size-delta compensation is applied.
999 expected_great_grand_child_transform
.MakeIdentity();
1000 expected_great_grand_child_transform
.Translate(20.0, 20.0);
1002 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
1003 child_impl_
->draw_transform());
1004 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
1005 grand_child_impl_
->draw_transform());
1006 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
1007 great_grand_child_impl_
->draw_transform());
1010 TEST_F(LayerPositionConstraintTest
,
1011 ScrollCompensationForFixedWithinFixedWithInterveningContainer
) {
1012 // This test checks scroll compensation for a fixed-position layer that is
1013 // inside of another fixed-position layer, but they have different fixed
1014 // position containers. In this situation, the child fixed-position element
1015 // would still have to compensate with respect to its container.
1017 // Add one more layer to the hierarchy for this test.
1018 scoped_refptr
<Layer
> great_great_grand_child
=
1019 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
1020 great_grand_child_
->AddChild(great_great_grand_child
);
1022 child_
->SetIsContainerForFixedPositionLayers(true);
1023 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
1024 great_grand_child_
->SetIsContainerForFixedPositionLayers(true);
1025 great_grand_child_
->SetScrollClipLayerId(root_
->id());
1026 great_great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
1028 CommitAndUpdateImplPointers();
1030 LayerImpl
* container1
= child_impl_
;
1031 LayerImpl
* fixed_to_container1
= grand_child_impl_
;
1032 LayerImpl
* container2
= great_grand_child_impl_
;
1033 LayerImpl
* fixed_to_container2
= container2
->children()[0];
1035 container1
->SetScrollDelta(gfx::Vector2d(0, 15));
1036 container2
->SetScrollDelta(gfx::Vector2d(30, 0));
1037 ExecuteCalculateDrawProperties(root_impl_
);
1039 gfx::Transform expected_container1_transform
;
1040 expected_container1_transform
.Translate(0.0, -15.0);
1042 gfx::Transform expected_fixed_to_container1_transform
;
1044 // Since the container is a descendant of the fixed layer above,
1045 // the expected draw transform for container2 would not
1046 // include the scrollDelta that was applied to container1.
1047 gfx::Transform expected_container2_transform
;
1048 expected_container2_transform
.Translate(-30.0, 0.0);
1050 gfx::Transform expected_fixed_to_container2_transform
;
1052 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform
,
1053 container1
->draw_transform());
1055 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform
,
1056 fixed_to_container1
->draw_transform());
1058 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform
,
1059 container2
->draw_transform());
1061 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform
,
1062 fixed_to_container2
->draw_transform());
1065 TEST_F(LayerPositionConstraintTest
,
1066 ScrollCompensationForInnerViewportBoundsDelta
) {
1067 // This test checks for correct scroll compensation when the fixed-position
1068 // container is the inner viewport scroll layer and has non-zero bounds delta.
1069 scoped_refptr
<Layer
> fixed_child
=
1070 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
1071 fixed_child
->SetBounds(gfx::Size(300, 300));
1072 scroll_layer_
->AddChild(fixed_child
);
1073 fixed_child
->SetPositionConstraint(fixed_to_top_left_
);
1075 CommitAndUpdateImplPointers();
1077 LayerImpl
* fixed_child_impl
=
1078 root_impl_
->layer_tree_impl()->FindActiveTreeLayerById(fixed_child
->id());
1080 // Case 1: fixed-container size delta of 20, 20
1081 scroll_layer_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
1082 SetFixedContainerSizeDelta(scroll_layer_impl_
, gfx::Vector2d(20, 20));
1083 gfx::Transform expected_scroll_layer_transform
;
1084 expected_scroll_layer_transform
.Translate(-10.0, -10.0);
1085 gfx::Transform expected_fixed_child_transform
;
1087 ExecuteCalculateDrawProperties(root_impl_
);
1089 // Top-left fixed-position layer should not be affected by container size.
1090 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform
,
1091 scroll_layer_impl_
->draw_transform());
1092 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform
,
1093 fixed_child_impl
->draw_transform());
1095 // Case 2: Bottom-right fixed-position layer.
1096 fixed_child
->SetPositionConstraint(fixed_to_bottom_right_
);
1097 CommitAndUpdateImplPointers();
1099 root_impl_
->layer_tree_impl()->FindActiveTreeLayerById(fixed_child
->id());
1101 scroll_layer_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
1102 SetFixedContainerSizeDelta(scroll_layer_impl_
, gfx::Vector2d(20, 20));
1103 ExecuteCalculateDrawProperties(root_impl_
);
1105 // Bottom-right fixed-position layer moves as container resizes.
1106 expected_fixed_child_transform
.MakeIdentity();
1107 // Apply size delta.
1108 expected_fixed_child_transform
.Translate(20.0, 20.0);
1110 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_layer_transform
,
1111 scroll_layer_impl_
->draw_transform());
1112 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_child_transform
,
1113 fixed_child_impl
->draw_transform());