OLD | NEW |
---|---|
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_builder.h" | 5 #include "cc/trees/property_tree_builder.h" |
6 | 6 |
7 #include <map> | |
7 #include <set> | 8 #include <set> |
8 #include <map> | |
9 | 9 |
10 #include "cc/base/math_util.h" | 10 #include "cc/base/math_util.h" |
11 #include "cc/layers/layer.h" | 11 #include "cc/layers/layer.h" |
12 #include "cc/trees/layer_tree_host.h" | 12 #include "cc/trees/layer_tree_host.h" |
13 #include "ui/gfx/point_f.h" | 13 #include "ui/gfx/point_f.h" |
14 | 14 |
15 namespace cc { | 15 namespace cc { |
16 | 16 |
17 class LayerTreeHost; | 17 class LayerTreeHost; |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 // For convenience, we'll use a pointery data structure while we're building | 21 struct ClipAncestorData { |
22 // the property trees (since we won't necessarily be visiting the nodes in | 22 int node_id; |
23 // order and this will make for faster insertions). We'll flatten these pointery | 23 Layer* layer; |
24 // trees later. Eventually cc clients could produce flattened trees directly | |
25 // obviating this step. | |
26 template <typename T> | |
27 struct UnflattenedTreeNode { | |
28 scoped_ptr<T> data; | |
29 // There could be costs assoc'd with copying here if the trees get big, but we | |
30 // don't think that they will. | |
31 ScopedPtrVector<UnflattenedTreeNode<T>> descendants; | |
32 }; | 24 }; |
33 | 25 |
34 typedef UnflattenedTreeNode<OpacityTreeNode> UnflattenedOpacityNode; | |
35 typedef UnflattenedTreeNode<TransformTreeNode> UnflattenedTransformNode; | |
36 typedef UnflattenedTreeNode<ClipTreeNode> UnflattenedClipNode; | |
37 | |
38 struct DataForRecursion { | 26 struct DataForRecursion { |
39 UnflattenedOpacityNode* opacity_tree_parent; | 27 TransformTree* transform_tree; |
40 UnflattenedTransformNode* transform_tree_parent; | 28 ClipTree* clip_tree; |
41 UnflattenedTransformNode* transform_fixed_parent; | 29 OpacityTree* opacity_tree; |
42 std::vector<UnflattenedClipNode*> clip_ancestors; | 30 int transform_tree_parent; |
31 int transform_fixed_parent; | |
32 int opacity_tree_parent; | |
33 std::vector<ClipAncestorData> clip_ancestors; | |
43 gfx::Vector2dF offset_to_transform_parent; | 34 gfx::Vector2dF offset_to_transform_parent; |
35 // TODO(vollick): is this used? | |
44 gfx::Vector2dF offset_to_fixed_parent; | 36 gfx::Vector2dF offset_to_fixed_parent; |
45 const Layer* page_scale_layer; | 37 const Layer* page_scale_layer; |
46 float page_scale_factor; | 38 float page_scale_factor; |
47 float device_scale_factor; | 39 float device_scale_factor; |
48 }; | 40 }; |
49 | 41 |
50 template <typename T> | 42 // Sad trombone. |
51 void SetIndexForLayer(Layer* layer, int index) { | 43 static void UnassignLayersToTree(Layer* layer) { |
52 CHECK(false); // We should not be getting here | 44 layer->set_clip_tree_index(-1); |
53 } | 45 layer->set_transform_tree_index(-1); |
54 | 46 for (size_t i = 0; i < layer->children().size(); ++i) |
55 template <> | 47 UnassignLayersToTree(layer->children()[i].get()); |
56 void SetIndexForLayer<OpacityTreeNode>(Layer* layer, int index) { | |
57 layer->set_opacity_tree_index(index); | |
58 } | |
59 template <> | |
60 void SetIndexForLayer<ClipTreeNode>(Layer* layer, int index) { | |
61 layer->set_clip_tree_index(index); | |
62 } | |
63 | |
64 template <> | |
65 void SetIndexForLayer<TransformTreeNode>(Layer* layer, int index) { | |
66 layer->set_transform_tree_index(index); | |
67 } | |
68 | |
69 template <typename T> | |
70 void AssignLayerIndex(Layer* layer, int current_index, T* tree) { | |
71 CHECK(false); // We should not be getting here | |
72 } | |
73 | |
74 template <> | |
75 void AssignLayerIndex<OpacityTree>(Layer* layer, | |
76 int current_index, | |
77 OpacityTree* opacity_tree) { | |
78 if (opacity_tree->Node(current_index)->layer == layer) { | |
79 SetIndexForLayer<OpacityTreeNode>(layer, current_index); | |
80 return; | |
81 } | |
82 layer->set_opacity_tree_index(current_index); | |
83 } | 48 } |
84 | 49 |
85 // Computes the 2d translation from descendant space to ancestor space, assuming | 50 // Computes the 2d translation from descendant space to ancestor space, assuming |
86 // that all intermediate transforms are only 2d translations. Assumes no | 51 // that all intermediate transforms are only 2d translations. Assumes no |
87 // intermediate layers are scrollable. | 52 // intermediate layers are scrollable. |
88 gfx::Vector2dF ComputeTranslation(const Layer* ancestor, | 53 gfx::Vector2dF ComputeTranslation(const Layer* ancestor, |
89 const Layer* descendant) { | 54 const Layer* descendant) { |
90 // TODO(ajuma): Incorporate this computation into the initial tree walk, to | 55 // TODO(ajuma): Incorporate this computation into the initial tree walk, to |
91 // avoid extra work here. Or compute it using draw transforms, as | 56 // avoid extra work here. Or compute it using draw transforms, as |
92 // CalcDrawProps currently does in ComputeChangeOfBasisTranslation. | 57 // CalcDrawProps currently does in ComputeChangeOfBasisTranslation. |
93 gfx::Vector2dF accumulated_translation; | 58 gfx::Vector2dF accumulated_translation; |
94 for (const Layer* current_layer = descendant; current_layer != ancestor; | 59 for (const Layer* current_layer = descendant; current_layer != ancestor; |
95 current_layer = current_layer->parent()) { | 60 current_layer = current_layer->parent()) { |
96 » //TODO(awoloszyn) This fires from time to time. Figure out why this | 61 // TODO(awoloszyn) This fires from time to time. Figure out why this |
97 » // happening, and whether or not this should be a valid DCHECK | 62 // happening, and whether or not this should be a valid DCHECK |
98 /*DCHECK_EQ(gfx::Vector2dF().ToString(), | 63 // DCHECK_EQ(gfx::Vector2dF().ToString(), |
99 current_layer->TotalScrollOffset().ToString());*/ | 64 // current_layer->TotalScrollOffset().ToString()); |
100 accumulated_translation -= gfx::Vector2dF(current_layer->TotalScrollOffset() .x(), current_layer->TotalScrollOffset().y()); | 65 accumulated_translation -= |
66 gfx::Vector2dF(current_layer->TotalScrollOffset().x(), | |
67 current_layer->TotalScrollOffset().y()); | |
101 accumulated_translation += (current_layer->position() - gfx::PointF()) + | 68 accumulated_translation += (current_layer->position() - gfx::PointF()) + |
102 current_layer->transform().To2dTranslation(); | 69 current_layer->transform().To2dTranslation(); |
103 } | 70 } |
104 return accumulated_translation; | 71 return accumulated_translation; |
105 } | 72 } |
106 | 73 |
107 template <> | 74 // TODO(awoloszyn): This is currently WIP for fixing the fixed element with clip |
108 void AssignLayerIndex<TransformTree>(Layer* layer, | 75 // parent. May not stay. |
109 int current_index, | |
110 TransformTree* transform_tree) { | |
111 if (transform_tree->Node(current_index)->layer == layer) { | |
112 SetIndexForLayer<TransformTreeNode>(layer, current_index); | |
113 return; | |
114 } | |
115 // TODO(ajuma): Compute offset_to_parent for the scroll_parent and clip_parent | |
116 // cases during the earlier tree walk rather than here. | |
117 if (layer->position_constraint().is_fixed_position()) { | |
118 layer->set_transform_tree_index( | |
119 layer->fixed_position_container()->transform_tree_index()); | |
120 } else if (layer->scroll_parent()) { | |
121 layer->set_transform_tree_index( | |
122 layer->scroll_parent()->transform_tree_index()); | |
123 } else { | |
124 layer->set_transform_tree_index(layer->parent()->transform_tree_index()); | |
125 if (layer->clip_parent()) { | |
126 layer->set_offset_to_transform_parent(ComputeTranslation( | |
127 transform_tree->Node(layer->transform_tree_index())->layer, layer)); | |
128 } | |
129 } | |
130 DCHECK_LT(-1, layer->transform_tree_index()); | |
131 } | |
132 | |
133 template <> | |
134 void AssignLayerIndex<ClipTree>(Layer* layer, | |
135 int current_index, | |
136 ClipTree* clip_tree) { | |
137 if (clip_tree->Node(current_index)->layer == layer) { | |
138 SetIndexForLayer<ClipTreeNode>(layer, current_index); | |
139 return; | |
140 } | |
141 if (layer->scroll_parent()) { | |
142 layer->set_clip_tree_index(layer->scroll_parent()->clip_tree_index()); | |
143 } else if (layer->clip_parent()) { | |
144 layer->set_clip_tree_index(layer->clip_parent()->clip_tree_index()); | |
145 } else { | |
146 layer->set_clip_tree_index(layer->parent()->clip_tree_index()); | |
147 } | |
148 DCHECK_LT(-1, layer->clip_tree_index()); | |
149 } | |
150 | |
151 struct FlatteningData { | |
152 Layer* layer; | |
153 UnflattenedOpacityNode* opacity_node; | |
154 UnflattenedTransformNode* transform_node; | |
155 UnflattenedClipNode* clip_node; | |
156 }; | |
157 | |
158 //TODO(awoloszyn) This is currently WIP for fixing the fixed element | |
159 //» » » » with clip parent. May not stay. | |
160 struct SupplementalData { | 76 struct SupplementalData { |
161 Layer* layer; | 77 Layer* layer; |
162 gfx::Vector2dF offset_from_fixed_parent; | 78 gfx::Vector2dF offset_from_fixed_parent; |
163 }; | 79 }; |
164 | 80 |
165 void AssignLayersToTree(ClipTree* clip_tree, | 81 static TransformNode* GetTransformParent( |
166 TransformTree* transform_tree, | |
167 OpacityTree* opacity_tree, | |
168 std::vector<FlatteningData>* flattening_data) { | |
169 for(FlatteningData& data: *flattening_data) { | |
170 AssignLayerIndex(data.layer, data.clip_node->data->id, clip_tree); | |
171 AssignLayerIndex(data.layer, data.transform_node->data->id, transform_tree); | |
172 AssignLayerIndex(data.layer, data.opacity_node->data->id, opacity_tree); | |
173 } | |
174 } | |
175 | |
176 template <typename T> | |
177 void FlattenTreeInternal(UnflattenedTreeNode<T>* unflattened_tree, | |
178 PropertyTree<T>* flattened_tree, | |
179 int parent_id) { | |
180 int currentIndex = | |
181 flattened_tree->InsertWithParent(*unflattened_tree->data, parent_id); | |
182 unflattened_tree->data->id = currentIndex; | |
183 | |
184 for (size_t i = 0; i < unflattened_tree->descendants.size(); ++i) { | |
185 FlattenTreeInternal( | |
186 unflattened_tree->descendants[i], flattened_tree, currentIndex); | |
187 } | |
188 } | |
189 | |
190 template <typename T> | |
191 void FlattenTree(UnflattenedTreeNode<T>* unflattened_tree, | |
192 PropertyTree<T>* flattened_tree) { | |
193 int root_idx = flattened_tree->InsertRootNode(*unflattened_tree->data); | |
194 unflattened_tree->data->id = root_idx; | |
195 for (size_t i = 0; i < unflattened_tree->descendants.size(); ++i) { | |
196 FlattenTreeInternal( | |
197 unflattened_tree->descendants[i], flattened_tree, root_idx); | |
198 } | |
199 } | |
200 | |
201 UnflattenedTransformNode* GetTransformParent( | |
202 const DataForRecursion& data_for_recursion, | 82 const DataForRecursion& data_for_recursion, |
203 Layer* layer) { | 83 Layer* layer) { |
204 if (layer->position_constraint().is_fixed_position()) | 84 if (layer->position_constraint().is_fixed_position()) |
205 return data_for_recursion.transform_fixed_parent; | 85 return data_for_recursion.transform_tree->Node( |
206 return data_for_recursion.transform_tree_parent; | 86 data_for_recursion.transform_fixed_parent); |
87 return data_for_recursion.transform_tree->Node( | |
88 data_for_recursion.transform_tree_parent); | |
207 } | 89 } |
208 | 90 |
209 bool RequiresClipNode(Layer* layer) { | 91 static bool RequiresClipNode(Layer* layer) { |
210 if (!layer->parent()) { | 92 return !layer->parent() || layer->masks_to_bounds() || layer->mask_layer() || |
211 return true; | 93 layer->render_surface(); |
212 } | |
213 if(layer->masks_to_bounds()) { | |
214 return true; | |
215 } | |
216 if (layer->mask_layer()) { | |
217 return true; | |
218 } | |
219 if (layer->render_surface()) { | |
220 return true; | |
221 } | |
222 return false; | |
223 } | 94 } |
224 | 95 |
225 bool Clips(Layer* layer) { | 96 bool Clips(Layer* layer) { |
226 if (layer->masks_to_bounds() || | 97 if (layer->masks_to_bounds() || |
227 layer->mask_layer()) { | 98 layer->mask_layer()) { |
228 return true; | 99 return true; |
229 } | 100 } |
230 if (layer->render_target() != layer) { | 101 if (layer->render_target() != layer) { |
231 return true; | 102 return true; |
232 } | 103 } |
233 return !layer->render_surface()->clip_rect().IsEmpty(); | 104 return !layer->render_surface()->clip_rect().IsEmpty(); |
234 } | 105 } |
235 | 106 |
236 Layer* ClipNodeAncestor(Layer* layer) { | 107 Layer* ClipNodeAncestor(Layer* layer) { |
237 if (RequiresClipNode(layer)) | 108 if (RequiresClipNode(layer)) |
238 return layer; | 109 return layer; |
239 Layer* clip_ancestor = layer->clip_parent(); | 110 Layer* clip_ancestor = layer->clip_parent(); |
240 if (!clip_ancestor) | 111 if (!clip_ancestor) |
241 clip_ancestor = layer->scroll_parent(); | 112 clip_ancestor = layer->scroll_parent(); |
242 if (!clip_ancestor) | 113 if (!clip_ancestor) |
243 clip_ancestor = layer->parent(); | 114 clip_ancestor = layer->parent(); |
244 return ClipNodeAncestor(clip_ancestor); | 115 return ClipNodeAncestor(clip_ancestor); |
245 } | 116 } |
246 | 117 |
247 UnflattenedClipNode* GetClipParent(const DataForRecursion& data_for_recursion, | 118 static ClipNode* GetClipParent(const DataForRecursion& data_for_recursion, |
248 Layer* layer) { | 119 Layer* layer) { |
249 if (!layer->clip_parent()) | 120 if (!layer->parent() || !layer->clip_parent()) { |
250 return data_for_recursion.clip_ancestors.back(); | 121 fprintf(stderr, "aoeu id --> %d\n", |
122 data_for_recursion.clip_ancestors.back().node_id); | |
123 return data_for_recursion.clip_tree->Node( | |
124 data_for_recursion.clip_ancestors.back().node_id); | |
125 } | |
126 | |
251 Layer* clip_node_ancestor = ClipNodeAncestor(layer->clip_parent()); | 127 Layer* clip_node_ancestor = ClipNodeAncestor(layer->clip_parent()); |
252 std::vector<UnflattenedClipNode*>::const_reverse_iterator iter = | 128 fprintf(stderr, "looking for clip parent %p\n", clip_node_ancestor); |
129 std::vector<ClipAncestorData>::const_reverse_iterator iter = | |
253 data_for_recursion.clip_ancestors.rbegin(); | 130 data_for_recursion.clip_ancestors.rbegin(); |
254 for (; iter != data_for_recursion.clip_ancestors.rend(); ++iter) { | 131 for (; iter != data_for_recursion.clip_ancestors.rend(); ++iter) { |
255 if ((*iter)->data->layer == clip_node_ancestor) | 132 if (iter->layer == clip_node_ancestor) |
256 break; | 133 break; |
257 } | 134 } |
258 DCHECK(iter != data_for_recursion.clip_ancestors.rend()); | 135 DCHECK(iter != data_for_recursion.clip_ancestors.rend()); |
259 return *iter; | 136 return data_for_recursion.clip_tree->Node(iter->node_id); |
260 } | 137 } |
261 | 138 |
262 void AddOpacityNodeIfNeeded(const DataForRecursion& data_from_ancestor, | 139 void AddOpacityNodeIfNeeded(const DataForRecursion& data_from_ancestor, |
263 Layer* layer, | 140 Layer* layer, |
264 DataForRecursion* data_for_children) { | 141 DataForRecursion* data_for_children) { |
265 if (layer->parent() && layer->opacity() == 1.0) | 142 if (layer->parent() && layer->opacity() == 1.0) |
266 return; | 143 return; |
267 | 144 |
268 UnflattenedOpacityNode* node = data_from_ancestor.opacity_tree_parent; | |
269 if (layer->parent()) { | 145 if (layer->parent()) { |
270 data_from_ancestor.opacity_tree_parent->descendants.push_back( | 146 data_for_children->opacity_tree_parent = |
271 scoped_ptr<UnflattenedOpacityNode>(new UnflattenedOpacityNode())); | 147 data_from_ancestor.opacity_tree->InsertWithParent( |
272 node = data_from_ancestor.opacity_tree_parent->descendants.back(); | 148 OpacityNode(layer, layer->opacity()), |
273 data_for_children->opacity_tree_parent = node; | 149 data_from_ancestor.opacity_tree_parent); |
274 } | 150 } |
275 | |
276 node->data.reset(new OpacityTreeNode(layer, layer->opacity())); | |
277 } | 151 } |
278 | 152 |
279 void AddClipNodeIfNeeded(const DataForRecursion& data_from_ancestor, | 153 void AddClipNodeIfNeeded(const DataForRecursion& data_from_ancestor, |
280 Layer* layer, | 154 Layer* layer, |
281 DataForRecursion* data_for_children) { | 155 DataForRecursion* data_for_children) { |
282 if (!RequiresClipNode(layer)) | 156 ClipNode* parent = GetClipParent(data_from_ancestor, layer); |
157 if (!RequiresClipNode(layer)) { | |
158 layer->set_clip_tree_index(parent->id); | |
159 // if (layer->scroll_parent()) { | |
160 // layer->set_clip_tree_index(layer->scroll_parent()->clip_tree_index()); | |
161 // } else if (layer->clip_parent()) { | |
162 // layer->set_clip_tree_index(layer->clip_parent()->clip_tree_index()); | |
163 // } else { | |
164 // layer->set_clip_tree_index(layer->parent()->clip_tree_index()); | |
165 // } | |
283 return; | 166 return; |
284 | |
285 UnflattenedClipNode* node = data_from_ancestor.clip_ancestors.back(); | |
286 if (layer->parent()) { | |
287 UnflattenedClipNode* parent = GetClipParent(data_from_ancestor, layer); | |
288 parent->descendants.push_back( | |
289 scoped_ptr<UnflattenedClipNode>(new UnflattenedClipNode())); | |
290 node = parent->descendants.back(); | |
291 data_for_children->clip_ancestors.push_back(node); | |
292 } | 167 } |
293 | 168 |
294 node->data.reset(new ClipTreeNode(layer, gfx::RectF(layer->bounds()), | 169 // TODO(vollick): we should add the node for the parent here.. |
295 Clips(layer))); | 170 if (layer->parent()) { |
171 ClipAncestorData clip_ancestor_data; | |
172 clip_ancestor_data.node_id = data_for_children->clip_tree->InsertWithParent( | |
173 ClipNode(layer, gfx::RectF(layer->bounds()), Clips(layer)), parent->id); | |
174 clip_ancestor_data.layer = layer; | |
175 data_for_children->clip_ancestors.push_back(clip_ancestor_data); | |
176 } | |
177 | |
296 // TODO(awoloszyn): Right now when we hit a node with a replica, we | 178 // TODO(awoloszyn): Right now when we hit a node with a replica, we |
297 // reset the clip for all children since we may need to draw. We | 179 // reset the clip for all children since we may need to draw. We |
298 // need to figure out a better way, since we will need both the | 180 // need to figure out a better way, since we will need both the |
299 // clipped and unclipped versions. | 181 // clipped and unclipped versions. |
300 } | 182 } |
301 | 183 |
302 void AddTransformNodeIfNeeded(const DataForRecursion& data_from_ancestor, | 184 void AddTransformNodeIfNeeded(const DataForRecursion& data_from_ancestor, |
303 Layer* layer, | 185 Layer* layer, |
304 DataForRecursion* data_for_children, | 186 DataForRecursion* data_for_children, |
305 std::map<Layer*, SupplementalData>* supplemental_d ata) { | 187 std::map<Layer*, SupplementalData>* supplemental_d ata) { |
306 const bool is_root = !layer->parent(); | 188 const bool is_root = !layer->parent(); |
307 const bool is_page_scale_application_layer = | 189 const bool is_page_scale_application_layer = |
308 layer == data_from_ancestor.page_scale_layer; | 190 layer == data_from_ancestor.page_scale_layer; |
309 const bool is_scrollable = layer->scrollable(); | 191 const bool is_scrollable = layer->scrollable(); |
310 const bool is_fixed = layer->position_constraint().is_fixed_position(); | 192 const bool is_fixed = layer->position_constraint().is_fixed_position(); |
311 | 193 |
312 const bool has_significant_transform = | 194 const bool has_significant_transform = |
313 !layer->transform().IsIdentityOrTranslation(); | 195 !layer->transform().IsIdentityOrTranslation(); |
314 | 196 |
315 const bool has_animated_transform = | 197 const bool has_animated_transform = |
316 layer->layer_animation_controller()->IsAnimatingProperty( | 198 layer->layer_animation_controller()->IsAnimatingProperty( |
317 Animation::Transform); | 199 Animation::Transform); |
318 | 200 |
319 bool requires_transform_node = | 201 bool requires_transform_node = |
320 is_root || is_scrollable || is_fixed || has_significant_transform || | 202 is_root || is_scrollable || is_fixed || has_significant_transform || |
321 has_animated_transform || is_page_scale_application_layer; | 203 has_animated_transform || is_page_scale_application_layer; |
322 | 204 |
323 if (!requires_transform_node) { | 205 if (!requires_transform_node) { |
324 // DCHECK_EQ(gfx::Vector2dF().ToString(), | 206 // TODO(vollick): This can be drastrically simplified if we don't have an |
325 // layer->TotalScrollOffset().ToString()); | 207 // unflattened tree. We should be able to grab the transform parent |
326 // TODO(vollick): it's a little silly we have to jump through these hoops to | 208 // immediately and then compute an offset to it in a helper that can account |
327 // get a vector from a point. Surely there's a better way. | 209 // for scroll parents, fixed pos, etc. Leaving the logic here like this |
210 // temporarily while I convert away from unflattened trees. | |
328 data_for_children->offset_to_transform_parent += | 211 data_for_children->offset_to_transform_parent += |
329 (layer->position() - gfx::PointF()) + | 212 layer->position().OffsetFromOrigin() + |
awoloszyn
2014/11/12 19:38:59
That is way nicer.
| |
330 layer->transform().To2dTranslation(); | 213 layer->transform().To2dTranslation(); |
331 | 214 |
332 if (layer->IsContainerForFixedPositionLayers()) { | 215 if (layer->IsContainerForFixedPositionLayers()) { |
333 data_for_children->transform_fixed_parent = | 216 data_for_children->transform_fixed_parent = |
334 GetTransformParent(data_from_ancestor, layer); | 217 GetTransformParent(data_from_ancestor, layer)->id; |
335 } | 218 } |
336 data_for_children->offset_to_fixed_parent = | 219 data_for_children->offset_to_fixed_parent = |
337 data_from_ancestor.offset_to_fixed_parent; | 220 data_from_ancestor.offset_to_fixed_parent; |
338 if(layer->scroll_parent()) { | 221 if(layer->scroll_parent()) { |
339 gfx::Vector2dF offset_from_transform_parent_to_parent = ComputeTranslation ( | 222 gfx::Vector2dF offset_from_transform_parent_to_parent = |
340 layer->parent(), | 223 ComputeTranslation( |
341 data_from_ancestor.transform_tree_parent->data->layer); | 224 layer->parent(), |
225 data_from_ancestor.transform_tree | |
226 ->Node(data_from_ancestor.transform_tree_parent) | |
227 ->layer); | |
342 gfx::Vector2dF offset_to_parent = | 228 gfx::Vector2dF offset_to_parent = |
343 ComputeTranslation(layer->parent(), layer); | 229 ComputeTranslation(layer->parent(), layer); |
344 layer->set_offset_to_transform_parent( | 230 layer->set_offset_to_transform_parent( |
345 offset_to_parent - offset_from_transform_parent_to_parent); | 231 offset_to_parent - offset_from_transform_parent_to_parent); |
346 data_for_children->offset_to_transform_parent = layer->offset_to_trans form_parent(); | 232 data_for_children->offset_to_transform_parent = layer->offset_to_trans form_parent(); |
347 } else { | 233 } else { |
348 layer->set_offset_to_transform_parent( | 234 layer->set_offset_to_transform_parent( |
349 data_for_children->offset_to_transform_parent); | 235 data_for_children->offset_to_transform_parent); |
350 } | 236 } |
237 | |
238 TransformNode* transform_parent = | |
239 GetTransformParent(data_from_ancestor, layer); | |
awoloszyn
2014/11/12 19:38:59
GetTransformParent does not take into account scro
| |
240 | |
241 layer->set_transform_tree_index(transform_parent->id); | |
242 | |
243 // TODO(vollick): see note above. | |
244 if (!is_fixed && !layer->scroll_parent() && layer->clip_parent()) { | |
245 if (layer->clip_parent()) { | |
awoloszyn
2014/11/12 19:38:59
This line is redundant.
| |
246 layer->set_offset_to_transform_parent( | |
247 ComputeTranslation(data_from_ancestor.transform_tree | |
248 ->Node(layer->transform_tree_index()) | |
249 ->layer, | |
250 layer)); | |
251 } | |
252 } | |
253 | |
351 return; | 254 return; |
352 } | 255 } |
353 | 256 |
354 if (is_fixed) { | 257 if (is_fixed) { |
355 layer->set_fixed_position_container( | 258 layer->set_fixed_position_container( |
356 GetTransformParent(data_from_ancestor, layer)->data->layer); | 259 GetTransformParent(data_from_ancestor, layer)->layer); |
357 } else { | 260 } else { |
358 layer->set_fixed_position_container(NULL); | 261 layer->set_fixed_position_container(NULL); |
359 } | 262 } |
360 | 263 |
361 UnflattenedTransformNode* node = data_from_ancestor.transform_tree_parent; | |
362 if (layer->parent()) { | |
363 UnflattenedTransformNode* parent = | |
364 GetTransformParent(data_from_ancestor, layer); | |
365 parent->descendants.push_back( | |
366 scoped_ptr<UnflattenedTransformNode>(new UnflattenedTransformNode())); | |
367 node = parent->descendants.back(); | |
368 } | |
369 | |
370 if (layer->IsContainerForFixedPositionLayers()) { | |
371 data_for_children->transform_fixed_parent = node; | |
372 data_for_children->offset_to_fixed_parent = gfx::Vector2dF(); | |
373 } else { | |
374 data_for_children->offset_to_fixed_parent += | |
375 data_for_children->offset_to_transform_parent; | |
376 } | |
377 | |
378 data_for_children->transform_tree_parent = node; | |
379 data_for_children->offset_to_transform_parent = gfx::Vector2dF(); | |
380 layer->set_offset_to_transform_parent( | |
381 data_for_children->offset_to_transform_parent); | |
382 | |
383 gfx::Vector2dF offset_to_transform_parent = | 264 gfx::Vector2dF offset_to_transform_parent = |
384 data_from_ancestor.offset_to_transform_parent; | 265 data_from_ancestor.offset_to_transform_parent; |
385 | 266 |
386 if(layer->scroll_parent()) { | 267 if(layer->scroll_parent()) { |
387 gfx::Vector2dF offset_from_transform_parent_to_parent = ComputeTranslation( | 268 gfx::Vector2dF offset_from_transform_parent_to_parent = ComputeTranslation( |
388 layer->parent(), | 269 layer->parent(), data_from_ancestor.transform_tree |
389 data_from_ancestor.transform_tree_parent->data->layer); | 270 ->Node(data_from_ancestor.transform_tree_parent) |
271 ->layer); | |
390 gfx::Vector2dF offset_to_parent = | 272 gfx::Vector2dF offset_to_parent = |
391 ComputeTranslation(layer->parent(), layer); | 273 ComputeTranslation(layer->parent(), layer); |
392 layer->set_offset_to_transform_parent( | 274 layer->set_offset_to_transform_parent( |
393 offset_to_parent - offset_from_transform_parent_to_parent); | 275 offset_to_parent - offset_from_transform_parent_to_parent); |
394 offset_to_transform_parent = layer->offset_to_transform_parent(); | 276 offset_to_transform_parent = layer->offset_to_transform_parent(); |
395 } | 277 } |
396 | 278 |
397 gfx::Transform transform; | 279 gfx::Transform transform; |
398 float device_and_page_scale_factors = 1.0f; | 280 float device_and_page_scale_factors = 1.0f; |
399 if (is_root) { | 281 if (is_root) { |
400 device_and_page_scale_factors = data_from_ancestor.device_scale_factor; | 282 device_and_page_scale_factors = data_from_ancestor.device_scale_factor; |
401 } | 283 } |
402 | 284 |
403 if (is_page_scale_application_layer) { | 285 if (is_page_scale_application_layer) { |
404 device_and_page_scale_factors *= data_from_ancestor.page_scale_factor; | 286 device_and_page_scale_factors *= data_from_ancestor.page_scale_factor; |
405 } | 287 } |
406 | 288 |
407 transform.Scale(device_and_page_scale_factors, device_and_page_scale_factors); | 289 transform.Scale(device_and_page_scale_factors, device_and_page_scale_factors); |
408 // This may be backwards (we may need to apply the accumulated offset on the | 290 // This may be backwards (we may need to apply the accumulated offset on the |
409 // "other side"). NB: We've accounted for the scroll offset here but we | 291 // "other side"). NB: We've accounted for the scroll offset here but we |
410 // haven't taken into account snapping to screen space pixels (since we | 292 // haven't taken into account snapping to screen space pixels (since we |
411 // haven't computed any screen space transforms). For the purposes of | 293 // haven't computed any screen space transforms). For the purposes of |
412 // computing rects we need to record, this should be fine (the visible rects | 294 // computing rects we need to record, this should be fine (the visible rects |
413 // we compute may be slightly different than what we'd compute with snapping, | 295 // we compute may be slightly different than what we'd compute with snapping, |
414 // but since we significantly expand the visible rect when determining what to | 296 // but since we significantly expand the visible rect when determining what to |
415 // record, the slight difference should be inconsequential). | 297 // record, the slight difference should be inconsequential). |
416 gfx::Vector2dF position = layer->position() - gfx::PointF(); | 298 gfx::Vector2dF position = layer->position() - gfx::PointF(); |
417 if (!layer->scroll_parent()) { | 299 if (!layer->scroll_parent()) { |
418 position -= gfx::Vector2dF(layer->TotalScrollOffse t().x(), | 300 position -= gfx::Vector2dF(layer->TotalScrollOffset().x(), |
419 layer->TotalScrollOffset().y()); | 301 layer->TotalScrollOffset().y()); |
420 } | 302 } |
421 // - | |
422 // / gfx::PointF(layer->TotalScrollOffset().x(), | |
423 // layer->TotalScrollOffset().y()); | |
424 if (is_fixed) { | 303 if (is_fixed) { |
425 auto supplemental = supplemental_data->find(layer); | 304 auto supplemental = supplemental_data->find(layer); |
426 if (supplemental != supplemental_data->end()) { | 305 if (supplemental != supplemental_data->end()) { |
427 position += supplemental->second.offset_from_fixed_parent; | 306 position += supplemental->second.offset_from_fixed_parent; |
428 } else { | 307 } else { |
429 position += data_from_ancestor.offset_to_fixed_parent; | 308 position += data_from_ancestor.offset_to_fixed_parent; |
430 } | 309 } |
431 } else { | 310 } else { |
432 position += offset_to_transform_parent; | 311 position += offset_to_transform_parent; |
433 | |
434 } | 312 } |
435 transform.Translate3d(position.x() + layer->transform_origin().x(), | 313 transform.Translate3d(position.x() + layer->transform_origin().x(), |
436 position.y() + layer->transform_origin().y(), | 314 position.y() + layer->transform_origin().y(), |
437 layer->transform_origin().z()); | 315 layer->transform_origin().z()); |
438 transform.PreconcatTransform(layer->transform()); | 316 transform.PreconcatTransform(layer->transform()); |
439 transform.Translate3d(-layer->transform_origin().x(), | 317 transform.Translate3d(-layer->transform_origin().x(), |
440 -layer->transform_origin().y(), | 318 -layer->transform_origin().y(), |
441 -layer->transform_origin().z()); | 319 -layer->transform_origin().z()); |
442 | 320 |
443 node->data.reset(new TransformTreeNode(layer, transform)); | 321 if (is_root) { |
322 data_from_ancestor.transform_tree->root()->value = transform; | |
323 } else { | |
324 data_for_children->transform_tree_parent = | |
325 data_from_ancestor.transform_tree->InsertWithParent( | |
326 TransformNode(layer, transform), | |
327 GetTransformParent(data_from_ancestor, layer)->id); | |
328 } | |
329 | |
330 if (layer->IsContainerForFixedPositionLayers() || is_root) { | |
331 data_for_children->transform_fixed_parent = | |
332 data_for_children->transform_tree_parent; | |
333 data_for_children->offset_to_fixed_parent = gfx::Vector2dF(); | |
334 } else { | |
335 data_for_children->offset_to_fixed_parent += | |
336 data_for_children->offset_to_transform_parent; | |
337 } | |
338 | |
339 data_for_children->offset_to_transform_parent = gfx::Vector2dF(); | |
340 layer->set_offset_to_transform_parent(gfx::Vector2dF()); | |
341 layer->set_transform_tree_index(data_for_children->transform_tree_parent); | |
444 } | 342 } |
445 | 343 |
446 void BuildPropertyTreesInternal(Layer* layer, | 344 void BuildPropertyTreesInternal(Layer* layer, |
447 const DataForRecursion& data_from_parent, | 345 const DataForRecursion& data_from_parent, |
448 std::vector<FlatteningData>* flattening_data, | |
449 std::map<Layer*, SupplementalData>* supplemental _data) { | 346 std::map<Layer*, SupplementalData>* supplemental _data) { |
450 DataForRecursion data_for_children(data_from_parent); | 347 DataForRecursion data_for_children(data_from_parent); |
451 | 348 |
452 AddOpacityNodeIfNeeded(data_from_parent, layer, &data_for_children); | 349 AddOpacityNodeIfNeeded(data_from_parent, layer, &data_for_children); |
350 AddTransformNodeIfNeeded(data_from_parent, layer, &data_for_children, suppleme ntal_data); | |
351 layer->set_transform_tree_index(data_for_children.transform_tree_parent); | |
352 | |
453 AddClipNodeIfNeeded(data_from_parent, layer, &data_for_children); | 353 AddClipNodeIfNeeded(data_from_parent, layer, &data_for_children); |
454 AddTransformNodeIfNeeded(data_from_parent, layer, &data_for_children, suppleme ntal_data); | 354 layer->set_clip_tree_index(data_for_children.clip_ancestors.back().node_id); |
455 | 355 |
456 flattening_data->push_back((FlatteningData){layer, data_for_children.opacity_t ree_parent, | |
457 data_for_children.transform_tree_parent, | |
458 data_for_children.clip_ancestors.back()}); | |
459 | 356 |
460 for (size_t i = 0; i < layer->children().size(); ++i) { | 357 for (size_t i = 0; i < layer->children().size(); ++i) { |
358 // TODO(vollick): this should read: if (!scroll child) { recur; } | |
461 if ((layer->children()[i]->scroll_parent() && | 359 if ((layer->children()[i]->scroll_parent() && |
462 layer->children()[i]->scroll_parent() != layer) || | 360 layer->children()[i]->scroll_parent() != layer) || |
463 (!layer->children()[i]->scroll_parent() && | 361 (!layer->children()[i]->scroll_parent() && |
464 layer->children()[i]->clip_parent() && | 362 layer->children()[i]->clip_parent() && |
465 layer->children()[i]->clip_parent() != layer) ) { | 363 layer->children()[i]->clip_parent() != layer) ) { |
466 // TODO(awoloszyn): Clean this up. | 364 // TODO(awoloszyn): Clean this up. |
467 auto a = supplemental_data->insert(std::pair<Layer*, SupplementalData>( | 365 auto a = supplemental_data->insert(std::pair<Layer*, SupplementalData>( |
468 layer->children()[i].get(), (SupplementalData){layer->children()[i].ge t(), | 366 layer->children()[i].get(), (SupplementalData){layer->children()[i].ge t(), |
469 data_for_children.offset_to_fixed_parent})); | 367 data_for_children.offset_to_fixed_parent})); |
470 DCHECK(a.second); | 368 DCHECK(a.second); |
471 continue; | 369 continue; |
472 } | 370 } |
473 BuildPropertyTreesInternal(layer->children()[i].get(), data_for_children, fl attening_data, supplemental_data); | 371 BuildPropertyTreesInternal(layer->children()[i].get(), data_for_children, su pplemental_data); |
474 } | 372 } |
475 | 373 |
476 if (std::set<Layer*>* scroll_children = layer->scroll_children()) { | 374 if (std::set<Layer*>* scroll_children = layer->scroll_children()) { |
477 std::set<Layer*>::const_iterator iter = scroll_children->begin(); | 375 std::set<Layer*>::const_iterator iter = scroll_children->begin(); |
478 for (; iter != scroll_children->end(); ++iter) | 376 for (; iter != scroll_children->end(); ++iter) |
479 BuildPropertyTreesInternal(*iter, data_for_children, flattening_data, supp lemental_data); | 377 BuildPropertyTreesInternal(*iter, data_for_children, supplemental_data); |
480 } | 378 } |
379 // TODO(vollick): we should be able to visit clip children during the "normal" | |
380 // recursion. | |
481 if (std::set<Layer*>* clip_children = layer->clip_children()) { | 381 if (std::set<Layer*>* clip_children = layer->clip_children()) { |
482 std::set<Layer*>::const_iterator iter = clip_children->begin(); | 382 std::set<Layer*>::const_iterator iter = clip_children->begin(); |
483 for (; iter != clip_children->end(); ++iter) | 383 for (; iter != clip_children->end(); ++iter) |
484 BuildPropertyTreesInternal(*iter, data_for_children, flattening_data, supp lemental_data); | 384 BuildPropertyTreesInternal(*iter, data_for_children, supplemental_data); |
485 } | 385 } |
486 } | 386 } |
487 | 387 |
488 template void FlattenTreeInternal(UnflattenedClipNode* unflattened_tree, | |
489 ClipTree* flattened_tree, | |
490 int parent_id); | |
491 template void FlattenTreeInternal(UnflattenedOpacityNode* unflattened_tree, | |
492 OpacityTree* flattened_tree, | |
493 int parent_id); | |
494 template void FlattenTreeInternal(UnflattenedTransformNode* unflattened_tree, | |
495 TransformTree* flattened_tree, | |
496 int parent_id); | |
497 | |
498 template void FlattenTree(UnflattenedClipNode* unflattened_tree, | |
499 ClipTree* flattened_tree); | |
500 template void FlattenTree(UnflattenedOpacityNode* unflattened_tree, | |
501 OpacityTree* flattened_tree); | |
502 template void FlattenTree(UnflattenedTransformNode* unflattened_tree, | |
503 TransformTree* flattened_tree); | |
504 } // namespace | 388 } // namespace |
505 | 389 |
506 void PropertyTreeBuilder::BuildPropertyTrees( | 390 void PropertyTreeBuilder::BuildPropertyTrees( |
507 Layer* root_layer, | 391 Layer* root_layer, |
508 const Layer* page_scale_layer, | 392 const Layer* page_scale_layer, |
509 float page_scale_factor, | 393 float page_scale_factor, |
510 float device_scale_factor, | 394 float device_scale_factor, |
511 const gfx::Rect& viewport, | 395 const gfx::Rect& viewport, |
512 const gfx::Transform& device_transform, | 396 const gfx::Transform& device_transform, |
513 OpacityTree* opacity_tree, | 397 OpacityTree* opacity_tree, |
514 TransformTree* transform_tree, | 398 TransformTree* transform_tree, |
515 ClipTree* clip_tree) { | 399 ClipTree* clip_tree) { |
516 std::vector<FlatteningData> flattening_data; | |
517 std::map<Layer*, SupplementalData> supplemental_data; | 400 std::map<Layer*, SupplementalData> supplemental_data; |
518 UnflattenedOpacityNode unflattened_opacity_tree; | |
519 UnflattenedTransformNode unflattened_transform_tree; | |
520 UnflattenedClipNode unflattened_clip_tree; | |
521 | 401 |
522 DataForRecursion data_for_recursion; | 402 DataForRecursion data_for_recursion; |
523 data_for_recursion.opacity_tree_parent = &unflattened_opacity_tree; | 403 data_for_recursion.transform_tree = transform_tree; |
524 data_for_recursion.transform_tree_parent = &unflattened_transform_tree; | 404 data_for_recursion.clip_tree = clip_tree; |
525 data_for_recursion.transform_fixed_parent = &unflattened_transform_tree; | 405 data_for_recursion.opacity_tree = opacity_tree; |
526 data_for_recursion.clip_ancestors.push_back(&unflattened_clip_tree); | 406 data_for_recursion.transform_tree_parent = 0; |
407 data_for_recursion.transform_fixed_parent = 0; | |
527 data_for_recursion.page_scale_layer = page_scale_layer; | 408 data_for_recursion.page_scale_layer = page_scale_layer; |
528 data_for_recursion.page_scale_factor = page_scale_factor; | 409 data_for_recursion.page_scale_factor = page_scale_factor; |
529 data_for_recursion.device_scale_factor = device_scale_factor; | 410 data_for_recursion.device_scale_factor = device_scale_factor; |
530 | 411 |
531 BuildPropertyTreesInternal(root_layer, data_for_recursion, &flattening_data, & supplemental_data); | 412 ClipAncestorData root_clip_data = { 0, root_layer }; |
413 data_for_recursion.clip_ancestors.push_back(root_clip_data); | |
532 | 414 |
533 FlattenTree(&unflattened_opacity_tree, opacity_tree); | 415 BuildPropertyTreesInternal(root_layer, data_for_recursion, &supplemental_data) ; |
534 FlattenTree(&unflattened_clip_tree, clip_tree); | 416 |
535 FlattenTree(&unflattened_transform_tree, transform_tree); | |
536 AssignLayersToTree(clip_tree, transform_tree, opacity_tree, &flattening_data); | |
537 | 417 |
538 if (viewport.IsEmpty()) | 418 if (viewport.IsEmpty()) |
539 clip_tree->root()->clips = false; | 419 clip_tree->root()->clips = false; |
540 | 420 |
541 | 421 |
542 gfx::RectF transformed_viewport; | 422 gfx::RectF transformed_viewport; |
543 gfx::Transform combined_transform = transform_tree->root()->value; | 423 gfx::Transform combined_transform = transform_tree->root()->value; |
544 combined_transform.ConcatTransform(device_transform); | 424 combined_transform.ConcatTransform(device_transform); |
545 transform_tree->root()->value = combined_transform; | 425 transform_tree->root()->value = combined_transform; |
546 if (combined_transform.IsIdentity()) { | 426 if (combined_transform.IsIdentity()) { |
547 transformed_viewport = viewport; | 427 transformed_viewport = viewport; |
548 } else { | 428 } else { |
549 gfx::Transform inverse_transform; | 429 gfx::Transform inverse_transform; |
550 if (!combined_transform.GetInverse(&inverse_transform)) { | 430 if (!combined_transform.GetInverse(&inverse_transform)) { |
551 // If we have an univertible transform, then we clip off the entire | 431 // If we have an univertible transform, then we clip off the entire |
552 // subtree. | 432 // subtree. |
553 transformed_viewport = gfx::RectF(); | 433 transformed_viewport = gfx::RectF(); |
554 } else { | 434 } else { |
555 transformed_viewport = | 435 transformed_viewport = |
556 MathUtil::ProjectClippedRect(inverse_transform, viewport); | 436 MathUtil::ProjectClippedRect(inverse_transform, viewport); |
557 } | 437 } |
558 } | 438 } |
559 clip_tree->root()->value = transformed_viewport; | 439 clip_tree->root()->value = transformed_viewport; |
560 transform_tree->root()->clip_rect = transformed_viewport; | 440 transform_tree->root()->clip_rect = transformed_viewport; |
561 } | 441 } |
562 | 442 |
563 } // namespace cc | 443 } // namespace cc |
OLD | NEW |