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 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
55 class LayerPositionConstraintTest
: public testing::Test
{
57 LayerPositionConstraintTest()
58 : fake_client_(FakeLayerTreeHostClient::DIRECT_3D
),
60 FakeLayerTreeHost::Create(&fake_client_
, &task_graph_runner_
)),
62 scroll_layer_impl_(nullptr),
63 child_transform_layer_impl_(nullptr),
65 grand_child_impl_(nullptr),
66 great_grand_child_impl_(nullptr) {
67 layer_tree_host_
->InitializeForTesting(scoped_ptr
<Proxy
>(new FakeProxy
));
69 fixed_to_top_left_
.set_is_fixed_position(true);
70 fixed_to_bottom_right_
.set_is_fixed_position(true);
71 fixed_to_bottom_right_
.set_is_fixed_to_right_edge(true);
72 fixed_to_bottom_right_
.set_is_fixed_to_bottom_edge(true);
75 void CreateTreeForTest() {
76 root_
= Layer::Create(layer_settings_
);
77 scroll_layer_
= Layer::Create(layer_settings_
);
78 child_transform_layer_
= Layer::Create(layer_settings_
);
79 child_
= Layer::Create(layer_settings_
);
81 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
83 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
85 gfx::Transform IdentityMatrix
;
86 gfx::Point3F transform_origin
;
88 gfx::Size
bounds(200, 200);
89 gfx::Size
clip_bounds(100, 100);
90 SetLayerPropertiesForTesting(scroll_layer_
.get(), IdentityMatrix
,
91 transform_origin
, position
, bounds
, true);
92 SetLayerPropertiesForTesting(child_
.get(), IdentityMatrix
, transform_origin
,
93 position
, bounds
, true);
94 SetLayerPropertiesForTesting(grand_child_
.get(), IdentityMatrix
,
95 transform_origin
, position
, bounds
, true);
96 SetLayerPropertiesForTesting(great_grand_child_
.get(), IdentityMatrix
,
97 transform_origin
, position
, bounds
, true);
99 root_
->SetBounds(clip_bounds
);
100 scroll_layer_
->SetScrollClipLayerId(root_
->id());
101 child_
->SetScrollClipLayerId(root_
->id());
102 grand_child_
->SetScrollClipLayerId(root_
->id());
104 grand_child_
->AddChild(great_grand_child_
);
105 child_
->AddChild(grand_child_
);
106 child_transform_layer_
->AddChild(child_
);
107 scroll_layer_
->AddChild(child_transform_layer_
);
108 root_
->AddChild(scroll_layer_
);
110 layer_tree_host_
->SetRootLayer(root_
);
113 void CommitAndUpdateImplPointers() {
114 RenderSurfaceLayerList render_surface_layer_list
;
115 LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting
inputs(
116 root_
.get(), root_
->bounds(), &render_surface_layer_list
);
117 LayerTreeHostCommon::CalculateDrawProperties(&inputs
);
118 root_impl_
= layer_tree_host_
->CommitAndCreateLayerImplTree();
119 scroll_layer_impl_
= root_impl_
->children()[0];
120 child_transform_layer_impl_
= scroll_layer_impl_
->children()[0];
121 child_impl_
= child_transform_layer_impl_
->children()[0];
122 grand_child_impl_
= child_impl_
->children()[0];
123 great_grand_child_impl_
= grand_child_impl_
->children()[0];
127 FakeLayerTreeHostClient fake_client_
;
128 TestTaskGraphRunner task_graph_runner_
;
129 scoped_ptr
<FakeLayerTreeHost
> layer_tree_host_
;
130 LayerSettings layer_settings_
;
131 scoped_refptr
<Layer
> root_
;
132 scoped_refptr
<Layer
> scroll_layer_
;
133 scoped_refptr
<Layer
> child_transform_layer_
;
134 scoped_refptr
<Layer
> child_
;
135 scoped_refptr
<Layer
> grand_child_
;
136 scoped_refptr
<Layer
> great_grand_child_
;
137 LayerImpl
* root_impl_
;
138 LayerImpl
* scroll_layer_impl_
;
139 LayerImpl
* child_transform_layer_impl_
;
140 LayerImpl
* child_impl_
;
141 LayerImpl
* grand_child_impl_
;
142 LayerImpl
* great_grand_child_impl_
;
144 LayerPositionConstraint fixed_to_top_left_
;
145 LayerPositionConstraint fixed_to_bottom_right_
;
150 void SetFixedContainerSizeDelta(LayerImpl
* scroll_layer
,
151 const gfx::Vector2d
& delta
) {
152 DCHECK(scroll_layer
);
153 DCHECK(scroll_layer
->scrollable());
155 LayerImpl
* container_layer
= scroll_layer
->scroll_clip_layer();
156 container_layer
->SetBoundsDelta(delta
);
160 TEST_F(LayerPositionConstraintTest
,
161 ScrollCompensationForFixedPositionLayerWithDirectContainer
) {
162 // This test checks for correct scroll compensation when the fixed-position
163 // container is the direct parent of the fixed-position layer.
164 child_
->SetIsContainerForFixedPositionLayers(true);
165 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
167 CommitAndUpdateImplPointers();
169 // Case 1: scroll delta of 0, 0
170 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
171 ExecuteCalculateDrawProperties(root_impl_
);
173 gfx::Transform expected_child_transform
;
174 gfx::Transform expected_grand_child_transform
= expected_child_transform
;
176 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
177 child_impl_
->draw_transform());
178 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
179 grand_child_impl_
->draw_transform());
181 // Case 2: scroll delta of 10, 10
182 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
183 ExecuteCalculateDrawProperties(root_impl_
);
185 // Here the child is affected by scroll delta, but the fixed position
186 // grand_child should not be affected.
187 expected_child_transform
.MakeIdentity();
188 expected_child_transform
.Translate(-10.0, -10.0);
190 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
191 child_impl_
->draw_transform());
192 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
193 grand_child_impl_
->draw_transform());
195 // Case 3: fixed-container size delta of 20, 20
196 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
197 ExecuteCalculateDrawProperties(root_impl_
);
199 // Top-left fixed-position layer should not be affected by container size.
200 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
201 child_impl_
->draw_transform());
202 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
203 grand_child_impl_
->draw_transform());
205 // Case 4: Bottom-right fixed-position layer.
206 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
207 CommitAndUpdateImplPointers();
209 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
210 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
211 ExecuteCalculateDrawProperties(root_impl_
);
213 // Bottom-right fixed-position layer moves as container resizes.
214 expected_grand_child_transform
.MakeIdentity();
215 // Apply size delta from the child(container) layer.
216 expected_grand_child_transform
.Translate(20.0, 20.0);
218 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
219 child_impl_
->draw_transform());
220 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
221 grand_child_impl_
->draw_transform());
224 TEST_F(LayerPositionConstraintTest
,
225 ScrollCompensationForFixedPositionLayerWithDistantContainer
) {
226 // This test checks for correct scroll compensation when the fixed-position
227 // container is NOT the direct parent of the fixed-position layer.
228 child_
->SetIsContainerForFixedPositionLayers(true);
229 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
230 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
232 CommitAndUpdateImplPointers();
234 // Case 1: scroll delta of 0, 0
235 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
236 ExecuteCalculateDrawProperties(root_impl_
);
238 gfx::Transform expected_child_transform
;
239 gfx::Transform expected_grand_child_transform
;
240 expected_grand_child_transform
.Translate(8.0, 6.0);
242 gfx::Transform expected_great_grand_child_transform
=
243 expected_grand_child_transform
;
245 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
246 child_impl_
->draw_transform());
247 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
248 grand_child_impl_
->draw_transform());
249 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
250 great_grand_child_impl_
->draw_transform());
252 // Case 2: scroll delta of 10, 10
253 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
254 ExecuteCalculateDrawProperties(root_impl_
);
256 // Here the child and grand_child are affected by scroll delta, but the fixed
257 // position great_grand_child should not be affected.
258 expected_child_transform
.MakeIdentity();
259 expected_child_transform
.Translate(-10.0, -10.0);
260 expected_grand_child_transform
.MakeIdentity();
261 expected_grand_child_transform
.Translate(-2.0, -4.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());
266 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
267 great_grand_child_impl_
->draw_transform());
269 // Case 3: fixed-container size delta of 20, 20
270 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
271 ExecuteCalculateDrawProperties(root_impl_
);
273 // Top-left fixed-position layer should not be affected by container size.
274 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
275 child_impl_
->draw_transform());
276 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
277 grand_child_impl_
->draw_transform());
278 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
279 great_grand_child_impl_
->draw_transform());
281 // Case 4: Bottom-right fixed-position layer.
282 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
283 CommitAndUpdateImplPointers();
284 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
285 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
286 ExecuteCalculateDrawProperties(root_impl_
);
288 // Bottom-right fixed-position layer moves as container resizes.
289 expected_great_grand_child_transform
.MakeIdentity();
290 // Apply size delta from the child(container) layer.
291 expected_great_grand_child_transform
.Translate(20.0, 20.0);
292 // Apply layer position from the grand child layer.
293 expected_great_grand_child_transform
.Translate(8.0, 6.0);
295 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
296 child_impl_
->draw_transform());
297 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
298 grand_child_impl_
->draw_transform());
299 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
300 great_grand_child_impl_
->draw_transform());
303 TEST_F(LayerPositionConstraintTest
,
304 ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas
) {
305 // This test checks for correct scroll compensation when the fixed-position
306 // container has multiple ancestors that have nonzero scroll delta before
307 // reaching the space where the layer is fixed.
308 gfx::Transform rotation_about_z
;
309 rotation_about_z
.RotateAboutZAxis(90.0);
311 child_transform_layer_
->SetIsContainerForFixedPositionLayers(true);
312 child_transform_layer_
->SetTransform(rotation_about_z
);
313 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
314 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
316 CommitAndUpdateImplPointers();
318 // Case 1: scroll delta of 0, 0
319 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
320 ExecuteCalculateDrawProperties(root_impl_
);
322 gfx::Transform expected_child_transform
;
323 expected_child_transform
.PreconcatTransform(rotation_about_z
);
325 gfx::Transform expected_grand_child_transform
;
326 expected_grand_child_transform
.PreconcatTransform(
327 rotation_about_z
); // child's local transform is inherited
328 // translation because of position occurs before layer's local transform.
329 expected_grand_child_transform
.Translate(8.0, 6.0);
331 gfx::Transform expected_great_grand_child_transform
=
332 expected_grand_child_transform
;
334 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
335 child_impl_
->draw_transform());
336 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
337 grand_child_impl_
->draw_transform());
338 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
339 great_grand_child_impl_
->draw_transform());
341 // Case 2: scroll delta of 10, 20
342 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 0));
343 grand_child_impl_
->SetScrollDelta(gfx::Vector2d(5, 0));
344 ExecuteCalculateDrawProperties(root_impl_
);
346 // Here the child and grand_child are affected by scroll delta, but the fixed
347 // position great_grand_child should not be affected.
348 expected_child_transform
.MakeIdentity();
349 expected_child_transform
.PreconcatTransform(rotation_about_z
);
350 expected_child_transform
.Translate(-10.0, 0.0); // scroll delta
352 expected_grand_child_transform
.MakeIdentity();
353 expected_grand_child_transform
.PreconcatTransform(
354 rotation_about_z
); // child's local transform is inherited
355 expected_grand_child_transform
.Translate(
356 -10.0, 0.0); // child's scroll delta is inherited
357 expected_grand_child_transform
.Translate(-5.0,
358 0.0); // grand_child's scroll delta
359 // translation because of position
360 expected_grand_child_transform
.Translate(8.0, 6.0);
362 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
363 child_impl_
->draw_transform());
364 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
365 grand_child_impl_
->draw_transform());
366 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
367 great_grand_child_impl_
->draw_transform());
370 TEST_F(LayerPositionConstraintTest
,
371 ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms
) {
372 // This test checks for correct scroll compensation when the fixed-position
373 // container contributes to a different render surface than the fixed-position
374 // layer. In this case, the surface draw transforms also have to be accounted
375 // for when checking the scroll delta.
376 child_
->SetIsContainerForFixedPositionLayers(true);
377 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
378 grand_child_
->SetForceRenderSurface(true);
379 great_grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
381 gfx::Transform rotation_about_z
;
382 rotation_about_z
.RotateAboutZAxis(90.0);
383 great_grand_child_
->SetTransform(rotation_about_z
);
385 CommitAndUpdateImplPointers();
387 // Case 1: scroll delta of 0, 0
388 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
389 ExecuteCalculateDrawProperties(root_impl_
);
391 gfx::Transform expected_child_transform
;
392 gfx::Transform expected_surface_draw_transform
;
393 expected_surface_draw_transform
.Translate(8.0, 6.0);
394 gfx::Transform expected_grand_child_transform
;
395 gfx::Transform expected_great_grand_child_transform
;
396 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
397 EXPECT_TRUE(grand_child_impl_
->render_surface());
398 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
399 child_impl_
->draw_transform());
400 EXPECT_TRANSFORMATION_MATRIX_EQ(
401 expected_surface_draw_transform
,
402 grand_child_impl_
->render_surface()->draw_transform());
403 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
404 grand_child_impl_
->draw_transform());
405 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
406 great_grand_child_impl_
->draw_transform());
408 // Case 2: scroll delta of 10, 30
409 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
410 ExecuteCalculateDrawProperties(root_impl_
);
412 // Here the grand_child remains unchanged, because it scrolls along with the
413 // render surface, and the translation is actually in the render surface. But,
414 // the fixed position great_grand_child is more awkward: its actually being
415 // drawn with respect to the render surface, but it needs to remain fixed with
416 // resepct to a container beyond that surface. So, the net result is that,
417 // unlike previous tests where the fixed position layer's transform remains
418 // unchanged, here the fixed position layer's transform explicitly contains
419 // the translation that cancels out the scroll.
420 expected_child_transform
.MakeIdentity();
421 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
423 expected_surface_draw_transform
.MakeIdentity();
424 expected_surface_draw_transform
.Translate(-10.0, -30.0); // scroll delta
425 expected_surface_draw_transform
.Translate(8.0, 6.0);
427 expected_great_grand_child_transform
.MakeIdentity();
428 // explicit canceling out the scroll delta that gets embedded in the fixed
429 // position layer's surface.
430 expected_great_grand_child_transform
.Translate(10.0, 30.0);
431 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
433 EXPECT_TRUE(grand_child_impl_
->render_surface());
434 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
435 child_impl_
->draw_transform());
436 EXPECT_TRANSFORMATION_MATRIX_EQ(
437 expected_surface_draw_transform
,
438 grand_child_impl_
->render_surface()->draw_transform());
439 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
440 grand_child_impl_
->draw_transform());
441 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
442 great_grand_child_impl_
->draw_transform());
444 // Case 3: fixed-container size delta of 20, 20
445 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
446 ExecuteCalculateDrawProperties(root_impl_
);
448 // Top-left fixed-position layer should not be affected by container size.
449 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
450 child_impl_
->draw_transform());
451 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
452 grand_child_impl_
->draw_transform());
453 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
454 great_grand_child_impl_
->draw_transform());
456 // Case 4: Bottom-right fixed-position layer.
457 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
459 CommitAndUpdateImplPointers();
460 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
461 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
463 ExecuteCalculateDrawProperties(root_impl_
);
465 // Bottom-right fixed-position layer moves as container resizes.
466 expected_great_grand_child_transform
.MakeIdentity();
467 // explicit canceling out the scroll delta that gets embedded in the fixed
468 // position layer's surface.
469 expected_great_grand_child_transform
.Translate(10.0, 30.0);
470 // Also apply size delta in the child(container) layer space.
471 expected_great_grand_child_transform
.Translate(20.0, 20.0);
472 expected_great_grand_child_transform
.PreconcatTransform(rotation_about_z
);
474 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
475 child_impl_
->draw_transform());
476 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
477 grand_child_impl_
->draw_transform());
478 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
479 great_grand_child_impl_
->draw_transform());
482 TEST_F(LayerPositionConstraintTest
,
483 ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces
) {
484 // This test checks for correct scroll compensation when the fixed-position
485 // container contributes to a different render surface than the fixed-position
486 // layer, with additional render surfaces in-between. This checks that the
487 // conversion to ancestor surfaces is accumulated properly in the final matrix
490 // Add one more layer to the test tree for this scenario.
491 scoped_refptr
<Layer
> fixed_position_child
=
492 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
493 SetLayerPropertiesForTesting(fixed_position_child
.get(), gfx::Transform(),
494 gfx::Point3F(), gfx::PointF(),
495 gfx::Size(100, 100), true);
496 great_grand_child_
->AddChild(fixed_position_child
);
498 // Actually set up the scenario here.
499 child_
->SetIsContainerForFixedPositionLayers(true);
500 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
501 grand_child_
->SetForceRenderSurface(true);
502 great_grand_child_
->SetPosition(gfx::PointF(40.f
, 60.f
));
503 great_grand_child_
->SetForceRenderSurface(true);
504 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
506 // The additional rotation, which is non-commutative with translations, helps
507 // to verify that we have correct order-of-operations in the final scroll
508 // compensation. Note that rotating about the center of the layer ensures we
509 // do not accidentally clip away layers that we want to test.
510 gfx::Transform rotation_about_z
;
511 rotation_about_z
.Translate(50.0, 50.0);
512 rotation_about_z
.RotateAboutZAxis(90.0);
513 rotation_about_z
.Translate(-50.0, -50.0);
514 fixed_position_child
->SetTransform(rotation_about_z
);
516 CommitAndUpdateImplPointers();
517 LayerImpl
* fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
519 // Case 1: scroll delta of 0, 0
520 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
521 ExecuteCalculateDrawProperties(root_impl_
);
523 gfx::Transform expected_child_transform
;
525 gfx::Transform expected_grand_child_surface_draw_transform
;
526 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
528 gfx::Transform expected_grand_child_transform
;
530 gfx::Transform expected_great_grand_child_surface_draw_transform
;
531 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
533 gfx::Transform expected_great_grand_child_transform
;
535 gfx::Transform expected_fixed_position_child_transform
;
536 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
538 EXPECT_TRUE(grand_child_impl_
->render_surface());
539 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
540 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
541 child_impl_
->draw_transform());
542 EXPECT_TRANSFORMATION_MATRIX_EQ(
543 expected_grand_child_surface_draw_transform
,
544 grand_child_impl_
->render_surface()->draw_transform());
545 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
546 grand_child_impl_
->draw_transform());
547 EXPECT_TRANSFORMATION_MATRIX_EQ(
548 expected_great_grand_child_surface_draw_transform
,
549 great_grand_child_impl_
->render_surface()->draw_transform());
550 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
551 great_grand_child_impl_
->draw_transform());
552 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
553 fixed_position_child_impl
->draw_transform());
555 // Case 2: scroll delta of 10, 30
556 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
557 ExecuteCalculateDrawProperties(root_impl_
);
559 expected_child_transform
.MakeIdentity();
560 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
562 expected_grand_child_surface_draw_transform
.MakeIdentity();
563 expected_grand_child_surface_draw_transform
.Translate(-10.0,
564 -30.0); // scroll delta
565 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
567 // grand_child, great_grand_child, and great_grand_child's surface are not
568 // expected to change, since they are all not fixed, and they are all drawn
569 // with respect to grand_child's surface that already has the scroll delta
572 // But the great-great grandchild, "fixed_position_child", should have a
573 // transform that explicitly cancels out the scroll delta.
574 expected_fixed_position_child_transform
.MakeIdentity();
575 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
576 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
578 EXPECT_TRUE(grand_child_impl_
->render_surface());
579 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
580 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
581 child_impl_
->draw_transform());
582 EXPECT_TRANSFORMATION_MATRIX_EQ(
583 expected_grand_child_surface_draw_transform
,
584 grand_child_impl_
->render_surface()->draw_transform());
585 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
586 grand_child_impl_
->draw_transform());
587 EXPECT_TRANSFORMATION_MATRIX_EQ(
588 expected_great_grand_child_surface_draw_transform
,
589 great_grand_child_impl_
->render_surface()->draw_transform());
590 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
591 great_grand_child_impl_
->draw_transform());
592 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
593 fixed_position_child_impl
->draw_transform());
595 // Case 3: fixed-container size delta of 20, 20
596 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
597 ExecuteCalculateDrawProperties(root_impl_
);
599 // Top-left fixed-position layer should not be affected by container size.
600 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
601 child_impl_
->draw_transform());
602 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
603 grand_child_impl_
->draw_transform());
604 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
605 great_grand_child_impl_
->draw_transform());
606 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
607 fixed_position_child_impl
->draw_transform());
609 // Case 4: Bottom-right fixed-position layer.
610 fixed_position_child
->SetPositionConstraint(fixed_to_bottom_right_
);
611 CommitAndUpdateImplPointers();
612 fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
613 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
614 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
615 ExecuteCalculateDrawProperties(root_impl_
);
617 // Bottom-right fixed-position layer moves as container resizes.
618 expected_fixed_position_child_transform
.MakeIdentity();
619 // explicit canceling out the scroll delta that gets embedded in the fixed
620 // position layer's surface.
621 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
622 // Also apply size delta in the child(container) layer space.
623 expected_fixed_position_child_transform
.Translate(20.0, 20.0);
624 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
626 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
627 child_impl_
->draw_transform());
628 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
629 grand_child_impl_
->draw_transform());
630 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
631 great_grand_child_impl_
->draw_transform());
632 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
633 fixed_position_child_impl
->draw_transform());
637 LayerPositionConstraintTest
,
638 ScrollCompensationForFixedPositionLayerWithMultipleSurfacesAndTransforms
) {
639 // This test checks for correct scroll compensation when the fixed-position
640 // container contributes to a different render surface than the fixed-position
641 // layer, with additional render surfaces in-between, and the fixed-position
642 // container is transformed. This checks that the conversion to ancestor
643 // surfaces is accumulated properly in the final matrix transform.
645 // Add one more layer to the test tree for this scenario.
646 scoped_refptr
<Layer
> fixed_position_child
=
647 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
648 SetLayerPropertiesForTesting(fixed_position_child
.get(), gfx::Transform(),
649 gfx::Point3F(), gfx::PointF(),
650 gfx::Size(100, 100), true);
651 great_grand_child_
->AddChild(fixed_position_child
);
653 // Actually set up the scenario here.
654 child_transform_layer_
->SetIsContainerForFixedPositionLayers(true);
655 grand_child_
->SetPosition(gfx::PointF(8.f
, 6.f
));
656 grand_child_
->SetForceRenderSurface(true);
657 great_grand_child_
->SetPosition(gfx::PointF(40.f
, 60.f
));
658 great_grand_child_
->SetForceRenderSurface(true);
659 fixed_position_child
->SetPositionConstraint(fixed_to_top_left_
);
661 // The additional rotations, which are non-commutative with translations, help
662 // to verify that we have correct order-of-operations in the final scroll
663 // compensation. Note that rotating about the center of the layer ensures we
664 // do not accidentally clip away layers that we want to test.
665 gfx::Transform rotation_about_z
;
666 rotation_about_z
.Translate(50.0, 50.0);
667 rotation_about_z
.RotateAboutZAxis(90.0);
668 rotation_about_z
.Translate(-50.0, -50.0);
669 child_transform_layer_
->SetTransform(rotation_about_z
);
670 fixed_position_child
->SetTransform(rotation_about_z
);
672 CommitAndUpdateImplPointers();
673 LayerImpl
* fixed_position_child_impl
= great_grand_child_impl_
->children()[0];
675 // Case 1: scroll delta of 0, 0
676 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
677 ExecuteCalculateDrawProperties(root_impl_
);
679 gfx::Transform expected_child_transform
;
680 expected_child_transform
.PreconcatTransform(rotation_about_z
);
682 gfx::Transform expected_grand_child_surface_draw_transform
;
683 expected_grand_child_surface_draw_transform
.PreconcatTransform(
685 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
687 gfx::Transform expected_grand_child_transform
;
689 gfx::Transform expected_great_grand_child_surface_draw_transform
;
690 expected_great_grand_child_surface_draw_transform
.Translate(40.0, 60.0);
692 gfx::Transform expected_great_grand_child_transform
;
694 gfx::Transform expected_fixed_position_child_transform
;
695 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
697 EXPECT_TRUE(grand_child_impl_
->render_surface());
698 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
699 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
700 child_impl_
->draw_transform());
701 EXPECT_TRANSFORMATION_MATRIX_EQ(
702 expected_grand_child_surface_draw_transform
,
703 grand_child_impl_
->render_surface()->draw_transform());
704 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
705 grand_child_impl_
->draw_transform());
706 EXPECT_TRANSFORMATION_MATRIX_EQ(
707 expected_great_grand_child_surface_draw_transform
,
708 great_grand_child_impl_
->render_surface()->draw_transform());
709 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
710 great_grand_child_impl_
->draw_transform());
711 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
712 fixed_position_child_impl
->draw_transform());
714 // Case 2: scroll delta of 10, 30
715 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 30));
716 ExecuteCalculateDrawProperties(root_impl_
);
718 expected_child_transform
.MakeIdentity();
719 expected_child_transform
.PreconcatTransform(rotation_about_z
);
720 expected_child_transform
.Translate(-10.0, -30.0); // scroll delta
722 expected_grand_child_surface_draw_transform
.MakeIdentity();
723 expected_grand_child_surface_draw_transform
.PreconcatTransform(
725 expected_grand_child_surface_draw_transform
.Translate(-10.0,
726 -30.0); // scroll delta
727 expected_grand_child_surface_draw_transform
.Translate(8.0, 6.0);
729 // grand_child, great_grand_child, and great_grand_child's surface are not
730 // expected to change, since they are all not fixed, and they are all drawn
731 // with respect to grand_child's surface that already has the scroll delta
734 // But the great-great grandchild, "fixed_position_child", should have a
735 // transform that explicitly cancels out the scroll delta.
736 expected_fixed_position_child_transform
.MakeIdentity();
737 // explicit canceling out the scroll delta that gets embedded in the fixed
738 // position layer's surface.
739 expected_fixed_position_child_transform
.Translate(10.0, 30.0);
740 expected_fixed_position_child_transform
.PreconcatTransform(rotation_about_z
);
742 EXPECT_TRUE(grand_child_impl_
->render_surface());
743 EXPECT_TRUE(great_grand_child_impl_
->render_surface());
744 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
745 child_impl_
->draw_transform());
746 EXPECT_TRANSFORMATION_MATRIX_EQ(
747 expected_grand_child_surface_draw_transform
,
748 grand_child_impl_
->render_surface()->draw_transform());
749 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
750 grand_child_impl_
->draw_transform());
751 EXPECT_TRANSFORMATION_MATRIX_EQ(
752 expected_great_grand_child_surface_draw_transform
,
753 great_grand_child_impl_
->render_surface()->draw_transform());
754 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
755 great_grand_child_impl_
->draw_transform());
756 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform
,
757 fixed_position_child_impl
->draw_transform());
760 TEST_F(LayerPositionConstraintTest
,
761 ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface
) {
762 // This test checks for correct scroll compensation when the fixed-position
763 // container itself has a render surface. In this case, the container layer
764 // should be treated like a layer that contributes to a render target, and
765 // that render target is completely irrelevant; it should not affect the
766 // scroll compensation.
767 child_
->SetIsContainerForFixedPositionLayers(true);
768 child_
->SetForceRenderSurface(true);
769 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
771 CommitAndUpdateImplPointers();
773 // Case 1: scroll delta of 0, 0
774 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
775 ExecuteCalculateDrawProperties(root_impl_
);
777 gfx::Transform expected_surface_draw_transform
;
778 gfx::Transform expected_child_transform
;
779 gfx::Transform expected_grand_child_transform
;
780 EXPECT_TRUE(child_impl_
->render_surface());
781 EXPECT_TRANSFORMATION_MATRIX_EQ(
782 expected_surface_draw_transform
,
783 child_impl_
->render_surface()->draw_transform());
784 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
785 child_impl_
->draw_transform());
786 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
787 grand_child_impl_
->draw_transform());
789 // Case 2: scroll delta of 10, 10
790 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
791 ExecuteCalculateDrawProperties(root_impl_
);
793 // The surface is translated by scroll delta, the child transform doesn't
794 // change because it scrolls along with the surface, but the fixed position
795 // grand_child needs to compensate for the scroll translation.
796 expected_surface_draw_transform
.MakeIdentity();
797 expected_surface_draw_transform
.Translate(-10.0, -10.0);
798 expected_grand_child_transform
.MakeIdentity();
799 expected_grand_child_transform
.Translate(10.0, 10.0);
801 EXPECT_TRUE(child_impl_
->render_surface());
802 EXPECT_TRANSFORMATION_MATRIX_EQ(
803 expected_surface_draw_transform
,
804 child_impl_
->render_surface()->draw_transform());
805 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
806 child_impl_
->draw_transform());
807 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
808 grand_child_impl_
->draw_transform());
810 // Case 3: fixed-container size delta of 20, 20
811 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
812 ExecuteCalculateDrawProperties(root_impl_
);
814 // Top-left fixed-position layer should not be affected by container size.
815 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
816 child_impl_
->draw_transform());
817 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
818 grand_child_impl_
->draw_transform());
820 // Case 4: Bottom-right fixed-position layer.
821 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
822 CommitAndUpdateImplPointers();
823 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
824 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
825 ExecuteCalculateDrawProperties(root_impl_
);
827 // Bottom-right fixed-position layer moves as container resizes.
828 expected_grand_child_transform
.MakeIdentity();
829 // The surface is translated by scroll delta, the child transform doesn't
830 // change because it scrolls along with the surface, but the fixed position
831 // grand_child needs to compensate for the scroll translation.
832 expected_grand_child_transform
.Translate(10.0, 10.0);
833 // Apply size delta from the child(container) layer.
834 expected_grand_child_transform
.Translate(20.0, 20.0);
836 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
837 child_impl_
->draw_transform());
838 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
839 grand_child_impl_
->draw_transform());
842 TEST_F(LayerPositionConstraintTest
,
843 ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer
) {
844 // This test checks the scenario where a fixed-position layer also happens to
845 // be a container itself for a descendant fixed position layer. In particular,
846 // the layer should not accidentally be fixed to itself.
847 child_
->SetIsContainerForFixedPositionLayers(true);
848 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
850 // This should not confuse the grand_child. If correct, the grand_child would
851 // still be considered fixed to its container (i.e. "child").
852 grand_child_
->SetIsContainerForFixedPositionLayers(true);
854 CommitAndUpdateImplPointers();
856 // Case 1: scroll delta of 0, 0
857 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
858 ExecuteCalculateDrawProperties(root_impl_
);
860 gfx::Transform expected_child_transform
;
861 gfx::Transform expected_grand_child_transform
;
862 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
863 child_impl_
->draw_transform());
864 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
865 grand_child_impl_
->draw_transform());
867 // Case 2: scroll delta of 10, 10
868 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
869 ExecuteCalculateDrawProperties(root_impl_
);
871 // Here the child is affected by scroll delta, but the fixed position
872 // grand_child should not be affected.
873 expected_child_transform
.MakeIdentity();
874 expected_child_transform
.Translate(-10.0, -10.0);
875 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
876 child_impl_
->draw_transform());
877 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
878 grand_child_impl_
->draw_transform());
880 // Case 3: fixed-container size delta of 20, 20
881 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
882 ExecuteCalculateDrawProperties(root_impl_
);
884 // Top-left fixed-position layer should not be affected by container size.
885 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
886 child_impl_
->draw_transform());
887 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
888 grand_child_impl_
->draw_transform());
890 // Case 4: Bottom-right fixed-position layer.
891 grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
892 CommitAndUpdateImplPointers();
893 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
894 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
896 ExecuteCalculateDrawProperties(root_impl_
);
898 // Bottom-right fixed-position layer moves as container resizes.
899 expected_grand_child_transform
.MakeIdentity();
900 // Apply size delta from the child(container) layer.
901 expected_grand_child_transform
.Translate(20.0, 20.0);
903 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
904 child_impl_
->draw_transform());
905 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
906 grand_child_impl_
->draw_transform());
909 TEST_F(LayerPositionConstraintTest
,
910 ScrollCompensationForFixedWithinFixedWithSameContainer
) {
911 // This test checks scroll compensation for a fixed-position layer that is
912 // inside of another fixed-position layer and both share the same container.
913 // In this situation, the parent fixed-position layer will receive
914 // the scroll compensation, and the child fixed-position layer does not
915 // need to compensate further.
916 child_
->SetIsContainerForFixedPositionLayers(true);
917 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
919 // Note carefully - great_grand_child is fixed to bottom right, to test
920 // sizeDelta being applied correctly; the compensation skips the grand_child
921 // because it is fixed to top left.
922 great_grand_child_
->SetPositionConstraint(fixed_to_bottom_right_
);
924 CommitAndUpdateImplPointers();
926 // Case 1: scrollDelta
927 child_impl_
->SetScrollDelta(gfx::Vector2d(10, 10));
928 ExecuteCalculateDrawProperties(root_impl_
);
930 // Here the child is affected by scroll delta, but the fixed position
931 // grand_child should not be affected.
932 gfx::Transform expected_child_transform
;
933 expected_child_transform
.Translate(-10.0, -10.0);
935 gfx::Transform expected_grand_child_transform
;
936 gfx::Transform expected_great_grand_child_transform
;
938 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
939 child_impl_
->draw_transform());
940 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
941 grand_child_impl_
->draw_transform());
942 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
943 great_grand_child_impl_
->draw_transform());
946 child_impl_
->SetScrollDelta(gfx::Vector2d(0, 0));
947 SetFixedContainerSizeDelta(child_impl_
, gfx::Vector2d(20, 20));
948 ExecuteCalculateDrawProperties(root_impl_
);
950 expected_child_transform
.MakeIdentity();
952 expected_grand_child_transform
.MakeIdentity();
954 // Fixed to bottom-right, size-delta compensation is applied.
955 expected_great_grand_child_transform
.MakeIdentity();
956 expected_great_grand_child_transform
.Translate(20.0, 20.0);
958 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform
,
959 child_impl_
->draw_transform());
960 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform
,
961 grand_child_impl_
->draw_transform());
962 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform
,
963 great_grand_child_impl_
->draw_transform());
966 TEST_F(LayerPositionConstraintTest
,
967 ScrollCompensationForFixedWithinFixedWithInterveningContainer
) {
968 // This test checks scroll compensation for a fixed-position layer that is
969 // inside of another fixed-position layer, but they have different fixed
970 // position containers. In this situation, the child fixed-position element
971 // would still have to compensate with respect to its container.
973 // Add one more layer to the hierarchy for this test.
974 scoped_refptr
<Layer
> great_great_grand_child
=
975 make_scoped_refptr(new LayerWithForcedDrawsContent(layer_settings_
));
976 great_grand_child_
->AddChild(great_great_grand_child
);
978 child_
->SetIsContainerForFixedPositionLayers(true);
979 grand_child_
->SetPositionConstraint(fixed_to_top_left_
);
980 great_grand_child_
->SetIsContainerForFixedPositionLayers(true);
981 great_grand_child_
->SetScrollClipLayerId(root_
->id());
982 great_great_grand_child
->SetPositionConstraint(fixed_to_top_left_
);
984 CommitAndUpdateImplPointers();
986 LayerImpl
* container1
= child_impl_
;
987 LayerImpl
* fixed_to_container1
= grand_child_impl_
;
988 LayerImpl
* container2
= great_grand_child_impl_
;
989 LayerImpl
* fixed_to_container2
= container2
->children()[0];
991 container1
->SetScrollDelta(gfx::Vector2d(0, 15));
992 container2
->SetScrollDelta(gfx::Vector2d(30, 0));
993 ExecuteCalculateDrawProperties(root_impl_
);
995 gfx::Transform expected_container1_transform
;
996 expected_container1_transform
.Translate(0.0, -15.0);
998 gfx::Transform expected_fixed_to_container1_transform
;
1000 // Since the container is a descendant of the fixed layer above,
1001 // the expected draw transform for container2 would not
1002 // include the scrollDelta that was applied to container1.
1003 gfx::Transform expected_container2_transform
;
1004 expected_container2_transform
.Translate(-30.0, 0.0);
1006 gfx::Transform expected_fixed_to_container2_transform
;
1008 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container1_transform
,
1009 container1
->draw_transform());
1011 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container1_transform
,
1012 fixed_to_container1
->draw_transform());
1014 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_container2_transform
,
1015 container2
->draw_transform());
1017 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_to_container2_transform
,
1018 fixed_to_container2
->draw_transform());