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