Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: cc/trees/property_tree_unittest.cc

Issue 1417963011: Added serialization to protobufs for property trees. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase and address comments. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/trees/property_tree.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/trees/property_tree.h" 5 #include "cc/trees/property_tree.h"
6 6
7 #include "cc/proto/property_tree.pb.h"
7 #include "cc/test/geometry_test_utils.h" 8 #include "cc/test/geometry_test_utils.h"
8 #include "cc/trees/draw_property_utils.h" 9 #include "cc/trees/draw_property_utils.h"
9 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
10 11
11 namespace cc { 12 namespace cc {
12 13 namespace {
13 TEST(PropertyTreeTest, ComputeTransformRoot) { 14
14 TransformTree tree; 15 TEST(PropertyTreeSerializationTest, TransformNodeDataSerialization) {
15 TransformNode& root = *tree.Node(0); 16 TransformNodeData original;
16 root.data.local.Translate(2, 2); 17 original.pre_local.Translate3d(1.f, 2.f, 3.f);
17 root.data.target_id = 0; 18 original.local.Translate3d(3.f, 1.f, 5.f);
18 tree.UpdateTransforms(0); 19 original.post_local.Translate3d(1.f, 8.f, 3.f);
19 20 original.to_parent.Translate3d(3.2f, 2.f, 3.f);
20 gfx::Transform expected; 21 original.to_target.Translate3d(2.6f, 2.f, 3.f);
21 gfx::Transform transform; 22 original.from_target.Translate3d(4.3f, 2.f, 3.f);
22 bool success = tree.ComputeTransform(0, 0, &transform); 23 original.to_screen.Translate3d(7.2f, 2.f, 4.5f);
23 EXPECT_TRUE(success); 24 original.from_screen.Translate3d(2.f, 2.f, 7.f);
24 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); 25 original.target_id = 3;
25 26 original.content_target_id = 4;
26 transform.MakeIdentity(); 27 original.source_node_id = 5;
27 expected.Translate(2, 2); 28 original.needs_local_transform_update = false;
28 success = tree.ComputeTransform(0, -1, &transform); 29 original.is_invertible = false;
29 EXPECT_TRUE(success); 30 original.ancestors_are_invertible = false;
30 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); 31 original.is_animated = false;
31 32 original.to_screen_is_animated = false;
32 transform.MakeIdentity(); 33 original.has_only_translation_animations = false;
33 expected.MakeIdentity(); 34 original.to_screen_has_scale_animation = false;
34 expected.Translate(-2, -2); 35 original.flattens_inherited_transform = false;
35 success = tree.ComputeTransform(-1, 0, &transform); 36 original.node_and_ancestors_are_flat = false;
36 EXPECT_TRUE(success); 37 original.node_and_ancestors_have_only_integer_translation = false;
37 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); 38 original.scrolls = false;
39 original.needs_sublayer_scale = false;
40 original.affected_by_inner_viewport_bounds_delta_x = false;
41 original.affected_by_inner_viewport_bounds_delta_y = false;
42 original.affected_by_outer_viewport_bounds_delta_x = false;
43 original.affected_by_outer_viewport_bounds_delta_y = false;
44 original.in_subtree_of_page_scale_layer = false;
45 original.post_local_scale_factor = 0.5f;
46 original.local_maximum_animation_target_scale = 0.6f;
47 original.local_starting_animation_scale = 0.7f;
48 original.combined_maximum_animation_target_scale = 0.8f;
49 original.combined_starting_animation_scale = 0.9f;
50 original.sublayer_scale = gfx::Vector2dF(0.5f, 0.5f);
51 original.scroll_offset = gfx::ScrollOffset(1.5f, 1.5f);
52 original.scroll_snap = gfx::Vector2dF(0.4f, 0.4f);
53 original.source_offset = gfx::Vector2dF(2.5f, 2.4f);
54 original.source_to_parent = gfx::Vector2dF(3.2f, 3.2f);
55
56 proto::TreeNode proto;
57 original.ToProtobuf(&proto);
58 TransformNodeData result;
59 result.FromProtobuf(proto);
60
61 EXPECT_EQ(original, result);
38 } 62 }
39 63
40 TEST(PropertyTreeTest, ComputeTransformChild) { 64 TEST(PropertyTreeSerializationTest, TransformNodeSerialization) {
41 TransformTree tree; 65 TransformNode original;
42 TransformNode& root = *tree.Node(0); 66 original.id = 3;
43 root.data.local.Translate(2, 2); 67 original.parent_id = 2;
44 root.data.target_id = 0; 68 original.owner_id = 4;
45 tree.UpdateTransforms(0); 69
46 70 proto::TreeNode proto;
47 TransformNode child; 71 original.ToProtobuf(&proto);
48 child.data.local.Translate(3, 3); 72 TransformNode result;
49 child.data.target_id = 0; 73 result.FromProtobuf(proto);
50 child.data.source_node_id = 0; 74
51 75 EXPECT_EQ(original, result);
52 tree.Insert(child, 0);
53 tree.UpdateTransforms(1);
54
55 gfx::Transform expected;
56 gfx::Transform transform;
57
58 expected.Translate(3, 3);
59 bool success = tree.ComputeTransform(1, 0, &transform);
60 EXPECT_TRUE(success);
61 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
62
63 transform.MakeIdentity();
64 expected.MakeIdentity();
65 expected.Translate(-3, -3);
66 success = tree.ComputeTransform(0, 1, &transform);
67 EXPECT_TRUE(success);
68 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
69
70 transform.MakeIdentity();
71 expected.MakeIdentity();
72 expected.Translate(5, 5);
73 success = tree.ComputeTransform(1, -1, &transform);
74 EXPECT_TRUE(success);
75 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
76
77 transform.MakeIdentity();
78 expected.MakeIdentity();
79 expected.Translate(-5, -5);
80 success = tree.ComputeTransform(-1, 1, &transform);
81 EXPECT_TRUE(success);
82 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
83 } 76 }
84 77
85 TEST(PropertyTreeTest, ComputeTransformSibling) { 78 TEST(PropertyTreeSerializationTest, TransformTreeSerialization) {
86 TransformTree tree; 79 TransformTree original;
87 TransformNode& root = *tree.Node(0); 80 TransformNode& root = *original.Node(0);
88 root.data.local.Translate(2, 2); 81 root.data.target_id = 3;
89 root.data.target_id = 0; 82 root.data.content_target_id = 4;
90 tree.UpdateTransforms(0); 83 TransformNode second;
91 84 second.data.local.Translate3d(2.f, 2.f, 0.f);
92 TransformNode child; 85 second.data.source_node_id = 0;
93 child.data.local.Translate(3, 3); 86 second.data.target_id = 0;
94 child.data.source_node_id = 0; 87 TransformNode third;
95 child.data.target_id = 0; 88 third.data.scrolls = true;
96 89 third.data.source_node_id = 1;
97 TransformNode sibling; 90 third.data.target_id = 0;
98 sibling.data.local.Translate(7, 7); 91
99 sibling.data.source_node_id = 0; 92 original.Insert(second, 0);
100 sibling.data.target_id = 0; 93 original.Insert(third, 1);
101 94 original.set_needs_update(true);
102 tree.Insert(child, 0); 95
103 tree.Insert(sibling, 0); 96 original.set_page_scale_factor(0.5f);
104 97 original.set_device_scale_factor(0.6f);
105 tree.UpdateTransforms(1); 98 gfx::Transform transform =
106 tree.UpdateTransforms(2); 99 gfx::Transform(1.05f, 2.15f, 3.14f, 4.13f, 5.12f, 6.11f, 7.1f, 8.9f, 9.8f,
107 100 10.7f, 11.6f, 12.5f, 13.4f, 14.3f, 15.2f, 16.1f);
108 gfx::Transform expected; 101 original.SetDeviceTransformScaleFactor(transform);
109 gfx::Transform transform; 102 original.SetInnerViewportBoundsDelta(gfx::Vector2dF(0.4f, 0.6f));
110 103 original.SetOuterViewportBoundsDelta(gfx::Vector2dF(0.5f, 0.7f));
111 expected.Translate(4, 4); 104 original.AddNodeAffectedByInnerViewportBoundsDelta(0);
112 bool success = tree.ComputeTransform(2, 1, &transform); 105 original.AddNodeAffectedByOuterViewportBoundsDelta(1);
113 EXPECT_TRUE(success); 106
114 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); 107 proto::PropertyTree proto;
115 108 original.ToProtobuf(&proto);
116 transform.MakeIdentity(); 109 TransformTree result;
117 expected.MakeIdentity(); 110 result.FromProtobuf(proto);
118 expected.Translate(-4, -4); 111
119 success = tree.ComputeTransform(1, 2, &transform); 112 EXPECT_EQ(original, result);
120 EXPECT_TRUE(success);
121 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
122 } 113 }
123 114
124 TEST(PropertyTreeTest, ComputeTransformSiblingSingularAncestor) { 115 TEST(PropertyTreeSerializationTest, ClipNodeDataSerialization) {
125 // In this test, we have the following tree: 116 ClipNodeData original;
126 // root 117 original.clip = gfx::RectF(0.5f, 0.5f);
127 // + singular 118 original.combined_clip_in_target_space = gfx::RectF(0.6f, 0.6f);
128 // + child 119 original.clip_in_target_space = gfx::RectF(0.7f, 0.7f);
129 // + sibling 120 original.transform_id = 2;
130 // Since the lowest common ancestor of |child| and |sibling| has a singular 121 original.target_id = 3;
131 // transform, we cannot use screen space transforms to compute change of basis 122 original.applies_local_clip = false;
132 // transforms between these nodes. 123 original.layer_clipping_uses_only_local_clip = false;
133 TransformTree tree; 124 original.target_is_clipped = false;
134 TransformNode& root = *tree.Node(0); 125 original.layers_are_clipped = false;
135 root.data.local.Translate(2, 2); 126 original.layers_are_clipped_when_surfaces_disabled = false;
136 root.data.target_id = 0; 127 original.resets_clip = false;
137 tree.UpdateTransforms(0); 128
138 129 proto::TreeNode proto;
139 TransformNode singular; 130 original.ToProtobuf(&proto);
140 singular.data.local.matrix().set(2, 2, 0.0); 131 ClipNodeData result;
141 singular.data.source_node_id = 0; 132 result.FromProtobuf(proto);
142 singular.data.target_id = 0; 133
143 134 EXPECT_EQ(original, result);
144 TransformNode child;
145 child.data.local.Translate(3, 3);
146 child.data.source_node_id = 1;
147 child.data.target_id = 0;
148
149 TransformNode sibling;
150 sibling.data.local.Translate(7, 7);
151 sibling.data.source_node_id = 1;
152 sibling.data.target_id = 0;
153
154 tree.Insert(singular, 0);
155 tree.Insert(child, 1);
156 tree.Insert(sibling, 1);
157
158 tree.UpdateTransforms(1);
159 tree.UpdateTransforms(2);
160 tree.UpdateTransforms(3);
161
162 gfx::Transform expected;
163 gfx::Transform transform;
164
165 expected.Translate(4, 4);
166 bool success = tree.ComputeTransform(3, 2, &transform);
167 EXPECT_TRUE(success);
168 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
169
170 transform.MakeIdentity();
171 expected.MakeIdentity();
172 expected.Translate(-4, -4);
173 success = tree.ComputeTransform(2, 3, &transform);
174 EXPECT_TRUE(success);
175 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
176 } 135 }
177 136
178 TEST(PropertyTreeTest, TransformsWithFlattening) { 137 TEST(PropertyTreeSerializationTest, ClipNodeSerialization) {
179 TransformTree tree; 138 ClipNode original;
180 139 original.id = 3;
181 int grand_parent = tree.Insert(TransformNode(), 0); 140 original.parent_id = 2;
182 tree.Node(grand_parent)->data.content_target_id = grand_parent; 141 original.owner_id = 4;
183 tree.Node(grand_parent)->data.target_id = grand_parent; 142
184 tree.Node(grand_parent)->data.source_node_id = 0; 143 proto::TreeNode proto;
185 144 original.ToProtobuf(&proto);
186 gfx::Transform rotation_about_x; 145 ClipNode result;
187 rotation_about_x.RotateAboutXAxis(15); 146 result.FromProtobuf(proto);
188 147
189 int parent = tree.Insert(TransformNode(), grand_parent); 148 EXPECT_EQ(original, result);
190 tree.Node(parent)->data.needs_sublayer_scale = true;
191 tree.Node(parent)->data.target_id = grand_parent;
192 tree.Node(parent)->data.content_target_id = parent;
193 tree.Node(parent)->data.source_node_id = grand_parent;
194 tree.Node(parent)->data.local = rotation_about_x;
195
196 int child = tree.Insert(TransformNode(), parent);
197 tree.Node(child)->data.target_id = parent;
198 tree.Node(child)->data.content_target_id = parent;
199 tree.Node(child)->data.source_node_id = parent;
200 tree.Node(child)->data.flattens_inherited_transform = true;
201 tree.Node(child)->data.local = rotation_about_x;
202
203 int grand_child = tree.Insert(TransformNode(), child);
204 tree.Node(grand_child)->data.target_id = parent;
205 tree.Node(grand_child)->data.content_target_id = parent;
206 tree.Node(grand_child)->data.source_node_id = child;
207 tree.Node(grand_child)->data.flattens_inherited_transform = true;
208 tree.Node(grand_child)->data.local = rotation_about_x;
209
210 tree.set_needs_update(true);
211 ComputeTransforms(&tree);
212
213 gfx::Transform flattened_rotation_about_x = rotation_about_x;
214 flattened_rotation_about_x.FlattenTo2d();
215
216 EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x,
217 tree.Node(child)->data.to_target);
218
219 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_x * rotation_about_x,
220 tree.Node(child)->data.to_screen);
221
222 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_x * rotation_about_x,
223 tree.Node(grand_child)->data.to_target);
224
225 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_x *
226 flattened_rotation_about_x *
227 rotation_about_x,
228 tree.Node(grand_child)->data.to_screen);
229
230 gfx::Transform grand_child_to_child;
231 bool success =
232 tree.ComputeTransform(grand_child, child, &grand_child_to_child);
233 EXPECT_TRUE(success);
234 EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x, grand_child_to_child);
235
236 // Remove flattening at grand_child, and recompute transforms.
237 tree.Node(grand_child)->data.flattens_inherited_transform = false;
238 tree.set_needs_update(true);
239 ComputeTransforms(&tree);
240
241 EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x * rotation_about_x,
242 tree.Node(grand_child)->data.to_target);
243
244 EXPECT_TRANSFORMATION_MATRIX_EQ(
245 flattened_rotation_about_x * rotation_about_x * rotation_about_x,
246 tree.Node(grand_child)->data.to_screen);
247
248 success = tree.ComputeTransform(grand_child, child, &grand_child_to_child);
249 EXPECT_TRUE(success);
250 EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x, grand_child_to_child);
251 } 149 }
252 150
253 TEST(PropertyTreeTest, MultiplicationOrder) { 151 TEST(PropertyTreeSerializationTest, ClipTreeSerialization) {
254 TransformTree tree; 152 ClipTree original;
255 TransformNode& root = *tree.Node(0); 153 ClipNode& root = *original.Node(0);
256 root.data.local.Translate(2, 2); 154 root.data.transform_id = 2;
257 root.data.target_id = 0; 155 root.data.target_id = 1;
258 tree.UpdateTransforms(0); 156 ClipNode second;
259 157 second.data.transform_id = 4;
260 TransformNode child; 158 second.data.applies_local_clip = true;
261 child.data.local.Scale(2, 2); 159 ClipNode third;
262 child.data.target_id = 0; 160 third.data.target_id = 3;
263 child.data.source_node_id = 0; 161 third.data.target_is_clipped = false;
264 162
265 tree.Insert(child, 0); 163 original.Insert(second, 0);
266 tree.UpdateTransforms(1); 164 original.Insert(third, 1);
267 165 original.set_needs_update(true);
268 gfx::Transform expected; 166
269 expected.Translate(2, 2); 167 proto::PropertyTree proto;
270 expected.Scale(2, 2); 168 original.ToProtobuf(&proto);
271 169 ClipTree result;
272 gfx::Transform transform; 170 result.FromProtobuf(proto);
273 gfx::Transform inverse; 171
274 172 EXPECT_EQ(original, result);
275 bool success = tree.ComputeTransform(1, -1, &transform);
276 EXPECT_TRUE(success);
277 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
278
279 success = tree.ComputeTransform(-1, 1, &inverse);
280 EXPECT_TRUE(success);
281
282 transform = transform * inverse;
283 expected.MakeIdentity();
284 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
285 } 173 }
286 174
287 TEST(PropertyTreeTest, ComputeTransformWithUninvertibleTransform) { 175 TEST(PropertyTreeSerializationTest, EffectNodeDataSerialization) {
288 TransformTree tree; 176 EffectNodeData original;
289 TransformNode& root = *tree.Node(0); 177 original.opacity = 0.5f;
290 root.data.target_id = 0; 178 original.screen_space_opacity = 0.6f;
291 tree.UpdateTransforms(0); 179 original.has_render_surface = false;
292 180 original.transform_id = 2;
293 TransformNode child; 181 original.clip_id = 3;
294 child.data.local.Scale(0, 0); 182
295 child.data.target_id = 0; 183 proto::TreeNode proto;
296 child.data.source_node_id = 0; 184 original.ToProtobuf(&proto);
297 185 EffectNodeData result;
298 tree.Insert(child, 0); 186 result.FromProtobuf(proto);
299 tree.UpdateTransforms(1); 187
300 188 EXPECT_EQ(original, result);
301 gfx::Transform expected;
302 expected.Scale(0, 0);
303
304 gfx::Transform transform;
305 gfx::Transform inverse;
306
307 bool success = tree.ComputeTransform(1, 0, &transform);
308 EXPECT_TRUE(success);
309 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
310
311 // To compute this would require inverting the 0 matrix, so we cannot
312 // succeed.
313 success = tree.ComputeTransform(0, 1, &inverse);
314 EXPECT_FALSE(success);
315 } 189 }
316 190
317 TEST(PropertyTreeTest, ComputeTransformWithSublayerScale) { 191 TEST(PropertyTreeSerializationTest, EffectNodeSerialization) {
318 TransformTree tree; 192 EffectNode original;
319 TransformNode& root = *tree.Node(0); 193 original.id = 3;
320 root.data.target_id = 0; 194 original.parent_id = 2;
321 tree.UpdateTransforms(0); 195 original.owner_id = 4;
322 196
323 TransformNode grand_parent; 197 proto::TreeNode proto;
324 grand_parent.data.local.Scale(2.f, 2.f); 198 original.ToProtobuf(&proto);
325 grand_parent.data.target_id = 0; 199 EffectNode result;
326 grand_parent.data.source_node_id = 0; 200 result.FromProtobuf(proto);
327 grand_parent.data.needs_sublayer_scale = true; 201
328 int grand_parent_id = tree.Insert(grand_parent, 0); 202 EXPECT_EQ(original, result);
329 tree.UpdateTransforms(grand_parent_id);
330
331 TransformNode parent;
332 parent.data.local.Translate(15.f, 15.f);
333 parent.data.target_id = grand_parent_id;
334 parent.data.source_node_id = grand_parent_id;
335 int parent_id = tree.Insert(parent, grand_parent_id);
336 tree.UpdateTransforms(parent_id);
337
338 TransformNode child;
339 child.data.local.Scale(3.f, 3.f);
340 child.data.target_id = grand_parent_id;
341 child.data.source_node_id = parent_id;
342 int child_id = tree.Insert(child, parent_id);
343 tree.UpdateTransforms(child_id);
344
345 TransformNode grand_child;
346 grand_child.data.local.Scale(5.f, 5.f);
347 grand_child.data.target_id = grand_parent_id;
348 grand_child.data.source_node_id = child_id;
349 grand_child.data.needs_sublayer_scale = true;
350 int grand_child_id = tree.Insert(grand_child, child_id);
351 tree.UpdateTransforms(grand_child_id);
352
353 EXPECT_EQ(gfx::Vector2dF(2.f, 2.f),
354 tree.Node(grand_parent_id)->data.sublayer_scale);
355 EXPECT_EQ(gfx::Vector2dF(30.f, 30.f),
356 tree.Node(grand_child_id)->data.sublayer_scale);
357
358 // Compute transform from grand_parent to grand_child.
359 gfx::Transform expected_transform_without_sublayer_scale;
360 expected_transform_without_sublayer_scale.Scale(1.f / 15.f, 1.f / 15.f);
361 expected_transform_without_sublayer_scale.Translate(-15.f, -15.f);
362
363 gfx::Transform expected_transform_with_dest_sublayer_scale;
364 expected_transform_with_dest_sublayer_scale.Scale(30.f, 30.f);
365 expected_transform_with_dest_sublayer_scale.Scale(1.f / 15.f, 1.f / 15.f);
366 expected_transform_with_dest_sublayer_scale.Translate(-15.f, -15.f);
367
368 gfx::Transform expected_transform_with_source_sublayer_scale;
369 expected_transform_with_source_sublayer_scale.Scale(1.f / 15.f, 1.f / 15.f);
370 expected_transform_with_source_sublayer_scale.Translate(-15.f, -15.f);
371 expected_transform_with_source_sublayer_scale.Scale(0.5f, 0.5f);
372
373 gfx::Transform transform;
374 bool success =
375 tree.ComputeTransform(grand_parent_id, grand_child_id, &transform);
376 EXPECT_TRUE(success);
377 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_without_sublayer_scale,
378 transform);
379
380 success = tree.ComputeTransformWithDestinationSublayerScale(
381 grand_parent_id, grand_child_id, &transform);
382 EXPECT_TRUE(success);
383 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_with_dest_sublayer_scale,
384 transform);
385
386 success = tree.ComputeTransformWithSourceSublayerScale(
387 grand_parent_id, grand_child_id, &transform);
388 EXPECT_TRUE(success);
389 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_with_source_sublayer_scale,
390 transform);
391
392 // Now compute transform from grand_child to grand_parent.
393 expected_transform_without_sublayer_scale.MakeIdentity();
394 expected_transform_without_sublayer_scale.Translate(15.f, 15.f);
395 expected_transform_without_sublayer_scale.Scale(15.f, 15.f);
396
397 expected_transform_with_dest_sublayer_scale.MakeIdentity();
398 expected_transform_with_dest_sublayer_scale.Scale(2.f, 2.f);
399 expected_transform_with_dest_sublayer_scale.Translate(15.f, 15.f);
400 expected_transform_with_dest_sublayer_scale.Scale(15.f, 15.f);
401
402 expected_transform_with_source_sublayer_scale.MakeIdentity();
403 expected_transform_with_source_sublayer_scale.Translate(15.f, 15.f);
404 expected_transform_with_source_sublayer_scale.Scale(15.f, 15.f);
405 expected_transform_with_source_sublayer_scale.Scale(1.f / 30.f, 1.f / 30.f);
406
407 success = tree.ComputeTransform(grand_child_id, grand_parent_id, &transform);
408 EXPECT_TRUE(success);
409 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_without_sublayer_scale,
410 transform);
411
412 success = tree.ComputeTransformWithDestinationSublayerScale(
413 grand_child_id, grand_parent_id, &transform);
414 EXPECT_TRUE(success);
415 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_with_dest_sublayer_scale,
416 transform);
417
418 success = tree.ComputeTransformWithSourceSublayerScale(
419 grand_child_id, grand_parent_id, &transform);
420 EXPECT_TRUE(success);
421 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_with_source_sublayer_scale,
422 transform);
423 } 203 }
424 204
425 TEST(PropertyTreeTest, ComputeTransformToTargetWithZeroSublayerScale) { 205 TEST(PropertyTreeSerializationTest, EffectTreeSerialization) {
426 TransformTree tree; 206 EffectTree original;
427 TransformNode& root = *tree.Node(0); 207 EffectNode& root = *original.Node(0);
428 root.data.target_id = 0; 208 root.data.transform_id = 2;
429 tree.UpdateTransforms(0); 209 root.data.clip_id = 1;
430 210 EffectNode second;
431 TransformNode grand_parent; 211 second.data.transform_id = 4;
432 grand_parent.data.local.Scale(2.f, 0.f); 212 second.data.opacity = true;
433 grand_parent.data.target_id = 0; 213 EffectNode third;
434 grand_parent.data.source_node_id = 0; 214 third.data.clip_id = 3;
435 grand_parent.data.needs_sublayer_scale = true; 215 third.data.has_render_surface = false;
436 int grand_parent_id = tree.Insert(grand_parent, 0); 216
437 tree.Node(grand_parent_id)->data.content_target_id = grand_parent_id; 217 original.Insert(second, 0);
438 tree.UpdateTransforms(grand_parent_id); 218 original.Insert(third, 1);
439 219 original.set_needs_update(true);
440 TransformNode parent; 220
441 parent.data.local.Translate(1.f, 1.f); 221 proto::PropertyTree proto;
442 parent.data.target_id = grand_parent_id; 222 original.ToProtobuf(&proto);
443 parent.data.content_target_id = grand_parent_id; 223 EffectTree result;
444 parent.data.source_node_id = grand_parent_id; 224 result.FromProtobuf(proto);
445 int parent_id = tree.Insert(parent, grand_parent_id); 225
446 tree.UpdateTransforms(parent_id); 226 EXPECT_EQ(original, result);
447
448 TransformNode child;
449 child.data.local.Translate(3.f, 4.f);
450 child.data.target_id = grand_parent_id;
451 child.data.content_target_id = grand_parent_id;
452 child.data.source_node_id = parent_id;
453 int child_id = tree.Insert(child, parent_id);
454 tree.UpdateTransforms(child_id);
455
456 gfx::Transform expected_transform;
457 expected_transform.Translate(4.f, 5.f);
458
459 gfx::Transform transform;
460 bool success = tree.ComputeTransform(child_id, grand_parent_id, &transform);
461 EXPECT_TRUE(success);
462 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform);
463
464 tree.Node(grand_parent_id)->data.local.MakeIdentity();
465 tree.Node(grand_parent_id)->data.local.Scale(0.f, 2.f);
466 tree.Node(grand_parent_id)->data.needs_local_transform_update = true;
467 tree.set_needs_update(true);
468
469 ComputeTransforms(&tree);
470
471 success = tree.ComputeTransform(child_id, grand_parent_id, &transform);
472 EXPECT_TRUE(success);
473 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform);
474
475 tree.Node(grand_parent_id)->data.local.MakeIdentity();
476 tree.Node(grand_parent_id)->data.local.Scale(0.f, 0.f);
477 tree.Node(grand_parent_id)->data.needs_local_transform_update = true;
478 tree.set_needs_update(true);
479
480 ComputeTransforms(&tree);
481
482 success = tree.ComputeTransform(child_id, grand_parent_id, &transform);
483 EXPECT_TRUE(success);
484 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform);
485 } 227 }
486 228
487 TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) { 229 TEST(PropertyTreeSerializationTest, PropertyTrees) {
488 // This tests that flattening is performed correctly when 230 PropertyTrees original;
489 // destination and its ancestors are flat, but there are 3d transforms 231 original.transform_tree.Insert(TransformNode(), 0);
490 // and flattening between the source and destination. 232 original.transform_tree.Insert(TransformNode(), 1);
491 TransformTree tree; 233 original.clip_tree.Insert(ClipNode(), 0);
492 234 original.clip_tree.Insert(ClipNode(), 1);
493 int parent = tree.Insert(TransformNode(), 0); 235 original.effect_tree.Insert(EffectNode(), 0);
494 tree.Node(parent)->data.content_target_id = parent; 236 original.effect_tree.Insert(EffectNode(), 1);
495 tree.Node(parent)->data.target_id = parent; 237 original.needs_rebuild = false;
496 tree.Node(parent)->data.source_node_id = 0; 238 original.non_root_surfaces_enabled = false;
497 tree.Node(parent)->data.local.Translate(2, 2); 239 original.sequence_number = 3;
498 240
499 gfx::Transform rotation_about_x; 241 proto::PropertyTrees proto;
500 rotation_about_x.RotateAboutXAxis(15); 242 original.ToProtobuf(&proto);
501 243 PropertyTrees result;
502 int child = tree.Insert(TransformNode(), parent); 244 result.FromProtobuf(proto);
503 tree.Node(child)->data.content_target_id = child; 245
504 tree.Node(child)->data.target_id = child; 246 EXPECT_EQ(original, result);
505 tree.Node(child)->data.source_node_id = parent;
506 tree.Node(child)->data.local = rotation_about_x;
507
508
509 int grand_child = tree.Insert(TransformNode(), child);
510 tree.Node(grand_child)->data.content_target_id = grand_child;
511 tree.Node(grand_child)->data.target_id = grand_child;
512 tree.Node(grand_child)->data.source_node_id = child;
513 tree.Node(grand_child)->data.flattens_inherited_transform = true;
514
515 tree.set_needs_update(true);
516 ComputeTransforms(&tree);
517
518 gfx::Transform flattened_rotation_about_x = rotation_about_x;
519 flattened_rotation_about_x.FlattenTo2d();
520
521 gfx::Transform grand_child_to_parent;
522 bool success =
523 tree.ComputeTransform(grand_child, parent, &grand_child_to_parent);
524 EXPECT_TRUE(success);
525 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_x,
526 grand_child_to_parent);
527 } 247 }
528 248
529 TEST(PropertyTreeTest, ScreenSpaceOpacityUpdateTest) { 249 class PropertyTreeTest : public testing::Test {
530 // This tests that screen space opacity is updated for the subtree when 250 public:
531 // opacity of a node changes. 251 PropertyTreeTest() : test_serialization_(false) {}
532 EffectTree tree; 252
533 253 protected:
534 int parent = tree.Insert(EffectNode(), 0); 254 void RunTest(bool test_serialization) {
535 int child = tree.Insert(EffectNode(), parent); 255 test_serialization_ = test_serialization;
536 256 StartTest();
537 EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 1.f); 257 }
538 tree.Node(parent)->data.opacity = 0.5f; 258
539 tree.set_needs_update(true); 259 virtual void StartTest() = 0;
540 ComputeOpacities(&tree); 260
541 EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 0.5f); 261 TransformTree TransformTreeForTest(const TransformTree& transform_tree) {
542 262 if (!test_serialization_) {
543 tree.Node(child)->data.opacity = 0.5f; 263 return transform_tree;
544 tree.set_needs_update(true); 264 }
545 ComputeOpacities(&tree); 265 TransformTree new_tree;
546 EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 0.25f); 266 proto::PropertyTree proto;
547 } 267 transform_tree.ToProtobuf(&proto);
548 268 new_tree.FromProtobuf(proto);
549 TEST(PropertyTreeTest, NonIntegerTranslationTest) { 269
550 // This tests that when a node has non-integer translation, the information 270 EXPECT_EQ(transform_tree, new_tree);
551 // is propagated to the subtree. 271 return new_tree;
552 TransformTree tree; 272 }
553 273
554 int parent = tree.Insert(TransformNode(), 0); 274 EffectTree EffectTreeForTest(const EffectTree& effect_tree) {
555 tree.Node(parent)->data.target_id = parent; 275 if (!test_serialization_) {
556 tree.Node(parent)->data.local.Translate(1.5f, 1.5f); 276 return effect_tree;
557 277 }
558 int child = tree.Insert(TransformNode(), parent); 278 EffectTree new_tree;
559 tree.Node(child)->data.target_id = parent; 279 proto::PropertyTree proto;
560 tree.Node(child)->data.local.Translate(1, 1); 280 effect_tree.ToProtobuf(&proto);
561 tree.set_needs_update(true); 281 new_tree.FromProtobuf(proto);
562 ComputeTransforms(&tree); 282
563 EXPECT_FALSE( 283 EXPECT_EQ(effect_tree, new_tree);
564 tree.Node(parent)->data.node_and_ancestors_have_only_integer_translation); 284 return new_tree;
565 EXPECT_FALSE( 285 }
566 tree.Node(child)->data.node_and_ancestors_have_only_integer_translation); 286
567 287 private:
568 tree.Node(parent)->data.local.Translate(0.5f, 0.5f); 288 bool test_serialization_;
569 tree.Node(child)->data.local.Translate(0.5f, 0.5f); 289 };
570 tree.set_needs_update(true); 290
571 ComputeTransforms(&tree); 291 #define DIRECT_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME) \
572 EXPECT_TRUE( 292 TEST_F(TEST_FIXTURE_NAME, RunDirect) { RunTest(false); }
573 tree.Node(parent)->data.node_and_ancestors_have_only_integer_translation); 293
574 EXPECT_FALSE( 294 #define SERIALIZED_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME) \
575 tree.Node(child)->data.node_and_ancestors_have_only_integer_translation); 295 TEST_F(TEST_FIXTURE_NAME, RunSerialized) { RunTest(true); }
576 296
577 tree.Node(child)->data.local.Translate(0.5f, 0.5f); 297 #define DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME) \
578 tree.Node(child)->data.target_id = child; 298 DIRECT_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME); \
579 tree.set_needs_update(true); 299 SERIALIZED_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME)
580 ComputeTransforms(&tree); 300
581 EXPECT_TRUE( 301 class PropertyTreeTestComputeTransformRoot : public PropertyTreeTest {
582 tree.Node(parent)->data.node_and_ancestors_have_only_integer_translation); 302 protected:
583 EXPECT_TRUE( 303 void StartTest() override {
584 tree.Node(child)->data.node_and_ancestors_have_only_integer_translation); 304 TransformTree tree;
585 } 305 TransformNode& root = *tree.Node(0);
586 306 root.data.local.Translate(2, 2);
307 root.data.target_id = 0;
308 tree = TransformTreeForTest(tree);
309 tree.UpdateTransforms(0);
310
311 gfx::Transform expected;
312 gfx::Transform transform;
313 bool success = tree.ComputeTransform(0, 0, &transform);
314 EXPECT_TRUE(success);
315 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
316
317 transform.MakeIdentity();
318 expected.Translate(2, 2);
319 success = tree.ComputeTransform(0, -1, &transform);
320 EXPECT_TRUE(success);
321 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
322
323 transform.MakeIdentity();
324 expected.MakeIdentity();
325 expected.Translate(-2, -2);
326 success = tree.ComputeTransform(-1, 0, &transform);
327 EXPECT_TRUE(success);
328 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
329 }
330 };
331
332 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
333 PropertyTreeTestComputeTransformRoot);
334
335 class PropertyTreeTestComputeTransformChild : public PropertyTreeTest {
336 protected:
337 void StartTest() override {
338 TransformTree tree;
339 TransformNode& root = *tree.Node(0);
340 root.data.local.Translate(2, 2);
341 root.data.target_id = 0;
342 tree.UpdateTransforms(0);
343
344 TransformNode child;
345 child.data.local.Translate(3, 3);
346 child.data.target_id = 0;
347 child.data.source_node_id = 0;
348
349 tree.Insert(child, 0);
350 tree = TransformTreeForTest(tree);
351 tree.UpdateTransforms(1);
352
353 gfx::Transform expected;
354 gfx::Transform transform;
355
356 expected.Translate(3, 3);
357 bool success = tree.ComputeTransform(1, 0, &transform);
358 EXPECT_TRUE(success);
359 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
360
361 transform.MakeIdentity();
362 expected.MakeIdentity();
363 expected.Translate(-3, -3);
364 success = tree.ComputeTransform(0, 1, &transform);
365 EXPECT_TRUE(success);
366 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
367
368 transform.MakeIdentity();
369 expected.MakeIdentity();
370 expected.Translate(5, 5);
371 success = tree.ComputeTransform(1, -1, &transform);
372 EXPECT_TRUE(success);
373 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
374
375 transform.MakeIdentity();
376 expected.MakeIdentity();
377 expected.Translate(-5, -5);
378 success = tree.ComputeTransform(-1, 1, &transform);
379 EXPECT_TRUE(success);
380 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
381 }
382 };
383
384 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
385 PropertyTreeTestComputeTransformChild);
386
387 class PropertyTreeTestComputeTransformSibling : public PropertyTreeTest {
388 protected:
389 void StartTest() override {
390 TransformTree tree;
391 TransformNode& root = *tree.Node(0);
392 root.data.local.Translate(2, 2);
393 root.data.target_id = 0;
394 tree.UpdateTransforms(0);
395
396 TransformNode child;
397 child.data.local.Translate(3, 3);
398 child.data.source_node_id = 0;
399 child.data.target_id = 0;
400
401 TransformNode sibling;
402 sibling.data.local.Translate(7, 7);
403 sibling.data.source_node_id = 0;
404 sibling.data.target_id = 0;
405
406 tree.Insert(child, 0);
407 tree.Insert(sibling, 0);
408
409 tree = TransformTreeForTest(tree);
410
411 tree.UpdateTransforms(1);
412 tree.UpdateTransforms(2);
413
414 gfx::Transform expected;
415 gfx::Transform transform;
416
417 expected.Translate(4, 4);
418 bool success = tree.ComputeTransform(2, 1, &transform);
419 EXPECT_TRUE(success);
420 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
421
422 transform.MakeIdentity();
423 expected.MakeIdentity();
424 expected.Translate(-4, -4);
425 success = tree.ComputeTransform(1, 2, &transform);
426 EXPECT_TRUE(success);
427 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
428 }
429 };
430
431 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
432 PropertyTreeTestComputeTransformSibling);
433
434 class PropertyTreeTestComputeTransformSiblingSingularAncestor
435 : public PropertyTreeTest {
436 protected:
437 void StartTest() override {
438 // In this test, we have the following tree:
439 // root
440 // + singular
441 // + child
442 // + sibling
443 // Since the lowest common ancestor of |child| and |sibling| has a singular
444 // transform, we cannot use screen space transforms to compute change of
445 // basis
446 // transforms between these nodes.
447 TransformTree tree;
448 TransformNode& root = *tree.Node(0);
449 root.data.local.Translate(2, 2);
450 root.data.target_id = 0;
451 tree.UpdateTransforms(0);
452
453 TransformNode singular;
454 singular.data.local.matrix().set(2, 2, 0.0);
455 singular.data.source_node_id = 0;
456 singular.data.target_id = 0;
457
458 TransformNode child;
459 child.data.local.Translate(3, 3);
460 child.data.source_node_id = 1;
461 child.data.target_id = 0;
462
463 TransformNode sibling;
464 sibling.data.local.Translate(7, 7);
465 sibling.data.source_node_id = 1;
466 sibling.data.target_id = 0;
467
468 tree.Insert(singular, 0);
469 tree.Insert(child, 1);
470 tree.Insert(sibling, 1);
471
472 tree = TransformTreeForTest(tree);
473
474 tree.UpdateTransforms(1);
475 tree.UpdateTransforms(2);
476 tree.UpdateTransforms(3);
477
478 gfx::Transform expected;
479 gfx::Transform transform;
480
481 expected.Translate(4, 4);
482 bool success = tree.ComputeTransform(3, 2, &transform);
483 EXPECT_TRUE(success);
484 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
485
486 transform.MakeIdentity();
487 expected.MakeIdentity();
488 expected.Translate(-4, -4);
489 success = tree.ComputeTransform(2, 3, &transform);
490 EXPECT_TRUE(success);
491 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
492 }
493 };
494
495 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
496 PropertyTreeTestComputeTransformSiblingSingularAncestor);
497
498 class PropertyTreeTestTransformsWithFlattening : public PropertyTreeTest {
499 protected:
500 void StartTest() override {
501 TransformTree tree;
502
503 int grand_parent = tree.Insert(TransformNode(), 0);
504 tree.Node(grand_parent)->data.content_target_id = grand_parent;
505 tree.Node(grand_parent)->data.target_id = grand_parent;
506 tree.Node(grand_parent)->data.source_node_id = 0;
507
508 gfx::Transform rotation_about_x;
509 rotation_about_x.RotateAboutXAxis(15);
510
511 int parent = tree.Insert(TransformNode(), grand_parent);
512 tree.Node(parent)->data.needs_sublayer_scale = true;
513 tree.Node(parent)->data.target_id = grand_parent;
514 tree.Node(parent)->data.content_target_id = parent;
515 tree.Node(parent)->data.source_node_id = grand_parent;
516 tree.Node(parent)->data.local = rotation_about_x;
517
518 int child = tree.Insert(TransformNode(), parent);
519 tree.Node(child)->data.target_id = parent;
520 tree.Node(child)->data.content_target_id = parent;
521 tree.Node(child)->data.source_node_id = parent;
522 tree.Node(child)->data.flattens_inherited_transform = true;
523 tree.Node(child)->data.local = rotation_about_x;
524
525 int grand_child = tree.Insert(TransformNode(), child);
526 tree.Node(grand_child)->data.target_id = parent;
527 tree.Node(grand_child)->data.content_target_id = parent;
528 tree.Node(grand_child)->data.source_node_id = child;
529 tree.Node(grand_child)->data.flattens_inherited_transform = true;
530 tree.Node(grand_child)->data.local = rotation_about_x;
531
532 tree.set_needs_update(true);
533 tree = TransformTreeForTest(tree);
534 ComputeTransforms(&tree);
535
536 gfx::Transform flattened_rotation_about_x = rotation_about_x;
537 flattened_rotation_about_x.FlattenTo2d();
538
539 EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x,
540 tree.Node(child)->data.to_target);
541
542 EXPECT_TRANSFORMATION_MATRIX_EQ(
543 flattened_rotation_about_x * rotation_about_x,
544 tree.Node(child)->data.to_screen);
545
546 EXPECT_TRANSFORMATION_MATRIX_EQ(
547 flattened_rotation_about_x * rotation_about_x,
548 tree.Node(grand_child)->data.to_target);
549
550 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_x *
551 flattened_rotation_about_x *
552 rotation_about_x,
553 tree.Node(grand_child)->data.to_screen);
554
555 gfx::Transform grand_child_to_child;
556 bool success =
557 tree.ComputeTransform(grand_child, child, &grand_child_to_child);
558 EXPECT_TRUE(success);
559 EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x, grand_child_to_child);
560
561 // Remove flattening at grand_child, and recompute transforms.
562 tree.Node(grand_child)->data.flattens_inherited_transform = false;
563 tree.set_needs_update(true);
564 tree = TransformTreeForTest(tree);
565 ComputeTransforms(&tree);
566
567 EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x * rotation_about_x,
568 tree.Node(grand_child)->data.to_target);
569
570 EXPECT_TRANSFORMATION_MATRIX_EQ(
571 flattened_rotation_about_x * rotation_about_x * rotation_about_x,
572 tree.Node(grand_child)->data.to_screen);
573
574 success = tree.ComputeTransform(grand_child, child, &grand_child_to_child);
575 EXPECT_TRUE(success);
576 EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x, grand_child_to_child);
577 }
578 };
579
580 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
581 PropertyTreeTestTransformsWithFlattening);
582
583 class PropertyTreeTestMultiplicationOrder : public PropertyTreeTest {
584 protected:
585 void StartTest() override {
586 TransformTree tree;
587 TransformNode& root = *tree.Node(0);
588 root.data.local.Translate(2, 2);
589 root.data.target_id = 0;
590 tree.UpdateTransforms(0);
591
592 TransformNode child;
593 child.data.local.Scale(2, 2);
594 child.data.target_id = 0;
595 child.data.source_node_id = 0;
596
597 tree.Insert(child, 0);
598 tree = TransformTreeForTest(tree);
599 tree.UpdateTransforms(1);
600
601 gfx::Transform expected;
602 expected.Translate(2, 2);
603 expected.Scale(2, 2);
604
605 gfx::Transform transform;
606 gfx::Transform inverse;
607
608 bool success = tree.ComputeTransform(1, -1, &transform);
609 EXPECT_TRUE(success);
610 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
611
612 success = tree.ComputeTransform(-1, 1, &inverse);
613 EXPECT_TRUE(success);
614
615 transform = transform * inverse;
616 expected.MakeIdentity();
617 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
618 }
619 };
620
621 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(PropertyTreeTestMultiplicationOrder);
622
623 class PropertyTreeTestComputeTransformWithUninvertibleTransform
624 : public PropertyTreeTest {
625 protected:
626 void StartTest() override {
627 TransformTree tree;
628 TransformNode& root = *tree.Node(0);
629 root.data.target_id = 0;
630 tree.UpdateTransforms(0);
631
632 TransformNode child;
633 child.data.local.Scale(0, 0);
634 child.data.target_id = 0;
635 child.data.source_node_id = 0;
636
637 tree.Insert(child, 0);
638 tree = TransformTreeForTest(tree);
639 tree.UpdateTransforms(1);
640
641 gfx::Transform expected;
642 expected.Scale(0, 0);
643
644 gfx::Transform transform;
645 gfx::Transform inverse;
646
647 bool success = tree.ComputeTransform(1, 0, &transform);
648 EXPECT_TRUE(success);
649 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform);
650
651 // To compute this would require inverting the 0 matrix, so we cannot
652 // succeed.
653 success = tree.ComputeTransform(0, 1, &inverse);
654 EXPECT_FALSE(success);
655 }
656 };
657
658 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
659 PropertyTreeTestComputeTransformWithUninvertibleTransform);
660
661 class PropertyTreeTestComputeTransformWithSublayerScale
662 : public PropertyTreeTest {
663 protected:
664 void StartTest() override {
665 TransformTree tree;
666 TransformNode& root = *tree.Node(0);
667 root.data.target_id = 0;
668 tree.UpdateTransforms(0);
669
670 TransformNode grand_parent;
671 grand_parent.data.local.Scale(2.f, 2.f);
672 grand_parent.data.target_id = 0;
673 grand_parent.data.source_node_id = 0;
674 grand_parent.data.needs_sublayer_scale = true;
675 int grand_parent_id = tree.Insert(grand_parent, 0);
676 tree.UpdateTransforms(grand_parent_id);
677
678 TransformNode parent;
679 parent.data.local.Translate(15.f, 15.f);
680 parent.data.target_id = grand_parent_id;
681 parent.data.source_node_id = grand_parent_id;
682 int parent_id = tree.Insert(parent, grand_parent_id);
683 tree.UpdateTransforms(parent_id);
684
685 TransformNode child;
686 child.data.local.Scale(3.f, 3.f);
687 child.data.target_id = grand_parent_id;
688 child.data.source_node_id = parent_id;
689 int child_id = tree.Insert(child, parent_id);
690 tree.UpdateTransforms(child_id);
691
692 TransformNode grand_child;
693 grand_child.data.local.Scale(5.f, 5.f);
694 grand_child.data.target_id = grand_parent_id;
695 grand_child.data.source_node_id = child_id;
696 grand_child.data.needs_sublayer_scale = true;
697 int grand_child_id = tree.Insert(grand_child, child_id);
698 tree = TransformTreeForTest(tree);
699 tree.UpdateTransforms(grand_child_id);
700
701 EXPECT_EQ(gfx::Vector2dF(2.f, 2.f),
702 tree.Node(grand_parent_id)->data.sublayer_scale);
703 EXPECT_EQ(gfx::Vector2dF(30.f, 30.f),
704 tree.Node(grand_child_id)->data.sublayer_scale);
705
706 // Compute transform from grand_parent to grand_child.
707 gfx::Transform expected_transform_without_sublayer_scale;
708 expected_transform_without_sublayer_scale.Scale(1.f / 15.f, 1.f / 15.f);
709 expected_transform_without_sublayer_scale.Translate(-15.f, -15.f);
710
711 gfx::Transform expected_transform_with_dest_sublayer_scale;
712 expected_transform_with_dest_sublayer_scale.Scale(30.f, 30.f);
713 expected_transform_with_dest_sublayer_scale.Scale(1.f / 15.f, 1.f / 15.f);
714 expected_transform_with_dest_sublayer_scale.Translate(-15.f, -15.f);
715
716 gfx::Transform expected_transform_with_source_sublayer_scale;
717 expected_transform_with_source_sublayer_scale.Scale(1.f / 15.f, 1.f / 15.f);
718 expected_transform_with_source_sublayer_scale.Translate(-15.f, -15.f);
719 expected_transform_with_source_sublayer_scale.Scale(0.5f, 0.5f);
720
721 gfx::Transform transform;
722 bool success =
723 tree.ComputeTransform(grand_parent_id, grand_child_id, &transform);
724 EXPECT_TRUE(success);
725 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_without_sublayer_scale,
726 transform);
727
728 success = tree.ComputeTransformWithDestinationSublayerScale(
729 grand_parent_id, grand_child_id, &transform);
730 EXPECT_TRUE(success);
731 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_with_dest_sublayer_scale,
732 transform);
733
734 success = tree.ComputeTransformWithSourceSublayerScale(
735 grand_parent_id, grand_child_id, &transform);
736 EXPECT_TRUE(success);
737 EXPECT_TRANSFORMATION_MATRIX_EQ(
738 expected_transform_with_source_sublayer_scale, transform);
739
740 // Now compute transform from grand_child to grand_parent.
741 expected_transform_without_sublayer_scale.MakeIdentity();
742 expected_transform_without_sublayer_scale.Translate(15.f, 15.f);
743 expected_transform_without_sublayer_scale.Scale(15.f, 15.f);
744
745 expected_transform_with_dest_sublayer_scale.MakeIdentity();
746 expected_transform_with_dest_sublayer_scale.Scale(2.f, 2.f);
747 expected_transform_with_dest_sublayer_scale.Translate(15.f, 15.f);
748 expected_transform_with_dest_sublayer_scale.Scale(15.f, 15.f);
749
750 expected_transform_with_source_sublayer_scale.MakeIdentity();
751 expected_transform_with_source_sublayer_scale.Translate(15.f, 15.f);
752 expected_transform_with_source_sublayer_scale.Scale(15.f, 15.f);
753 expected_transform_with_source_sublayer_scale.Scale(1.f / 30.f, 1.f / 30.f);
754
755 success =
756 tree.ComputeTransform(grand_child_id, grand_parent_id, &transform);
757 EXPECT_TRUE(success);
758 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_without_sublayer_scale,
759 transform);
760
761 success = tree.ComputeTransformWithDestinationSublayerScale(
762 grand_child_id, grand_parent_id, &transform);
763 EXPECT_TRUE(success);
764 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform_with_dest_sublayer_scale,
765 transform);
766
767 success = tree.ComputeTransformWithSourceSublayerScale(
768 grand_child_id, grand_parent_id, &transform);
769 EXPECT_TRUE(success);
770 EXPECT_TRANSFORMATION_MATRIX_EQ(
771 expected_transform_with_source_sublayer_scale, transform);
772 }
773 };
774
775 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
776 PropertyTreeTestComputeTransformWithSublayerScale);
777
778 class PropertyTreeTestComputeTransformToTargetWithZeroSublayerScale
779 : public PropertyTreeTest {
780 protected:
781 void StartTest() override {
782 TransformTree tree;
783 TransformNode& root = *tree.Node(0);
784 root.data.target_id = 0;
785 tree.UpdateTransforms(0);
786
787 TransformNode grand_parent;
788 grand_parent.data.local.Scale(2.f, 0.f);
789 grand_parent.data.target_id = 0;
790 grand_parent.data.source_node_id = 0;
791 grand_parent.data.needs_sublayer_scale = true;
792 int grand_parent_id = tree.Insert(grand_parent, 0);
793 tree.Node(grand_parent_id)->data.content_target_id = grand_parent_id;
794 tree.UpdateTransforms(grand_parent_id);
795
796 TransformNode parent;
797 parent.data.local.Translate(1.f, 1.f);
798 parent.data.target_id = grand_parent_id;
799 parent.data.content_target_id = grand_parent_id;
800 parent.data.source_node_id = grand_parent_id;
801 int parent_id = tree.Insert(parent, grand_parent_id);
802 tree.UpdateTransforms(parent_id);
803
804 TransformNode child;
805 child.data.local.Translate(3.f, 4.f);
806 child.data.target_id = grand_parent_id;
807 child.data.content_target_id = grand_parent_id;
808 child.data.source_node_id = parent_id;
809 int child_id = tree.Insert(child, parent_id);
810 tree = TransformTreeForTest(tree);
811 tree.UpdateTransforms(child_id);
812
813 gfx::Transform expected_transform;
814 expected_transform.Translate(4.f, 5.f);
815
816 gfx::Transform transform;
817 bool success = tree.ComputeTransform(child_id, grand_parent_id, &transform);
818 EXPECT_TRUE(success);
819 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform);
820
821 tree.Node(grand_parent_id)->data.local.MakeIdentity();
822 tree.Node(grand_parent_id)->data.local.Scale(0.f, 2.f);
823 tree.Node(grand_parent_id)->data.needs_local_transform_update = true;
824 tree.set_needs_update(true);
825 tree = TransformTreeForTest(tree);
826
827 ComputeTransforms(&tree);
828
829 success = tree.ComputeTransform(child_id, grand_parent_id, &transform);
830 EXPECT_TRUE(success);
831 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform);
832
833 tree.Node(grand_parent_id)->data.local.MakeIdentity();
834 tree.Node(grand_parent_id)->data.local.Scale(0.f, 0.f);
835 tree.Node(grand_parent_id)->data.needs_local_transform_update = true;
836 tree.set_needs_update(true);
837 tree = TransformTreeForTest(tree);
838
839 ComputeTransforms(&tree);
840
841 success = tree.ComputeTransform(child_id, grand_parent_id, &transform);
842 EXPECT_TRUE(success);
843 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform);
844 }
845 };
846
847 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
848 PropertyTreeTestComputeTransformToTargetWithZeroSublayerScale);
849
850 class PropertyTreeTestFlatteningWhenDestinationHasOnlyFlatAncestors
851 : public PropertyTreeTest {
852 protected:
853 void StartTest() override {
854 // This tests that flattening is performed correctly when
855 // destination and its ancestors are flat, but there are 3d transforms
856 // and flattening between the source and destination.
857 TransformTree tree;
858
859 int parent = tree.Insert(TransformNode(), 0);
860 tree.Node(parent)->data.content_target_id = parent;
861 tree.Node(parent)->data.target_id = parent;
862 tree.Node(parent)->data.source_node_id = 0;
863 tree.Node(parent)->data.local.Translate(2, 2);
864
865 gfx::Transform rotation_about_x;
866 rotation_about_x.RotateAboutXAxis(15);
867
868 int child = tree.Insert(TransformNode(), parent);
869 tree.Node(child)->data.content_target_id = child;
870 tree.Node(child)->data.target_id = child;
871 tree.Node(child)->data.source_node_id = parent;
872 tree.Node(child)->data.local = rotation_about_x;
873
874 int grand_child = tree.Insert(TransformNode(), child);
875 tree.Node(grand_child)->data.content_target_id = grand_child;
876 tree.Node(grand_child)->data.target_id = grand_child;
877 tree.Node(grand_child)->data.source_node_id = child;
878 tree.Node(grand_child)->data.flattens_inherited_transform = true;
879
880 tree.set_needs_update(true);
881 tree = TransformTreeForTest(tree);
882 ComputeTransforms(&tree);
883
884 gfx::Transform flattened_rotation_about_x = rotation_about_x;
885 flattened_rotation_about_x.FlattenTo2d();
886
887 gfx::Transform grand_child_to_parent;
888 bool success =
889 tree.ComputeTransform(grand_child, parent, &grand_child_to_parent);
890 EXPECT_TRUE(success);
891 EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_x,
892 grand_child_to_parent);
893 }
894 };
895
896 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
897 PropertyTreeTestFlatteningWhenDestinationHasOnlyFlatAncestors);
898
899 class PropertyTreeTestScreenSpaceOpacityUpdateTest : public PropertyTreeTest {
900 protected:
901 void StartTest() override {
902 // This tests that screen space opacity is updated for the subtree when
903 // opacity of a node changes.
904 EffectTree tree;
905
906 int parent = tree.Insert(EffectNode(), 0);
907 int child = tree.Insert(EffectNode(), parent);
908 tree = EffectTreeForTest(tree);
909
910 EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 1.f);
911 tree.Node(parent)->data.opacity = 0.5f;
912 tree.set_needs_update(true);
913 tree = EffectTreeForTest(tree);
914 ComputeOpacities(&tree);
915 EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 0.5f);
916
917 tree.Node(child)->data.opacity = 0.5f;
918 tree.set_needs_update(true);
919 tree = EffectTreeForTest(tree);
920 ComputeOpacities(&tree);
921 EXPECT_EQ(tree.Node(child)->data.screen_space_opacity, 0.25f);
922 }
923 };
924
925 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
926 PropertyTreeTestScreenSpaceOpacityUpdateTest);
927
928 class PropertyTreeTestNonIntegerTranslationTest : public PropertyTreeTest {
929 protected:
930 void StartTest() override {
931 // This tests that when a node has non-integer translation, the information
932 // is propagated to the subtree.
933 TransformTree tree;
934
935 int parent = tree.Insert(TransformNode(), 0);
936 tree.Node(parent)->data.target_id = parent;
937 tree.Node(parent)->data.local.Translate(1.5f, 1.5f);
938
939 int child = tree.Insert(TransformNode(), parent);
940 tree.Node(child)->data.target_id = parent;
941 tree.Node(child)->data.local.Translate(1, 1);
942 tree.set_needs_update(true);
943 tree = TransformTreeForTest(tree);
944 ComputeTransforms(&tree);
945 EXPECT_FALSE(tree.Node(parent)
946 ->data.node_and_ancestors_have_only_integer_translation);
947 EXPECT_FALSE(tree.Node(child)
948 ->data.node_and_ancestors_have_only_integer_translation);
949
950 tree.Node(parent)->data.local.Translate(0.5f, 0.5f);
951 tree.Node(child)->data.local.Translate(0.5f, 0.5f);
952 tree.set_needs_update(true);
953 tree = TransformTreeForTest(tree);
954 ComputeTransforms(&tree);
955 EXPECT_TRUE(tree.Node(parent)
956 ->data.node_and_ancestors_have_only_integer_translation);
957 EXPECT_FALSE(tree.Node(child)
958 ->data.node_and_ancestors_have_only_integer_translation);
959
960 tree.Node(child)->data.local.Translate(0.5f, 0.5f);
961 tree.Node(child)->data.target_id = child;
962 tree.set_needs_update(true);
963 tree = TransformTreeForTest(tree);
964 ComputeTransforms(&tree);
965 EXPECT_TRUE(tree.Node(parent)
966 ->data.node_and_ancestors_have_only_integer_translation);
967 EXPECT_TRUE(tree.Node(child)
968 ->data.node_and_ancestors_have_only_integer_translation);
969 }
970 };
971
972 DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(
973 PropertyTreeTestNonIntegerTranslationTest);
974
975 #undef DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F
976 #undef SERIALIZED_PROPERTY_TREE_TEST_F
977 #undef DIRECT_PROPERTY_TREE_TEST_F
978
979 } // namespace
587 } // namespace cc 980 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/property_tree.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698