1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/layers/layer_position_constraint.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/layers/layer_impl.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/test/fake_impl_proxy.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/test/fake_layer_tree_host_impl.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/test/geometry_test_utils.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/trees/layer_tree_host_common.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace cc { 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SetLayerPropertiesForTesting(LayerImpl* layer, 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Transform& transform, 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Transform& sublayer_transform, 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::PointF anchor, 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::PointF position, 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Size bounds, 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool preserves3d) { 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) layer->SetTransform(transform); 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) layer->SetSublayerTransform(sublayer_transform); 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) layer->SetAnchorPoint(anchor); 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) layer->SetPosition(position); 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) layer->SetBounds(bounds); 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) layer->SetPreserves3d(preserves3d); 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) layer->SetContentBounds(bounds); 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExecuteCalculateDrawProperties(LayerImpl* root_layer, 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) float device_scale_factor, 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) float page_scale_factor, 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* page_scale_application_layer, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool can_use_lcd_text) { 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform identity_matrix; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<LayerImpl*> dummy_render_surface_layer_list; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Size device_viewport_size = 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Size(root_layer->bounds().width() * device_scale_factor, 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_layer->bounds().height() * device_scale_factor); 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We are probably not testing what is intended if the root_layer bounds are 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // empty. 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!root_layer->bounds().IsEmpty()); 49558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( 50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch root_layer, device_viewport_size, &dummy_render_surface_layer_list); 51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch inputs.device_scale_factor = device_scale_factor; 52558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch inputs.page_scale_factor = page_scale_factor; 53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch inputs.page_scale_application_layer = page_scale_application_layer; 54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch inputs.can_use_lcd_text = can_use_lcd_text; 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LayerTreeHostCommon::CalculateDrawProperties(&inputs); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExecuteCalculateDrawProperties(LayerImpl* root_layer) { 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* page_scale_application_layer = NULL; 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties( 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_layer, 1.f, 1.f, page_scale_application_layer, false); 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class LayerPositionConstraintTest : public testing::Test { 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerPositionConstraintTest() 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : host_impl_(&proxy_) { 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_ = CreateTreeForTest(); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_to_top_left_.set_is_fixed_position(true); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_to_bottom_right_.set_is_fixed_position(true); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_to_bottom_right_.set_is_fixed_to_right_edge(true); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_to_bottom_right_.set_is_fixed_to_bottom_edge(true); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<LayerImpl> CreateTreeForTest() { 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<LayerImpl> root = 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 1); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<LayerImpl> child = 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 2); 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<LayerImpl> grand_child = 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 3); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<LayerImpl> great_grand_child = 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 4); 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform IdentityMatrix; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::PointF anchor; 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::PointF position; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Size bounds(100, 100); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetLayerPropertiesForTesting(root.get(), 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMatrix, 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMatrix, 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) anchor, 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) position, 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bounds, 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetLayerPropertiesForTesting(child.get(), 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMatrix, 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMatrix, 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) anchor, 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) position, 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bounds, 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetLayerPropertiesForTesting(grand_child.get(), 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMatrix, 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMatrix, 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) anchor, 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) position, 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bounds, 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetLayerPropertiesForTesting(great_grand_child.get(), 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMatrix, 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMatrix, 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) anchor, 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) position, 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bounds, 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) root->SetMaxScrollOffset(gfx::Vector2d(100, 100)); 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) root->SetScrollable(true); 120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) child->SetMaxScrollOffset(gfx::Vector2d(100, 100)); 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) child->SetScrollable(true); 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) grand_child->SetMaxScrollOffset(gfx::Vector2d(100, 100)); 123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) grand_child->SetScrollable(true); 124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->AddChild(great_grand_child.Pass()); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->AddChild(grand_child.Pass()); 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root->AddChild(child.Pass()); 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return root.Pass(); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FakeImplProxy proxy_; 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FakeLayerTreeHostImpl host_impl_; 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<LayerImpl> root_; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerPositionConstraint fixed_to_top_left_; 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerPositionConstraint fixed_to_bottom_right_; 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionLayerWithDirectContainer) { 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks for correct scroll compensation when the fixed-position 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container is the direct parent of the fixed-position layer. 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetIsContainerForFixedPositionLayers(true); 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_top_left_); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: scroll delta of 0, 0 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(0, 0)); 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_child_transform; 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_transform = expected_child_transform; 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: scroll delta of 10, 10 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(10, 10)); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here the child is affected by scroll delta, but the fixed position 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // grand_child should not be affected. 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.MakeIdentity(); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.Translate(-10.0, -10.0); 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_bottom_right_); 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Bottom-right fixed-position layer moves as container resizes. 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.MakeIdentity(); 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply size delta from the child(container) layer. 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(20.0, 20.0); 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionLayerWithTransformedDirectContainer) { 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks for correct scroll compensation when the fixed-position 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container is the direct parent of the fixed-position layer, but that 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container is transformed. In this case, the fixed position element 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // inherits the container's transform, but the scroll delta that has to be 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // undone should not be affected by that transform. 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Transforms are in general non-commutative; using something like a 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // non-uniform scale helps to verify that translations and non-uniform scales 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // are applied in the correct order. 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This scale will cause child and grand_child to be effectively 200 x 800 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // with respect to the render target. 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform non_uniform_scale; 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) non_uniform_scale.Scale(2.0, 8.0); 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetTransform(non_uniform_scale); 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetIsContainerForFixedPositionLayers(true); 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_top_left_); 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: scroll delta of 0, 0 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(0, 0)); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_child_transform; 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.PreconcatTransform(non_uniform_scale); 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_transform = expected_child_transform; 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: scroll delta of 10, 20 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(10, 20)); 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The child should be affected by scroll delta, but the fixed position 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // grand_child should not be affected. 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.MakeIdentity(); 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.Translate(-10.0, -20.0); // scroll delta 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.PreconcatTransform(non_uniform_scale); 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_bottom_right_); 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Bottom-right fixed-position layer moves as container resizes. 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.MakeIdentity(); 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply child layer transform. 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.PreconcatTransform(non_uniform_scale); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply size delta from the child(container) layer. 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(20.0, 20.0); 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionLayerWithDistantContainer) { 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks for correct scroll compensation when the fixed-position 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container is NOT the direct parent of the fixed-position layer. 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* great_grand_child = grand_child->children()[0]; 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetIsContainerForFixedPositionLayers(true); 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPosition(gfx::PointF(8.f, 6.f)); 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetPositionConstraint(fixed_to_top_left_); 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: scroll delta of 0, 0 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(0, 0)); 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_child_transform; 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_transform; 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(8.0, 6.0); 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_great_grand_child_transform = 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform; 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: scroll delta of 10, 10 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(10, 10)); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here the child and grand_child are affected by scroll delta, but the fixed 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // position great_grand_child should not be affected. 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.MakeIdentity(); 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.Translate(-10.0, -10.0); 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.MakeIdentity(); 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(-2.0, -4.0); 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetPositionConstraint(fixed_to_bottom_right_); 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Bottom-right fixed-position layer moves as container resizes. 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.MakeIdentity(); 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply size delta from the child(container) layer. 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.Translate(20.0, 20.0); 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply layer position from the grand child layer. 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.Translate(8.0, 6.0); 350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionLayerWithDistantContainerAndTransforms) { 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks for correct scroll compensation when the fixed-position 362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container is NOT the direct parent of the fixed-position layer, and the 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // hierarchy has various transforms that have to be processed in the correct 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // order. 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* great_grand_child = grand_child->children()[0]; 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform rotation_about_z; 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z.RotateAboutZAxis(90.0); 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetIsContainerForFixedPositionLayers(true); 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetTransform(rotation_about_z); 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPosition(gfx::PointF(8.f, 6.f)); 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetTransform(rotation_about_z); 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // great_grand_child is positioned upside-down with respect to the render 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // target. 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetPositionConstraint(fixed_to_top_left_); 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: scroll delta of 0, 0 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(0, 0)); 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_child_transform; 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.PreconcatTransform(rotation_about_z); 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_transform; 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.PreconcatTransform( 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // child's local transform is inherited 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // translation because of position occurs before layer's local transform. 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(8.0, 6.0); 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.PreconcatTransform( 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // grand_child's local transform 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_great_grand_child_transform = 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform; 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: scroll delta of 10, 20 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(10, 20)); 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here the child and grand_child are affected by scroll delta, but the fixed 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // position great_grand_child should not be affected. 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.MakeIdentity(); 412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.Translate(-10.0, -20.0); // scroll delta 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.PreconcatTransform(rotation_about_z); 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.MakeIdentity(); 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate( 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) -10.0, -20.0); // child's scroll delta is inherited 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.PreconcatTransform( 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // child's local transform is inherited 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // translation because of position occurs before layer's local transform. 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(8.0, 6.0); 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.PreconcatTransform( 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // grand_child's local transform 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetPositionConstraint(fixed_to_bottom_right_); 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Bottom-right fixed-position layer moves as container resizes. 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.MakeIdentity(); 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply child layer transform. 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.PreconcatTransform(rotation_about_z); 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply size delta from the child(container) layer. 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.Translate(20.0, 20.0); 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply layer position from the grand child layer. 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.Translate(8.0, 6.0); 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply grand child layer transform. 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.PreconcatTransform(rotation_about_z); 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionLayerWithMultipleScrollDeltas) { 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks for correct scroll compensation when the fixed-position 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container has multiple ancestors that have nonzero scroll delta before 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // reaching the space where the layer is fixed. In this test, each scroll 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // delta occurs in a different space because of each layer's local transform. 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks for correct scroll compensation when the fixed-position 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container is NOT the direct parent of the fixed-position layer, and the 475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // hierarchy has various transforms that have to be processed in the correct 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // order. 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* great_grand_child = grand_child->children()[0]; 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform rotation_about_z; 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z.RotateAboutZAxis(90.0); 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetIsContainerForFixedPositionLayers(true); 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetTransform(rotation_about_z); 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPosition(gfx::PointF(8.f, 6.f)); 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetTransform(rotation_about_z); 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // great_grand_child is positioned upside-down with respect to the render 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // target. 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetPositionConstraint(fixed_to_top_left_); 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: scroll delta of 0, 0 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(0, 0)); 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_child_transform; 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.PreconcatTransform(rotation_about_z); 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_transform; 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.PreconcatTransform( 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // child's local transform is inherited 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // translation because of position occurs before layer's local transform. 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(8.0, 6.0); 504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.PreconcatTransform( 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // grand_child's local transform 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_great_grand_child_transform = 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform; 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: scroll delta of 10, 20 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(10, 0)); 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetScrollDelta(gfx::Vector2d(5, 0)); 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here the child and grand_child are affected by scroll delta, but the fixed 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // position great_grand_child should not be affected. 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.MakeIdentity(); 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.Translate(-10.0, 0.0); // scroll delta 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.PreconcatTransform(rotation_about_z); 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.MakeIdentity(); 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate( 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) -10.0, 0.0); // child's scroll delta is inherited 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.PreconcatTransform( 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // child's local transform is inherited 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(-5.0, 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0.0); // grand_child's scroll delta 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // translation because of position occurs before layer's local transform. 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(8.0, 6.0); 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.PreconcatTransform( 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // grand_child's local transform 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetPositionConstraint(fixed_to_bottom_right_); 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Bottom-right fixed-position layer moves as container resizes. 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.MakeIdentity(); 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply child layer transform. 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.PreconcatTransform(rotation_about_z); 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply size delta from the child(container) layer. 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.Translate(20.0, 20.0); 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply layer position from the grand child layer. 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.Translate(8.0, 6.0); 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply grand child layer transform. 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.PreconcatTransform(rotation_about_z); 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionWithIntermediateSurfaceAndTransforms) { 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks for correct scroll compensation when the fixed-position 585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container contributes to a different render surface than the fixed-position 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // layer. In this case, the surface draw transforms also have to be accounted 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // for when checking the scroll delta. 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* great_grand_child = grand_child->children()[0]; 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetIsContainerForFixedPositionLayers(true); 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPosition(gfx::PointF(8.f, 6.f)); 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetForceRenderSurface(true); 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetPositionConstraint(fixed_to_top_left_); 596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetDrawsContent(true); 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform rotation_about_z; 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z.RotateAboutZAxis(90.0); 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetTransform(rotation_about_z); 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: scroll delta of 0, 0 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(0, 0)); 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_child_transform; 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_surface_draw_transform; 608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform.Translate(8.0, 6.0); 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform.PreconcatTransform(rotation_about_z); 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_transform; 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_great_grand_child_transform; 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(grand_child->render_surface()); 613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ( 616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform, 617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->render_surface()->draw_transform()); 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: scroll delta of 10, 30 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(10, 30)); 625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here the grand_child remains unchanged, because it scrolls along with the 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // render surface, and the translation is actually in the render surface. But, 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the fixed position great_grand_child is more awkward: its actually being 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // drawn with respect to the render surface, but it needs to remain fixed with 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // resepct to a container beyond that surface. So, the net result is that, 632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // unlike previous tests where the fixed position layer's transform remains 633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // unchanged, here the fixed position layer's transform explicitly contains 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the translation that cancels out the scroll. 635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.MakeIdentity(); 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.Translate(-10.0, -30.0); // scroll delta 637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform.MakeIdentity(); 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform.Translate(-10.0, -30.0); // scroll delta 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform.Translate(8.0, 6.0); 641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform.PreconcatTransform(rotation_about_z); 642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The rotation and its inverse are needed to place the scroll delta 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // compensation in the correct space. This test will fail if the 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // rotation/inverse are backwards, too, so it requires perfect order of 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // operations. 647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.MakeIdentity(); 648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.PreconcatTransform( 649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Inverse(rotation_about_z)); 650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // explicit canceling out the scroll delta that gets embedded in the fixed 651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // position layer's surface. 652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.Translate(10.0, 30.0); 653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.PreconcatTransform(rotation_about_z); 654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(grand_child->render_surface()); 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ( 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform, 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->render_surface()->draw_transform()); 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetPositionConstraint(fixed_to_bottom_right_); 680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Bottom-right fixed-position layer moves as container resizes. 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.MakeIdentity(); 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The rotation and its inverse are needed to place the scroll delta 685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // compensation in the correct space. This test will fail if the 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // rotation/inverse are backwards, too, so it requires perfect order of 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // operations. 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.PreconcatTransform( 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Inverse(rotation_about_z)); 690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // explicit canceling out the scroll delta that gets embedded in the fixed 691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // position layer's surface. 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.Translate(10.0, 30.0); 693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Also apply size delta in the child(container) layer space. 694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.Translate(20.0, 20.0); 695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_transform.PreconcatTransform(rotation_about_z); 696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionLayerWithMultipleIntermediateSurfaces) { 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks for correct scroll compensation when the fixed-position 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container contributes to a different render surface than the fixed-position 709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // layer, with additional render surfaces in-between. This checks that the 710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // conversion to ancestor surfaces is accumulated properly in the final matrix 711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // transform. 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* great_grand_child = grand_child->children()[0]; 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add one more layer to the test tree for this scenario. 717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform identity; 719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<LayerImpl> fixed_position_child = 720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl::Create(host_impl_.active_tree(), 5); 721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetLayerPropertiesForTesting(fixed_position_child.get(), 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) identity, 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) identity, 724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::PointF(), 725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::PointF(), 726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Size(100, 100), 727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false); 728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->AddChild(fixed_position_child.Pass()); 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* fixed_position_child = great_grand_child->children()[0]; 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Actually set up the scenario here. 733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetIsContainerForFixedPositionLayers(true); 734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPosition(gfx::PointF(8.f, 6.f)); 735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetForceRenderSurface(true); 736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetPosition(gfx::PointF(40.f, 60.f)); 737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetForceRenderSurface(true); 738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_position_child->SetPositionConstraint(fixed_to_top_left_); 739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_position_child->SetDrawsContent(true); 740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The additional rotations, which are non-commutative with translations, help 742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to verify that we have correct order-of-operations in the final scroll 743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // compensation. Note that rotating about the center of the layer ensures we 744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // do not accidentally clip away layers that we want to test. 745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform rotation_about_z; 746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z.Translate(50.0, 50.0); 747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z.RotateAboutZAxis(90.0); 748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z.Translate(-50.0, -50.0); 749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetTransform(rotation_about_z); 750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->SetTransform(rotation_about_z); 751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: scroll delta of 0, 0 753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(0, 0)); 754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_child_transform; 757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_surface_draw_transform; 759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_surface_draw_transform.Translate(8.0, 6.0); 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_surface_draw_transform.PreconcatTransform( 761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); 762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_transform; 764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_great_grand_child_surface_draw_transform; 766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_surface_draw_transform.Translate(40.0, 60.0); 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_surface_draw_transform.PreconcatTransform( 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); 769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_great_grand_child_transform; 771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_fixed_position_child_transform; 773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(grand_child->render_surface()); 775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(great_grand_child->render_surface()); 776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ( 779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_surface_draw_transform, 780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->render_surface()->draw_transform()); 781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ( 784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_surface_draw_transform, 785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->render_surface()->draw_transform()); 786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform, 789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_position_child->draw_transform()); 790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: scroll delta of 10, 30 792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(10, 30)); 793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.MakeIdentity(); 796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.Translate(-10.0, -30.0); // scroll delta 797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_surface_draw_transform.MakeIdentity(); 799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_surface_draw_transform.Translate(-10.0, 800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) -30.0); // scroll delta 801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_surface_draw_transform.Translate(8.0, 6.0); 802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_surface_draw_transform.PreconcatTransform( 803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); 804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // grand_child, great_grand_child, and great_grand_child's surface are not 806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // expected to change, since they are all not fixed, and they are all drawn 807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // with respect to grand_child's surface that already has the scroll delta 808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // accounted for. 809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // But the great-great grandchild, "fixed_position_child", should have a 811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // transform that explicitly cancels out the scroll delta. The expected 812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // transform is: compound_draw_transform.Inverse() * translate(positive scroll 813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // delta) * compound_origin_transform from great_grand_childSurface's origin 814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to the root surface. 815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform compound_draw_transform; 816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) compound_draw_transform.Translate(8.0, 817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6.0); // origin translation of grand_child 818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) compound_draw_transform.PreconcatTransform( 819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // rotation of grand_child 820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) compound_draw_transform.Translate( 821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40.0, 60.0); // origin translation of great_grand_child 822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) compound_draw_transform.PreconcatTransform( 823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_about_z); // rotation of great_grand_child 824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_fixed_position_child_transform.MakeIdentity(); 826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_fixed_position_child_transform.PreconcatTransform( 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Inverse(compound_draw_transform)); 828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // explicit canceling out the scroll delta that gets embedded in the fixed 829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // position layer's surface. 830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_fixed_position_child_transform.Translate(10.0, 30.0); 831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_fixed_position_child_transform.PreconcatTransform( 832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) compound_draw_transform); 833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(grand_child->render_surface()); 835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(great_grand_child->render_surface()); 836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 838c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ( 839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_surface_draw_transform, 840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->render_surface()->draw_transform()); 841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ( 844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_great_grand_child_surface_draw_transform, 845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->render_surface()->draw_transform()); 846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform, 849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_position_child->draw_transform()); 850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform, 864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_position_child->draw_transform()); 865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_position_child->SetPositionConstraint(fixed_to_bottom_right_); 868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Bottom-right fixed-position layer moves as container resizes. 871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_fixed_position_child_transform.MakeIdentity(); 872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_fixed_position_child_transform.PreconcatTransform( 873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Inverse(compound_draw_transform)); 874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // explicit canceling out the scroll delta that gets embedded in the fixed 875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // position layer's surface. 876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_fixed_position_child_transform.Translate(10.0, 30.0); 877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Also apply size delta in the child(container) layer space. 878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_fixed_position_child_transform.Translate(20.0, 20.0); 879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_fixed_position_child_transform.PreconcatTransform( 880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) compound_draw_transform); 881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_transform, 887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) great_grand_child->draw_transform()); 888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_fixed_position_child_transform, 889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_position_child->draw_transform()); 890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionLayerWithContainerLayerThatHasSurface) { 894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks for correct scroll compensation when the fixed-position 895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // container itself has a render surface. In this case, the container layer 896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // should be treated like a layer that contributes to a render target, and 897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // that render target is completely irrelevant; it should not affect the 898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // scroll compensation. 899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetIsContainerForFixedPositionLayers(true); 903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetForceRenderSurface(true); 904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_top_left_); 905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetDrawsContent(true); 906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: scroll delta of 0, 0 908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(0, 0)); 909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_surface_draw_transform; 912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform.Translate(0.0, 0.0); 913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_child_transform; 914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_transform; 915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(child->render_surface()); 916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform, 917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->render_surface()->draw_transform()); 918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: scroll delta of 10, 10 924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(10, 10)); 925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The surface is translated by scroll delta, the child transform doesn't 928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // change because it scrolls along with the surface, but the fixed position 929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // grand_child needs to compensate for the scroll translation. 930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform.MakeIdentity(); 931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_surface_draw_transform.Translate(-10.0, -10.0); 932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.MakeIdentity(); 933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(10.0, 10.0); 934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(child->render_surface()); 936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform, 937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->render_surface()->draw_transform()); 938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_bottom_right_); 955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Bottom-right fixed-position layer moves as container resizes. 958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.MakeIdentity(); 959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The surface is translated by scroll delta, the child transform doesn't 960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // change because it scrolls along with the surface, but the fixed position 961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // grand_child needs to compensate for the scroll translation. 962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(10.0, 10.0); 963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply size delta from the child(container) layer. 964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(20.0, 20.0); 965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionLayerThatIsAlsoFixedPositionContainer) { 974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks the scenario where a fixed-position layer also happens to 975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // be a container itself for a descendant fixed position layer. In particular, 976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the layer should not accidentally be fixed to itself. 977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetIsContainerForFixedPositionLayers(true); 981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_top_left_); 982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This should not confuse the grand_child. If correct, the grand_child would 984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // still be considered fixed to its container (i.e. "child"). 985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetIsContainerForFixedPositionLayers(true); 986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: scroll delta of 0, 0 988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(0, 0)); 989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_child_transform; 992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform expected_grand_child_transform; 993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: scroll delta of 10, 10 999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetScrollDelta(gfx::Vector2d(10, 10)); 1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Here the child is affected by scroll delta, but the fixed position 1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // grand_child should not be affected. 1004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.MakeIdentity(); 1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_child_transform.Translate(-10.0, -10.0); 1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 1019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_bottom_right_); 1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Bottom-right fixed-position layer moves as container resizes. 1026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.MakeIdentity(); 1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Apply size delta from the child(container) layer. 1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expected_grand_child_transform.Translate(20.0, 20.0); 1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) child->draw_transform()); 1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerPositionConstraintTest, 1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScrollCompensationForFixedPositionLayerThatHasNoContainer) { 1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This test checks scroll compensation when a fixed-position layer does not 1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // find any ancestor that is a "containerForFixedPositionLayers". In this 1040868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // situation, the layer should be fixed to the root layer. 1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* child = root_->children()[0]; 1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LayerImpl* grand_child = child->children()[0]; 1043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform rotation_by_z; 1045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rotation_by_z.RotateAboutZAxis(90.0); 1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_->SetTransform(rotation_by_z); 1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_top_left_); 1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 1: root scroll delta of 0, 0 1051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_->SetScrollDelta(gfx::Vector2d(0, 0)); 1052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 1053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Transform identity_matrix; 1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z, child->draw_transform()); 1057868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z, 1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 1059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 2: root scroll delta of 10, 10 1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_->SetScrollDelta(gfx::Vector2d(10, 20)); 1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1064868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Transform expected_child_transform; 1065868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) expected_child_transform.Translate(-10.0, -20.0); 1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) expected_child_transform.PreconcatTransform(rotation_by_z); 1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1068868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 1069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) child->draw_transform()); 1070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z, 1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 3: fixed-container size delta of 20, 20 1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_->SetFixedContainerSizeDelta(gfx::Vector2d(20, 20)); 1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Top-left fixed-position layer should not be affected by container size. 1078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 1079868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) child->draw_transform()); 1080868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_by_z, 1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Case 4: Bottom-right fixed-position layer. 1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->SetPositionConstraint(fixed_to_bottom_right_); 1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExecuteCalculateDrawProperties(root_.get()); 1086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1087868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Transform expected_grand_child_transform; 1088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) expected_grand_child_transform.Translate(-20.0, 20.0); 1089868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) expected_grand_child_transform.PreconcatTransform(rotation_by_z); 1090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1091868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform, 1092868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) child->draw_transform()); 1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_transform, 1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) grand_child->draw_transform()); 1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace cc 1099