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