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/trees/layer_tree_host_common.h"
14 #include "testing/gtest/include/gtest/gtest.h"
19 class LayerWithForcedDrawsContent
: public Layer
{
21 explicit LayerWithForcedDrawsContent(const LayerSettings
& settings
)
24 bool DrawsContent() const override
;
27 ~LayerWithForcedDrawsContent() override
{}
30 bool LayerWithForcedDrawsContent::DrawsContent() const {
34 void SetLayerPropertiesForTesting(Layer
* layer
,
35 const gfx::Transform
& transform
,
36 const gfx::Point3F
& transform_origin
,
37 const gfx::PointF
& position
,
38 const gfx::Size
& bounds
,
39 bool flatten_transform
) {
40 layer
->SetTransform(transform
);
41 layer
->SetTransformOrigin(transform_origin
);
42 layer
->SetPosition(position
);
43 layer
->SetBounds(bounds
);
44 layer
->SetShouldFlattenTransform(flatten_transform
);
47 void ExecuteCalculateDrawProperties(LayerImpl
* root_layer
) {
48 std::vector
<LayerImpl
*> dummy_render_surface_layer_list
;
49 LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting
inputs(
50 root_layer
, root_layer
->bounds(), &dummy_render_surface_layer_list
);
51 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
54 class LayerPositionConstraintTest
: public testing::Test
{
56 LayerPositionConstraintTest()
57 : fake_client_(FakeLayerTreeHostClient::DIRECT_3D
),
58 layer_tree_host_(FakeLayerTreeHost::Create(&fake_client_
)),
60 scroll_layer_impl_(nullptr),
61 child_transform_layer_impl_(nullptr),
63 grand_child_impl_(nullptr),
64 great_grand_child_impl_(nullptr) {
65 layer_tree_host_
->InitializeForTesting(scoped_ptr
<Proxy
>(new FakeProxy
));
67 fixed_to_top_left_
.set_is_fixed_position(true);
68 fixed_to_bottom_right_
.set_is_fixed_position(true);
69 fixed_to_bottom_right_
.set_is_fixed_to_right_edge(true);
70 fixed_to_bottom_right_
.set_is_fixed_to_bottom_edge(true);
73 void CreateTreeForTest() {
74 root_
= Layer::Create(layer_settings_
);
75 scroll_layer_
= Layer::Create(layer_settings_
);
76 child_transform_layer_
= Layer::Create(layer_settings_
);
77 child_
= Layer::Create(layer_settings_
);
79 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
81 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
83 gfx::Transform IdentityMatrix
;
84 gfx::Point3F transform_origin
;
86 gfx::Size
bounds(200, 200);
87 gfx::Size
clip_bounds(100, 100);
88 SetLayerPropertiesForTesting(scroll_layer_
.get(), IdentityMatrix
,
89 transform_origin
, position
, bounds
, true);
90 SetLayerPropertiesForTesting(child_
.get(), IdentityMatrix
, transform_origin
,
91 position
, bounds
, true);
92 SetLayerPropertiesForTesting(grand_child_
.get(), IdentityMatrix
,
93 transform_origin
, position
, bounds
, true);
94 SetLayerPropertiesForTesting(great_grand_child_
.get(), IdentityMatrix
,
95 transform_origin
, position
, bounds
, true);
97 root_
->SetBounds(clip_bounds
);
98 scroll_layer_
->SetScrollClipLayerId(root_
->id());
99 child_
->SetScrollClipLayerId(root_
->id());
100 grand_child_
->SetScrollClipLayerId(root_
->id());
102 grand_child_
->AddChild(great_grand_child_
);
103 child_
->AddChild(grand_child_
);
104 child_transform_layer_
->AddChild(child_
);
105 scroll_layer_
->AddChild(child_transform_layer_
);
106 root_
->AddChild(scroll_layer_
);
108 layer_tree_host_
->SetRootLayer(root_
);
111 void CommitAndUpdateImplPointers() {
112 RenderSurfaceLayerList render_surface_layer_list
;
113 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
114 root_
.get(), root_
->bounds(), &render_surface_layer_list
);
115 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
116 root_impl_
= layer_tree_host_
->CommitAndCreateLayerImplTree();
117 scroll_layer_impl_
= root_impl_
->children()[0];
118 child_transform_layer_impl_
= scroll_layer_impl_
->children()[0];
119 child_impl_
= child_transform_layer_impl_
->children()[0];
120 grand_child_impl_
= child_impl_
->children()[0];
121 great_grand_child_impl_
= grand_child_impl_
->children()[0];
125 FakeLayerTreeHostClient fake_client_
;
126 scoped_ptr
<FakeLayerTreeHost
> layer_tree_host_
;
127 LayerSettings layer_settings_
;
128 scoped_refptr
<Layer
> root_
;
129 scoped_refptr
<Layer
> scroll_layer_
;
130 scoped_refptr
<Layer
> child_transform_layer_
;
131 scoped_refptr
<Layer
> child_
;
132 scoped_refptr
<Layer
> grand_child_
;
133 scoped_refptr
<Layer
> great_grand_child_
;
134 LayerImpl
* root_impl_
;
135 LayerImpl
* scroll_layer_impl_
;
136 LayerImpl
* child_transform_layer_impl_
;
137 LayerImpl
* child_impl_
;
138 LayerImpl
* grand_child_impl_
;
139 LayerImpl
* great_grand_child_impl_
;
141 LayerPositionConstraint fixed_to_top_left_
;
142 LayerPositionConstraint fixed_to_bottom_right_
;
147 void SetFixedContainerSizeDelta(LayerImpl
* scroll_layer
,
148 const gfx::Vector2d
& delta
) {
149 DCHECK(scroll_layer
);
150 DCHECK(scroll_layer
->scrollable());
152 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
153 container_layer
->SetBoundsDelta(delta
);
157 TEST_F(LayerPositionConstraintTest
,
158 ScrollCompensationForFixedPositionLayerWithDirectContainer
) {
159 // This test checks for correct scroll compensation when the fixed-position
160 // container is the direct parent of the fixed-position layer.
161 child_
->SetIsContainerForFixedPositionLayers(true);
162 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
164 CommitAndUpdateImplPointers();
166 // Case 1: scroll delta of 0, 0
167 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
168 ExecuteCalculateDrawProperties(root_impl_
);
170 gfx::Transform expected_child_transform
;
171 gfx::Transform expected_grand_child_transform
= expected_child_transform
;
173 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
174 child_impl_
->draw_transform());
175 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
176 grand_child_impl_
->draw_transform());
178 // Case 2: scroll delta of 10, 10
179 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
180 ExecuteCalculateDrawProperties(root_impl_
);
182 // Here the child is affected by scroll delta, but the fixed position
183 // grand_child should not be affected.
184 expected_child_transform
.MakeIdentity();
185 expected_child_transform
.Translate(-10.0, -10.0);
187 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
188 child_impl_
->draw_transform());
189 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
190 grand_child_impl_
->draw_transform());
192 // Case 3: fixed-container size delta of 20, 20
193 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
194 ExecuteCalculateDrawProperties(root_impl_
);
196 // Top-left fixed-position layer should not be affected by container size.
197 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
198 child_impl_
->draw_transform());
199 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
200 grand_child_impl_
->draw_transform());
202 // Case 4: Bottom-right fixed-position layer.
203 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
204 CommitAndUpdateImplPointers();
206 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
207 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
208 ExecuteCalculateDrawProperties(root_impl_
);
210 // Bottom-right fixed-position layer moves as container resizes.
211 expected_grand_child_transform
.MakeIdentity();
212 // Apply size delta from the child(container) layer.
213 expected_grand_child_transform
.Translate(20.0, 20.0);
215 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
216 child_impl_
->draw_transform());
217 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
218 grand_child_impl_
->draw_transform());
221 TEST_F(LayerPositionConstraintTest
,
222 ScrollCompensationForFixedPositionLayerWithDistantContainer
) {
223 // This test checks for correct scroll compensation when the fixed-position
224 // container is NOT the direct parent of the fixed-position layer.
225 child_
->SetIsContainerForFixedPositionLayers(true);
226 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
227 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
229 CommitAndUpdateImplPointers();
231 // Case 1: scroll delta of 0, 0
232 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
233 ExecuteCalculateDrawProperties(root_impl_
);
235 gfx::Transform expected_child_transform
;
236 gfx::Transform expected_grand_child_transform
;
237 expected_grand_child_transform
.Translate(8.0, 6.0);
239 gfx::Transform expected_great_grand_child_transform
=
240 expected_grand_child_transform
;
242 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
243 child_impl_
->draw_transform());
244 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
245 grand_child_impl_
->draw_transform());
246 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
247 great_grand_child_impl_
->draw_transform());
249 // Case 2: scroll delta of 10, 10
250 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
251 ExecuteCalculateDrawProperties(root_impl_
);
253 // Here the child and grand_child are affected by scroll delta, but the fixed
254 // position great_grand_child should not be affected.
255 expected_child_transform
.MakeIdentity();
256 expected_child_transform
.Translate(-10.0, -10.0);
257 expected_grand_child_transform
.MakeIdentity();
258 expected_grand_child_transform
.Translate(-2.0, -4.0);
259 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
260 child_impl_
->draw_transform());
261 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
262 grand_child_impl_
->draw_transform());
263 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
264 great_grand_child_impl_
->draw_transform());
266 // Case 3: fixed-container size delta of 20, 20
267 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
268 ExecuteCalculateDrawProperties(root_impl_
);
270 // Top-left fixed-position layer should not be affected by container size.
271 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
272 child_impl_
->draw_transform());
273 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
274 grand_child_impl_
->draw_transform());
275 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
276 great_grand_child_impl_
->draw_transform());
278 // Case 4: Bottom-right fixed-position layer.
279 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
280 CommitAndUpdateImplPointers();
281 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
282 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
283 ExecuteCalculateDrawProperties(root_impl_
);
285 // Bottom-right fixed-position layer moves as container resizes.
286 expected_great_grand_child_transform
.MakeIdentity();
287 // Apply size delta from the child(container) layer.
288 expected_great_grand_child_transform
.Translate(20.0, 20.0);
289 // Apply layer position from the grand child layer.
290 expected_great_grand_child_transform
.Translate(8.0, 6.0);
292 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
293 child_impl_
->draw_transform());
294 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
295 grand_child_impl_
->draw_transform());
296 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
297 great_grand_child_impl_
->draw_transform());
300 TEST_F(LayerPositionConstraintTest
,
301 ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas
) {
302 // This test checks for correct scroll compensation when the fixed-position
303 // container has multiple ancestors that have nonzero scroll delta before
304 // reaching the space where the layer is fixed.
305 gfx::Transform rotation_about_z
;
306 rotation_about_z
.RotateAboutZAxis(90.0);
308 child_transform_layer_
->SetIsContainerForFixedPositionLayers(true);
309 child_transform_layer_
->SetTransform(rotation_about_z
);
310 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
311 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
313 CommitAndUpdateImplPointers();
315 // Case 1: scroll delta of 0, 0
316 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
317 ExecuteCalculateDrawProperties(root_impl_
);
319 gfx::Transform expected_child_transform
;
320 expected_child_transform
.PreconcatTransform(rotation_about_z
);
322 gfx::Transform expected_grand_child_transform
;
323 expected_grand_child_transform
.PreconcatTransform(
324 rotation_about_z
); // child's local transform is inherited
325 // translation because of position occurs before layer's local transform.
326 expected_grand_child_transform
.Translate(8.0, 6.0);
328 gfx::Transform expected_great_grand_child_transform
=
329 expected_grand_child_transform
;
331 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
332 child_impl_
->draw_transform());
333 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
334 grand_child_impl_
->draw_transform());
335 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
336 great_grand_child_impl_
->draw_transform());
338 // Case 2: scroll delta of 10, 20
339 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 0));
340 grand_child_impl_
->SetScrollDelta(gfx::Vector2d(5, 0));
341 ExecuteCalculateDrawProperties(root_impl_
);
343 // Here the child and grand_child are affected by scroll delta, but the fixed
344 // position great_grand_child should not be affected.
345 expected_child_transform
.MakeIdentity();
346 expected_child_transform
.PreconcatTransform(rotation_about_z
);
347 expected_child_transform
.Translate(-10.0, 0.0); // scroll delta
349 expected_grand_child_transform
.MakeIdentity();
350 expected_grand_child_transform
.PreconcatTransform(
351 rotation_about_z
); // child's local transform is inherited
352 expected_grand_child_transform
.Translate(
353 -10.0, 0.0); // child's scroll delta is inherited
354 expected_grand_child_transform
.Translate(-5.0,
355 0.0); // grand_child's scroll delta
356 // translation because of position
357 expected_grand_child_transform
.Translate(8.0, 6.0);
359 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
360 child_impl_
->draw_transform());
361 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
362 grand_child_impl_
->draw_transform());
363 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
364 great_grand_child_impl_
->draw_transform());
367 TEST_F(LayerPositionConstraintTest
,
368 ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms
) {
369 // This test checks for correct scroll compensation when the fixed-position
370 // container contributes to a different render surface than the fixed-position
371 // layer. In this case, the surface draw transforms also have to be accounted
372 // for when checking the scroll delta.
373 child_
->SetIsContainerForFixedPositionLayers(true);
374 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
375 grand_child_
->SetForceRenderSurface(true);
376 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
378 gfx::Transform rotation_about_z
;
379 rotation_about_z
.RotateAboutZAxis(90.0);
380 great_grand_child_
->SetTransform(rotation_about_z
);
382 CommitAndUpdateImplPointers();
384 // Case 1: scroll delta of 0, 0
385 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
386 ExecuteCalculateDrawProperties(root_impl_
);
388 gfx::Transform expected_child_transform
;
389 gfx::Transform expected_surface_draw_transform
;
390 expected_surface_draw_transform
.Translate(8.0, 6.0);
391 gfx::Transform expected_grand_child_transform
;
392 gfx::Transform expected_great_grand_child_transform
;
393 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
394 EXPECT_TRUE(grand_child_impl_
->render_surface());
395 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
396 child_impl_
->draw_transform());
397 EXPECT_TRANSFORMATION_MATRIX_EQ(
398 expected_surface_draw_transform
,
399 grand_child_impl_
->render_surface()->draw_transform());
400 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
401 grand_child_impl_
->draw_transform());
402 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
403 great_grand_child_impl_
->draw_transform());
405 // Case 2: scroll delta of 10, 30
406 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
407 ExecuteCalculateDrawProperties(root_impl_
);
409 // Here the grand_child remains unchanged, because it scrolls along with the
410 // render surface, and the translation is actually in the render surface. But,
411 // the fixed position great_grand_child is more awkward: its actually being
412 // drawn with respect to the render surface, but it needs to remain fixed with
413 // resepct to a container beyond that surface. So, the net result is that,
414 // unlike previous tests where the fixed position layer's transform remains
415 // unchanged, here the fixed position layer's transform explicitly contains
416 // the translation that cancels out the scroll.
417 expected_child_transform
.MakeIdentity();
418 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
420 expected_surface_draw_transform
.MakeIdentity();
421 expected_surface_draw_transform
.Translate(-10.0, -30.0); // scroll delta
422 expected_surface_draw_transform
.Translate(8.0, 6.0);
424 expected_great_grand_child_transform
.MakeIdentity();
425 // explicit canceling out the scroll delta that gets embedded in the fixed
426 // position layer's surface.
427 expected_great_grand_child_transform
.Translate(10.0, 30.0);
428 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
430 EXPECT_TRUE(grand_child_impl_
->render_surface());
431 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
432 child_impl_
->draw_transform());
433 EXPECT_TRANSFORMATION_MATRIX_EQ(
434 expected_surface_draw_transform
,
435 grand_child_impl_
->render_surface()->draw_transform());
436 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
437 grand_child_impl_
->draw_transform());
438 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
439 great_grand_child_impl_
->draw_transform());
441 // Case 3: fixed-container size delta of 20, 20
442 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
443 ExecuteCalculateDrawProperties(root_impl_
);
445 // Top-left fixed-position layer should not be affected by container size.
446 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
447 child_impl_
->draw_transform());
448 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
449 grand_child_impl_
->draw_transform());
450 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
451 great_grand_child_impl_
->draw_transform());
453 // Case 4: Bottom-right fixed-position layer.
454 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
456 CommitAndUpdateImplPointers();
457 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
458 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
460 ExecuteCalculateDrawProperties(root_impl_
);
462 // Bottom-right fixed-position layer moves as container resizes.
463 expected_great_grand_child_transform
.MakeIdentity();
464 // explicit canceling out the scroll delta that gets embedded in the fixed
465 // position layer's surface.
466 expected_great_grand_child_transform
.Translate(10.0, 30.0);
467 // Also apply size delta in the child(container) layer space.
468 expected_great_grand_child_transform
.Translate(20.0, 20.0);
469 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
471 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
472 child_impl_
->draw_transform());
473 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
474 grand_child_impl_
->draw_transform());
475 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
476 great_grand_child_impl_
->draw_transform());
479 TEST_F(LayerPositionConstraintTest
,
480 ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces
) {
481 // This test checks for correct scroll compensation when the fixed-position
482 // container contributes to a different render surface than the fixed-position
483 // layer, with additional render surfaces in-between. This checks that the
484 // conversion to ancestor surfaces is accumulated properly in the final matrix
487 // Add one more layer to the test tree for this scenario.
488 scoped_refptr
<Layer
> fixed_position_child
=
489 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
490 SetLayerPropertiesForTesting(fixed_position_child
.get(), gfx::Transform(),
491 gfx::Point3F(), gfx::PointF(),
492 gfx::Size(100, 100), true);
493 great_grand_child_
->AddChild(fixed_position_child
);
495 // Actually set up the scenario here.
496 child_
->SetIsContainerForFixedPositionLayers(true);
497 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
498 grand_child_
->SetForceRenderSurface(true);
499 great_grand_child_
->SetPosition(gfx::PointF(40.f
, 60.f
));
500 great_grand_child_
->SetForceRenderSurface(true);
501 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
503 // The additional rotation, which is non-commutative with translations, helps
504 // to verify that we have correct order-of-operations in the final scroll
505 // compensation. Note that rotating about the center of the layer ensures we
506 // do not accidentally clip away layers that we want to test.
507 gfx::Transform rotation_about_z
;
508 rotation_about_z
.Translate(50.0, 50.0);
509 rotation_about_z
.RotateAboutZAxis(90.0);
510 rotation_about_z
.Translate(-50.0, -50.0);
511 fixed_position_child
->SetTransform(rotation_about_z
);
513 CommitAndUpdateImplPointers();
514 LayerImpl
* fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
516 // Case 1: scroll delta of 0, 0
517 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
518 ExecuteCalculateDrawProperties(root_impl_
);
520 gfx::Transform expected_child_transform
;
522 gfx::Transform expected_grand_child_surface_draw_transform
;
523 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
525 gfx::Transform expected_grand_child_transform
;
527 gfx::Transform expected_great_grand_child_surface_draw_transform
;
528 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
530 gfx::Transform expected_great_grand_child_transform
;
532 gfx::Transform expected_fixed_position_child_transform
;
533 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
535 EXPECT_TRUE(grand_child_impl_
->render_surface());
536 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
537 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
538 child_impl_
->draw_transform());
539 EXPECT_TRANSFORMATION_MATRIX_EQ(
540 expected_grand_child_surface_draw_transform
,
541 grand_child_impl_
->render_surface()->draw_transform());
542 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
543 grand_child_impl_
->draw_transform());
544 EXPECT_TRANSFORMATION_MATRIX_EQ(
545 expected_great_grand_child_surface_draw_transform
,
546 great_grand_child_impl_
->render_surface()->draw_transform());
547 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
548 great_grand_child_impl_
->draw_transform());
549 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
550 fixed_position_child_impl
->draw_transform());
552 // Case 2: scroll delta of 10, 30
553 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
554 ExecuteCalculateDrawProperties(root_impl_
);
556 expected_child_transform
.MakeIdentity();
557 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
559 expected_grand_child_surface_draw_transform
.MakeIdentity();
560 expected_grand_child_surface_draw_transform
.Translate(-10.0,
561 -30.0); // scroll delta
562 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
564 // grand_child, great_grand_child, and great_grand_child's surface are not
565 // expected to change, since they are all not fixed, and they are all drawn
566 // with respect to grand_child's surface that already has the scroll delta
569 // But the great-great grandchild, "fixed_position_child", should have a
570 // transform that explicitly cancels out the scroll delta.
571 expected_fixed_position_child_transform
.MakeIdentity();
572 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
573 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
575 EXPECT_TRUE(grand_child_impl_
->render_surface());
576 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
577 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
578 child_impl_
->draw_transform());
579 EXPECT_TRANSFORMATION_MATRIX_EQ(
580 expected_grand_child_surface_draw_transform
,
581 grand_child_impl_
->render_surface()->draw_transform());
582 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
583 grand_child_impl_
->draw_transform());
584 EXPECT_TRANSFORMATION_MATRIX_EQ(
585 expected_great_grand_child_surface_draw_transform
,
586 great_grand_child_impl_
->render_surface()->draw_transform());
587 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
588 great_grand_child_impl_
->draw_transform());
589 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
590 fixed_position_child_impl
->draw_transform());
592 // Case 3: fixed-container size delta of 20, 20
593 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
594 ExecuteCalculateDrawProperties(root_impl_
);
596 // Top-left fixed-position layer should not be affected by container size.
597 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
598 child_impl_
->draw_transform());
599 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
600 grand_child_impl_
->draw_transform());
601 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
602 great_grand_child_impl_
->draw_transform());
603 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
604 fixed_position_child_impl
->draw_transform());
606 // Case 4: Bottom-right fixed-position layer.
607 fixed_position_child
->SetPositionConstraint(fixed_to_bottom_right_
);
608 CommitAndUpdateImplPointers();
609 fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
610 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
611 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
612 ExecuteCalculateDrawProperties(root_impl_
);
614 // Bottom-right fixed-position layer moves as container resizes.
615 expected_fixed_position_child_transform
.MakeIdentity();
616 // explicit canceling out the scroll delta that gets embedded in the fixed
617 // position layer's surface.
618 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
619 // Also apply size delta in the child(container) layer space.
620 expected_fixed_position_child_transform
.Translate(20.0, 20.0);
621 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
623 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
624 child_impl_
->draw_transform());
625 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
626 grand_child_impl_
->draw_transform());
627 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
628 great_grand_child_impl_
->draw_transform());
629 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
630 fixed_position_child_impl
->draw_transform());
634 LayerPositionConstraintTest
,
635 ScrollCompensationForFixedPositionLayerWithMultipleSurfacesAndTransforms
) {
636 // This test checks for correct scroll compensation when the fixed-position
637 // container contributes to a different render surface than the fixed-position
638 // layer, with additional render surfaces in-between, and the fixed-position
639 // container is transformed. This checks that the conversion to ancestor
640 // surfaces is accumulated properly in the final matrix transform.
642 // Add one more layer to the test tree for this scenario.
643 scoped_refptr
<Layer
> fixed_position_child
=
644 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
645 SetLayerPropertiesForTesting(fixed_position_child
.get(), gfx::Transform(),
646 gfx::Point3F(), gfx::PointF(),
647 gfx::Size(100, 100), true);
648 great_grand_child_
->AddChild(fixed_position_child
);
650 // Actually set up the scenario here.
651 child_transform_layer_
->SetIsContainerForFixedPositionLayers(true);
652 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
653 grand_child_
->SetForceRenderSurface(true);
654 great_grand_child_
->SetPosition(gfx::PointF(40.f
, 60.f
));
655 great_grand_child_
->SetForceRenderSurface(true);
656 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
658 // The additional rotations, which are non-commutative with translations, help
659 // to verify that we have correct order-of-operations in the final scroll
660 // compensation. Note that rotating about the center of the layer ensures we
661 // do not accidentally clip away layers that we want to test.
662 gfx::Transform rotation_about_z
;
663 rotation_about_z
.Translate(50.0, 50.0);
664 rotation_about_z
.RotateAboutZAxis(90.0);
665 rotation_about_z
.Translate(-50.0, -50.0);
666 child_transform_layer_
->SetTransform(rotation_about_z
);
667 fixed_position_child
->SetTransform(rotation_about_z
);
669 CommitAndUpdateImplPointers();
670 LayerImpl
* fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
672 // Case 1: scroll delta of 0, 0
673 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
674 ExecuteCalculateDrawProperties(root_impl_
);
676 gfx::Transform expected_child_transform
;
677 expected_child_transform
.PreconcatTransform(rotation_about_z
);
679 gfx::Transform expected_grand_child_surface_draw_transform
;
680 expected_grand_child_surface_draw_transform
.PreconcatTransform(
682 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
684 gfx::Transform expected_grand_child_transform
;
686 gfx::Transform expected_great_grand_child_surface_draw_transform
;
687 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
689 gfx::Transform expected_great_grand_child_transform
;
691 gfx::Transform expected_fixed_position_child_transform
;
692 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
694 EXPECT_TRUE(grand_child_impl_
->render_surface());
695 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
696 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
697 child_impl_
->draw_transform());
698 EXPECT_TRANSFORMATION_MATRIX_EQ(
699 expected_grand_child_surface_draw_transform
,
700 grand_child_impl_
->render_surface()->draw_transform());
701 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
702 grand_child_impl_
->draw_transform());
703 EXPECT_TRANSFORMATION_MATRIX_EQ(
704 expected_great_grand_child_surface_draw_transform
,
705 great_grand_child_impl_
->render_surface()->draw_transform());
706 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
707 great_grand_child_impl_
->draw_transform());
708 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
709 fixed_position_child_impl
->draw_transform());
711 // Case 2: scroll delta of 10, 30
712 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
713 ExecuteCalculateDrawProperties(root_impl_
);
715 expected_child_transform
.MakeIdentity();
716 expected_child_transform
.PreconcatTransform(rotation_about_z
);
717 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
719 expected_grand_child_surface_draw_transform
.MakeIdentity();
720 expected_grand_child_surface_draw_transform
.PreconcatTransform(
722 expected_grand_child_surface_draw_transform
.Translate(-10.0,
723 -30.0); // scroll delta
724 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
726 // grand_child, great_grand_child, and great_grand_child's surface are not
727 // expected to change, since they are all not fixed, and they are all drawn
728 // with respect to grand_child's surface that already has the scroll delta
731 // But the great-great grandchild, "fixed_position_child", should have a
732 // transform that explicitly cancels out the scroll delta.
733 expected_fixed_position_child_transform
.MakeIdentity();
734 // explicit canceling out the scroll delta that gets embedded in the fixed
735 // position layer's surface.
736 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
737 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
739 EXPECT_TRUE(grand_child_impl_
->render_surface());
740 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
741 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
742 child_impl_
->draw_transform());
743 EXPECT_TRANSFORMATION_MATRIX_EQ(
744 expected_grand_child_surface_draw_transform
,
745 grand_child_impl_
->render_surface()->draw_transform());
746 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
747 grand_child_impl_
->draw_transform());
748 EXPECT_TRANSFORMATION_MATRIX_EQ(
749 expected_great_grand_child_surface_draw_transform
,
750 great_grand_child_impl_
->render_surface()->draw_transform());
751 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
752 great_grand_child_impl_
->draw_transform());
753 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
754 fixed_position_child_impl
->draw_transform());
757 TEST_F(LayerPositionConstraintTest
,
758 ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface
) {
759 // This test checks for correct scroll compensation when the fixed-position
760 // container itself has a render surface. In this case, the container layer
761 // should be treated like a layer that contributes to a render target, and
762 // that render target is completely irrelevant; it should not affect the
763 // scroll compensation.
764 child_
->SetIsContainerForFixedPositionLayers(true);
765 child_
->SetForceRenderSurface(true);
766 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
768 CommitAndUpdateImplPointers();
770 // Case 1: scroll delta of 0, 0
771 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
772 ExecuteCalculateDrawProperties(root_impl_
);
774 gfx::Transform expected_surface_draw_transform
;
775 gfx::Transform expected_child_transform
;
776 gfx::Transform expected_grand_child_transform
;
777 EXPECT_TRUE(child_impl_
->render_surface());
778 EXPECT_TRANSFORMATION_MATRIX_EQ(
779 expected_surface_draw_transform
,
780 child_impl_
->render_surface()->draw_transform());
781 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
782 child_impl_
->draw_transform());
783 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
784 grand_child_impl_
->draw_transform());
786 // Case 2: scroll delta of 10, 10
787 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
788 ExecuteCalculateDrawProperties(root_impl_
);
790 // The surface is translated by scroll delta, the child transform doesn't
791 // change because it scrolls along with the surface, but the fixed position
792 // grand_child needs to compensate for the scroll translation.
793 expected_surface_draw_transform
.MakeIdentity();
794 expected_surface_draw_transform
.Translate(-10.0, -10.0);
795 expected_grand_child_transform
.MakeIdentity();
796 expected_grand_child_transform
.Translate(10.0, 10.0);
798 EXPECT_TRUE(child_impl_
->render_surface());
799 EXPECT_TRANSFORMATION_MATRIX_EQ(
800 expected_surface_draw_transform
,
801 child_impl_
->render_surface()->draw_transform());
802 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
803 child_impl_
->draw_transform());
804 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
805 grand_child_impl_
->draw_transform());
807 // Case 3: fixed-container size delta of 20, 20
808 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
809 ExecuteCalculateDrawProperties(root_impl_
);
811 // Top-left fixed-position layer should not be affected by container size.
812 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
813 child_impl_
->draw_transform());
814 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
815 grand_child_impl_
->draw_transform());
817 // Case 4: Bottom-right fixed-position layer.
818 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
819 CommitAndUpdateImplPointers();
820 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
821 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
822 ExecuteCalculateDrawProperties(root_impl_
);
824 // Bottom-right fixed-position layer moves as container resizes.
825 expected_grand_child_transform
.MakeIdentity();
826 // The surface is translated by scroll delta, the child transform doesn't
827 // change because it scrolls along with the surface, but the fixed position
828 // grand_child needs to compensate for the scroll translation.
829 expected_grand_child_transform
.Translate(10.0, 10.0);
830 // Apply size delta from the child(container) layer.
831 expected_grand_child_transform
.Translate(20.0, 20.0);
833 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
834 child_impl_
->draw_transform());
835 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
836 grand_child_impl_
->draw_transform());
839 TEST_F(LayerPositionConstraintTest
,
840 ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer
) {
841 // This test checks the scenario where a fixed-position layer also happens to
842 // be a container itself for a descendant fixed position layer. In particular,
843 // the layer should not accidentally be fixed to itself.
844 child_
->SetIsContainerForFixedPositionLayers(true);
845 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
847 // This should not confuse the grand_child. If correct, the grand_child would
848 // still be considered fixed to its container (i.e. "child").
849 grand_child_
->SetIsContainerForFixedPositionLayers(true);
851 CommitAndUpdateImplPointers();
853 // Case 1: scroll delta of 0, 0
854 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
855 ExecuteCalculateDrawProperties(root_impl_
);
857 gfx::Transform expected_child_transform
;
858 gfx::Transform expected_grand_child_transform
;
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 2: scroll delta of 10, 10
865 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
866 ExecuteCalculateDrawProperties(root_impl_
);
868 // Here the child is affected by scroll delta, but the fixed position
869 // grand_child should not be affected.
870 expected_child_transform
.MakeIdentity();
871 expected_child_transform
.Translate(-10.0, -10.0);
872 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
873 child_impl_
->draw_transform());
874 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
875 grand_child_impl_
->draw_transform());
877 // Case 3: fixed-container size delta of 20, 20
878 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
879 ExecuteCalculateDrawProperties(root_impl_
);
881 // Top-left fixed-position layer should not be affected by container size.
882 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
883 child_impl_
->draw_transform());
884 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
885 grand_child_impl_
->draw_transform());
887 // Case 4: Bottom-right fixed-position layer.
888 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
889 CommitAndUpdateImplPointers();
890 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
891 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
893 ExecuteCalculateDrawProperties(root_impl_
);
895 // Bottom-right fixed-position layer moves as container resizes.
896 expected_grand_child_transform
.MakeIdentity();
897 // Apply size delta from the child(container) layer.
898 expected_grand_child_transform
.Translate(20.0, 20.0);
900 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
901 child_impl_
->draw_transform());
902 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
903 grand_child_impl_
->draw_transform());
906 TEST_F(LayerPositionConstraintTest
,
907 ScrollCompensationForFixedWithinFixedWithSameContainer
) {
908 // This test checks scroll compensation for a fixed-position layer that is
909 // inside of another fixed-position layer and both share the same container.
910 // In this situation, the parent fixed-position layer will receive
911 // the scroll compensation, and the child fixed-position layer does not
912 // need to compensate further.
913 child_
->SetIsContainerForFixedPositionLayers(true);
914 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
916 // Note carefully - great_grand_child is fixed to bottom right, to test
917 // sizeDelta being applied correctly; the compensation skips the grand_child
918 // because it is fixed to top left.
919 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
921 CommitAndUpdateImplPointers();
923 // Case 1: scrollDelta
924 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
925 ExecuteCalculateDrawProperties(root_impl_
);
927 // Here the child is affected by scroll delta, but the fixed position
928 // grand_child should not be affected.
929 gfx::Transform expected_child_transform
;
930 expected_child_transform
.Translate(-10.0, -10.0);
932 gfx::Transform expected_grand_child_transform
;
933 gfx::Transform expected_great_grand_child_transform
;
935 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
936 child_impl_
->draw_transform());
937 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
938 grand_child_impl_
->draw_transform());
939 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
940 great_grand_child_impl_
->draw_transform());
943 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
944 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
945 ExecuteCalculateDrawProperties(root_impl_
);
947 expected_child_transform
.MakeIdentity();
949 expected_grand_child_transform
.MakeIdentity();
951 // Fixed to bottom-right, size-delta compensation is applied.
952 expected_great_grand_child_transform
.MakeIdentity();
953 expected_great_grand_child_transform
.Translate(20.0, 20.0);
955 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
956 child_impl_
->draw_transform());
957 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
958 grand_child_impl_
->draw_transform());
959 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
960 great_grand_child_impl_
->draw_transform());
963 TEST_F(LayerPositionConstraintTest
,
964 ScrollCompensationForFixedWithinFixedWithInterveningContainer
) {
965 // This test checks scroll compensation for a fixed-position layer that is
966 // inside of another fixed-position layer, but they have different fixed
967 // position containers. In this situation, the child fixed-position element
968 // would still have to compensate with respect to its container.
970 // Add one more layer to the hierarchy for this test.
971 scoped_refptr
<Layer
> great_great_grand_child
=
972 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
973 great_grand_child_
->AddChild(great_great_grand_child
);
975 child_
->SetIsContainerForFixedPositionLayers(true);
976 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
977 great_grand_child_
->SetIsContainerForFixedPositionLayers(true);
978 great_great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
980 CommitAndUpdateImplPointers();
982 LayerImpl
* container1
= child_impl_
;
983 LayerImpl
* fixed_to_container1
= grand_child_impl_
;
984 LayerImpl
* container2
= great_grand_child_impl_
;
985 LayerImpl
* fixed_to_container2
= container2
->children()[0];
987 container1
->SetScrollDelta(gfx::Vector2d(0, 15));
988 container2
->SetScrollDelta(gfx::Vector2d(30, 0));
989 ExecuteCalculateDrawProperties(root_impl_
);
991 gfx::Transform expected_container1_transform
;
992 expected_container1_transform
.Translate(0.0, -15.0);
994 gfx::Transform expected_fixed_to_container1_transform
;
996 // Since the container is a descendant of the fixed layer above,
997 // the expected draw transform for container2 would not
998 // include the scrollDelta that was applied to container1.
999 gfx::Transform expected_container2_transform
;
1000 expected_container2_transform
.Translate(-30.0, 0.0);
1002 gfx::Transform expected_fixed_to_container2_transform
;
1004 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform
,
1005 container1
->draw_transform());
1007 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform
,
1008 fixed_to_container1
->draw_transform());
1010 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform
,
1011 container2
->draw_transform());
1013 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform
,
1014 fixed_to_container2
->draw_transform());