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 "testing/gtest/include/gtest/gtest.h"
14 #include "ui/gfx/box_f.h"
15 #include "ui/gfx/test/gfx_util.h"
20 float diagonal(float width
, float height
) {
21 return std::sqrt(width
* width
+ height
* height
);
24 class LayerUtilsGetAnimationBoundsTest
: public testing::Test
{
26 LayerUtilsGetAnimationBoundsTest()
27 : host_impl_(&proxy_
, &shared_bitmap_manager_
),
28 root_(CreateThreeNodeTree(host_impl_
)),
29 parent_(root_
->children()[0]),
30 child_(parent_
->children()[0]) {}
32 LayerImpl
* root() { return root_
.get(); }
33 LayerImpl
* parent() { return parent_
; }
34 LayerImpl
* child() { return child_
; }
37 static scoped_ptr
<LayerImpl
> CreateThreeNodeTree(
38 LayerTreeHostImpl
& host_impl
) {
39 scoped_ptr
<LayerImpl
> root
= LayerImpl::Create(host_impl
.active_tree(), 1);
40 root
->AddChild(LayerImpl::Create(host_impl
.active_tree(), 2));
42 ->AddChild(LayerImpl::Create(host_impl
.active_tree(), 3));
47 TestSharedBitmapManager shared_bitmap_manager_
;
48 FakeLayerTreeHostImpl host_impl_
;
49 scoped_ptr
<LayerImpl
> root_
;
54 TEST_F(LayerUtilsGetAnimationBoundsTest
, ScaleRoot
) {
55 double duration
= 1.0;
57 TransformOperations start
;
58 start
.AppendScale(1.f
, 1.f
, 1.f
);
59 TransformOperations end
;
60 end
.AppendScale(2.f
, 2.f
, 1.f
);
61 AddAnimatedTransformToLayer(root(), duration
, start
, end
);
63 root()->SetPosition(gfx::PointF());
64 parent()->SetPosition(gfx::PointF());
65 parent()->SetBounds(gfx::Size(350, 200));
67 child()->SetDrawsContent(true);
68 child()->draw_properties().screen_space_transform_is_animating
= true;
69 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
70 child()->SetBounds(gfx::Size(100, 200));
73 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
75 gfx::BoxF
expected(150.f
, 50.f
, 0.f
, 350.f
, 450.f
, 0.f
);
76 EXPECT_BOXF_EQ(expected
, box
);
79 TEST_F(LayerUtilsGetAnimationBoundsTest
, TranslateParentLayer
) {
80 double duration
= 1.0;
82 TransformOperations start
;
83 start
.AppendTranslate(0.f
, 0.f
, 0.f
);
84 TransformOperations end
;
85 end
.AppendTranslate(50.f
, 50.f
, 0.f
);
86 AddAnimatedTransformToLayer(parent(), duration
, start
, end
);
88 parent()->SetBounds(gfx::Size(350, 200));
90 child()->SetDrawsContent(true);
91 child()->draw_properties().screen_space_transform_is_animating
= true;
92 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
93 child()->SetBounds(gfx::Size(100, 200));
96 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
98 gfx::BoxF
expected(150.f
, 50.f
, 0.f
, 150.f
, 250.f
, 0.f
);
99 EXPECT_BOXF_EQ(expected
, box
);
102 TEST_F(LayerUtilsGetAnimationBoundsTest
, TranslateChildLayer
) {
103 double duration
= 1.0;
105 TransformOperations start
;
106 start
.AppendTranslate(0.f
, 0.f
, 0.f
);
107 TransformOperations end
;
108 end
.AppendTranslate(50.f
, 50.f
, 0.f
);
109 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
111 parent()->SetBounds(gfx::Size(350, 200));
113 child()->SetDrawsContent(true);
114 child()->draw_properties().screen_space_transform_is_animating
= true;
115 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
116 child()->SetBounds(gfx::Size(100, 200));
119 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
120 EXPECT_TRUE(success
);
121 gfx::BoxF
expected(150.f
, 50.f
, 0.f
, 150.f
, 250.f
, 0.f
);
122 EXPECT_BOXF_EQ(expected
, box
);
125 TEST_F(LayerUtilsGetAnimationBoundsTest
, TranslateBothLayers
) {
126 double duration
= 1.0;
128 TransformOperations start
;
129 start
.AppendTranslate(0.f
, 0.f
, 0.f
);
130 TransformOperations child_end
;
131 child_end
.AppendTranslate(50.f
, 0.f
, 0.f
);
132 AddAnimatedTransformToLayer(parent(), duration
, start
, child_end
);
134 TransformOperations grand_child_end
;
135 grand_child_end
.AppendTranslate(0.f
, 50.f
, 0.f
);
136 AddAnimatedTransformToLayer(child(), duration
, start
, grand_child_end
);
138 parent()->SetBounds(gfx::Size(350, 200));
140 child()->SetDrawsContent(true);
141 child()->draw_properties().screen_space_transform_is_animating
= true;
142 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
143 child()->SetBounds(gfx::Size(100, 200));
146 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
147 EXPECT_TRUE(success
);
148 gfx::BoxF
expected(150.f
, 50.f
, 0.f
, 150.f
, 250.f
, 0.f
);
149 EXPECT_BOXF_EQ(expected
, box
);
152 TEST_F(LayerUtilsGetAnimationBoundsTest
, RotateXNoPerspective
) {
153 double duration
= 1.0;
155 TransformOperations start
;
156 start
.AppendRotate(1.f
, 0.f
, 0.f
, 0.f
);
157 TransformOperations end
;
158 end
.AppendRotate(1.f
, 0.f
, 0.f
, 90.f
);
159 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
161 parent()->SetBounds(gfx::Size(350, 200));
163 gfx::Size
bounds(100, 100);
164 child()->SetDrawsContent(true);
165 child()->draw_properties().screen_space_transform_is_animating
= true;
166 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
167 child()->SetBounds(bounds
);
168 child()->SetTransformOrigin(
169 gfx::Point3F(bounds
.width() * 0.5f
, bounds
.height() * 0.5f
, 0));
172 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
173 EXPECT_TRUE(success
);
174 gfx::BoxF
expected(150.f
, 50.f
, -50.f
, 100.f
, 100.f
, 100.f
);
175 EXPECT_BOXF_EQ(expected
, box
);
178 TEST_F(LayerUtilsGetAnimationBoundsTest
, RotateXWithPerspective
) {
179 double duration
= 1.0;
181 TransformOperations start
;
182 start
.AppendRotate(1.f
, 0.f
, 0.f
, 0.f
);
183 TransformOperations end
;
184 end
.AppendRotate(1.f
, 0.f
, 0.f
, 90.f
);
185 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
187 // Make the anchor point not the default 0.5 value and line up with the
188 // child center to make the math easier.
189 parent()->SetTransformOrigin(
190 gfx::Point3F(0.375f
* 400.f
, 0.375f
* 400.f
, 0.f
));
191 parent()->SetBounds(gfx::Size(400, 400));
193 gfx::Transform perspective
;
194 perspective
.ApplyPerspectiveDepth(100.f
);
195 parent()->SetTransform(perspective
);
197 gfx::Size
bounds(100, 100);
198 child()->SetDrawsContent(true);
199 child()->draw_properties().screen_space_transform_is_animating
= true;
200 child()->SetPosition(gfx::PointF(100.f
, 100.f
));
201 child()->SetBounds(bounds
);
202 child()->SetTransformOrigin(
203 gfx::Point3F(bounds
.width() * 0.5f
, bounds
.height() * 0.5f
, 0));
206 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
207 EXPECT_TRUE(success
);
208 gfx::BoxF
expected(50.f
, 50.f
, -33.333336f
, 200.f
, 200.f
, 133.333344f
);
209 EXPECT_BOXF_EQ(expected
, box
);
212 TEST_F(LayerUtilsGetAnimationBoundsTest
, RotateZ
) {
213 double duration
= 1.0;
215 TransformOperations start
;
216 start
.AppendRotate(0.f
, 0.f
, 1.f
, 0.f
);
217 TransformOperations end
;
218 end
.AppendRotate(0.f
, 0.f
, 1.f
, 90.f
);
219 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
221 parent()->SetBounds(gfx::Size(350, 200));
223 gfx::Size
bounds(100, 100);
224 child()->SetDrawsContent(true);
225 child()->draw_properties().screen_space_transform_is_animating
= true;
226 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
227 child()->SetBounds(bounds
);
228 child()->SetTransformOrigin(
229 gfx::Point3F(bounds
.width() * 0.5f
, bounds
.height() * 0.5f
, 0));
232 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
233 EXPECT_TRUE(success
);
234 float diag
= diagonal(bounds
.width(), bounds
.height());
235 gfx::BoxF
expected(150.f
+ 0.5f
* (bounds
.width() - diag
),
236 50.f
+ 0.5f
* (bounds
.height() - diag
),
241 EXPECT_BOXF_EQ(expected
, box
);
244 TEST_F(LayerUtilsGetAnimationBoundsTest
, MismatchedTransforms
) {
245 double duration
= 1.0;
247 TransformOperations start
;
248 start
.AppendTranslate(5, 6, 7);
249 TransformOperations end
;
250 end
.AppendRotate(0.f
, 0.f
, 1.f
, 90.f
);
251 AddAnimatedTransformToLayer(child(), duration
, start
, end
);
253 parent()->SetBounds(gfx::Size(350, 200));
255 gfx::Size
bounds(100, 100);
256 child()->SetDrawsContent(true);
257 child()->draw_properties().screen_space_transform_is_animating
= true;
258 child()->SetPosition(gfx::PointF(150.f
, 50.f
));
259 child()->SetBounds(bounds
);
262 bool success
= LayerUtils::GetAnimationBounds(*child(), &box
);
263 EXPECT_FALSE(success
);