1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/layers/layer_utils.h"
7 #include "cc/animation/transform_operations.h"
8 #include "cc/layers/layer_impl.h"
9 #include "cc/test/animation_test_common.h"
10 #include "cc/test/fake_impl_proxy.h"
11 #include "cc/test/fake_layer_tree_host_impl.h"
12 #include "cc/test/test_shared_bitmap_manager.h"
13 #include "cc/test/test_task_graph_runner.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "ui/gfx/geometry/box_f.h"
16 #include "ui/gfx/test/gfx_util.h"
21 float diagonal(float width
, float height
) {
22 return std::sqrt(width
* width
+ height
* height
);
25 class LayerUtilsGetAnimationBoundsTest
: public testing::Test
{
27 LayerUtilsGetAnimationBoundsTest()
28 : host_impl_(&proxy_
, &shared_bitmap_manager_
, &task_graph_runner_
),
29 root_(CreateThreeNodeTree(&host_impl_
)),
30 parent_(root_
->children()[0]),
31 child_(parent_
->children()[0]) {}
33 LayerImpl
* root() { return root_
.get(); }
34 LayerImpl
* parent() { return parent_
; }
35 LayerImpl
* child() { return child_
; }
38 static scoped_ptr
<LayerImpl
> CreateThreeNodeTree(
39 LayerTreeHostImpl
* host_impl
) {
40 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl
->active_tree(), 1);
41 root
->AddChild(LayerImpl::Create(host_impl
->active_tree(), 2));
42 root
->children()[0]->AddChild(
43 LayerImpl::Create(host_impl
->active_tree(), 3));
48 TestSharedBitmapManager shared_bitmap_manager_
;
49 TestTaskGraphRunner task_graph_runner_
;
50 FakeLayerTreeHostImpl host_impl_
;
51 scoped_ptr
<LayerImpl
> root_
;
56 TEST_F(LayerUtilsGetAnimationBoundsTest
, ScaleRoot
) {
57 double duration
= 1.0;
59 TransformOperations start
;
60 start
.AppendScale(1.f
, 1.f
, 1.f
);
61 TransformOperations end
;
62 end
.AppendScale(2.f
, 2.f
, 1.f
);
63 AddAnimatedTransformToLayer(root(), duration
, start
, end
);
65 root()->SetPosition(gfx::PointF());
66 parent()->SetPosition(gfx::PointF());
67 parent()->SetBounds(gfx::Size(350, 200));
69 child()->SetDrawsContent(true);
70 child()->draw_properties().screen_space_transform_is_animating
= true;
71 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
72 child()->SetBounds(gfx::Size(100, 200));
75 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
77 gfx::BoxF
expected(150.f
, 50.f
, 0.f
, 350.f
, 450.f
, 0.f
);
78 EXPECT_BOXF_EQ(expected
, box
);
81 TEST_F(LayerUtilsGetAnimationBoundsTest
, TranslateParentLayer
) {
82 double duration
= 1.0;
84 TransformOperations start
;
85 start
.AppendTranslate(0.f
, 0.f
, 0.f
);
86 TransformOperations end
;
87 end
.AppendTranslate(50.f
, 50.f
, 0.f
);
88 AddAnimatedTransformToLayer(parent(), duration
, start
, end
);
90 parent()->SetBounds(gfx::Size(350, 200));
92 child()->SetDrawsContent(true);
93 child()->draw_properties().screen_space_transform_is_animating
= true;
94 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
95 child()->SetBounds(gfx::Size(100, 200));
98 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
100 gfx::BoxF
expected(150.f
, 50.f
, 0.f
, 150.f
, 250.f
, 0.f
);
101 EXPECT_BOXF_EQ(expected
, box
);
104 TEST_F(LayerUtilsGetAnimationBoundsTest
, TranslateChildLayer
) {
105 double duration
= 1.0;
107 TransformOperations start
;
108 start
.AppendTranslate(0.f
, 0.f
, 0.f
);
109 TransformOperations end
;
110 end
.AppendTranslate(50.f
, 50.f
, 0.f
);
111 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
113 parent()->SetBounds(gfx::Size(350, 200));
115 child()->SetDrawsContent(true);
116 child()->draw_properties().screen_space_transform_is_animating
= true;
117 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
118 child()->SetBounds(gfx::Size(100, 200));
121 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
122 EXPECT_TRUE(success
);
123 gfx::BoxF
expected(150.f
, 50.f
, 0.f
, 150.f
, 250.f
, 0.f
);
124 EXPECT_BOXF_EQ(expected
, box
);
127 TEST_F(LayerUtilsGetAnimationBoundsTest
, TranslateBothLayers
) {
128 double duration
= 1.0;
130 TransformOperations start
;
131 start
.AppendTranslate(0.f
, 0.f
, 0.f
);
132 TransformOperations child_end
;
133 child_end
.AppendTranslate(50.f
, 0.f
, 0.f
);
134 AddAnimatedTransformToLayer(parent(), duration
, start
, child_end
);
136 TransformOperations grand_child_end
;
137 grand_child_end
.AppendTranslate(0.f
, 50.f
, 0.f
);
138 AddAnimatedTransformToLayer(child(), duration
, start
, grand_child_end
);
140 parent()->SetBounds(gfx::Size(350, 200));
142 child()->SetDrawsContent(true);
143 child()->draw_properties().screen_space_transform_is_animating
= true;
144 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
145 child()->SetBounds(gfx::Size(100, 200));
148 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
149 EXPECT_TRUE(success
);
150 gfx::BoxF
expected(150.f
, 50.f
, 0.f
, 150.f
, 250.f
, 0.f
);
151 EXPECT_BOXF_EQ(expected
, box
);
154 TEST_F(LayerUtilsGetAnimationBoundsTest
, RotateXNoPerspective
) {
155 double duration
= 1.0;
157 TransformOperations start
;
158 start
.AppendRotate(1.f
, 0.f
, 0.f
, 0.f
);
159 TransformOperations end
;
160 end
.AppendRotate(1.f
, 0.f
, 0.f
, 90.f
);
161 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
163 parent()->SetBounds(gfx::Size(350, 200));
165 gfx::Size
bounds(100, 100);
166 child()->SetDrawsContent(true);
167 child()->draw_properties().screen_space_transform_is_animating
= true;
168 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
169 child()->SetBounds(bounds
);
170 child()->SetTransformOrigin(
171 gfx::Point3F(bounds
.width() * 0.5f
, bounds
.height() * 0.5f
, 0));
174 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
175 EXPECT_TRUE(success
);
176 gfx::BoxF
expected(150.f
, 50.f
, -50.f
, 100.f
, 100.f
, 100.f
);
177 EXPECT_BOXF_EQ(expected
, box
);
180 TEST_F(LayerUtilsGetAnimationBoundsTest
, RotateXWithPerspective
) {
181 double duration
= 1.0;
183 TransformOperations start
;
184 start
.AppendRotate(1.f
, 0.f
, 0.f
, 0.f
);
185 TransformOperations end
;
186 end
.AppendRotate(1.f
, 0.f
, 0.f
, 90.f
);
187 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
189 // Make the anchor point not the default 0.5 value and line up with the
190 // child center to make the math easier.
191 parent()->SetTransformOrigin(
192 gfx::Point3F(0.375f
* 400.f
, 0.375f
* 400.f
, 0.f
));
193 parent()->SetBounds(gfx::Size(400, 400));
195 gfx::Transform perspective
;
196 perspective
.ApplyPerspectiveDepth(100.f
);
197 parent()->SetTransform(perspective
);
199 gfx::Size
bounds(100, 100);
200 child()->SetDrawsContent(true);
201 child()->draw_properties().screen_space_transform_is_animating
= true;
202 child()->SetPosition(gfx::PointF(100.f
, 100.f
));
203 child()->SetBounds(bounds
);
204 child()->SetTransformOrigin(
205 gfx::Point3F(bounds
.width() * 0.5f
, bounds
.height() * 0.5f
, 0));
208 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
209 EXPECT_TRUE(success
);
210 gfx::BoxF
expected(50.f
, 50.f
, -33.333336f
, 200.f
, 200.f
, 133.333344f
);
211 EXPECT_BOXF_EQ(expected
, box
);
214 TEST_F(LayerUtilsGetAnimationBoundsTest
, RotateZ
) {
215 double duration
= 1.0;
217 TransformOperations start
;
218 start
.AppendRotate(0.f
, 0.f
, 1.f
, 0.f
);
219 TransformOperations end
;
220 end
.AppendRotate(0.f
, 0.f
, 1.f
, 90.f
);
221 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
223 parent()->SetBounds(gfx::Size(350, 200));
225 gfx::Size
bounds(100, 100);
226 child()->SetDrawsContent(true);
227 child()->draw_properties().screen_space_transform_is_animating
= true;
228 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
229 child()->SetBounds(bounds
);
230 child()->SetTransformOrigin(
231 gfx::Point3F(bounds
.width() * 0.5f
, bounds
.height() * 0.5f
, 0));
234 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
235 EXPECT_TRUE(success
);
236 float diag
= diagonal(bounds
.width(), bounds
.height());
237 gfx::BoxF
expected(150.f
+ 0.5f
* (bounds
.width() - diag
),
238 50.f
+ 0.5f
* (bounds
.height() - diag
),
243 EXPECT_BOXF_EQ(expected
, box
);
246 TEST_F(LayerUtilsGetAnimationBoundsTest
, MismatchedTransforms
) {
247 double duration
= 1.0;
249 TransformOperations start
;
250 start
.AppendTranslate(5, 6, 7);
251 TransformOperations end
;
252 end
.AppendRotate(0.f
, 0.f
, 1.f
, 90.f
);
253 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
255 parent()->SetBounds(gfx::Size(350, 200));
257 gfx::Size
bounds(100, 100);
258 child()->SetDrawsContent(true);
259 child()->draw_properties().screen_space_transform_is_animating
= true;
260 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
261 child()->SetBounds(bounds
);
264 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
265 EXPECT_FALSE(success
);