Chromium Code Reviews| 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 |