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

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

Issue 1097583002: cc: Commit property trees to the compositor thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months 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
« cc/layers/layer.h ('K') | « cc/trees/property_tree_builder.h ('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_builder.h" 5 #include "cc/trees/property_tree_builder.h"
6 6
7 #include <map> 7 #include <map>
8 #include <set> 8 #include <set>
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/layers/layer_impl.h"
12 #include "cc/trees/layer_tree_host.h" 13 #include "cc/trees/layer_tree_host.h"
13 #include "ui/gfx/geometry/point_f.h" 14 #include "ui/gfx/geometry/point_f.h"
14 #include "ui/gfx/geometry/vector2d_conversions.h" 15 #include "ui/gfx/geometry/vector2d_conversions.h"
15 16
16 namespace cc { 17 namespace cc {
17 18
18 class LayerTreeHost; 19 class LayerTreeHost;
19 20
20 namespace { 21 namespace {
21 22
23 template <typename LayerType>
22 struct DataForRecursion { 24 struct DataForRecursion {
23 TransformTree* transform_tree; 25 TransformTree* transform_tree;
24 ClipTree* clip_tree; 26 ClipTree* clip_tree;
25 OpacityTree* opacity_tree; 27 OpacityTree* opacity_tree;
26 Layer* transform_tree_parent; 28 LayerType* transform_tree_parent;
27 Layer* transform_fixed_parent; 29 LayerType* transform_fixed_parent;
28 Layer* render_target; 30 LayerType* render_target;
29 int clip_tree_parent; 31 int clip_tree_parent;
30 int opacity_tree_parent; 32 int opacity_tree_parent;
31 const Layer* page_scale_layer; 33 const LayerType* page_scale_layer;
32 float page_scale_factor; 34 float page_scale_factor;
33 float device_scale_factor; 35 float device_scale_factor;
34 bool in_subtree_of_page_scale_application_layer; 36 bool in_subtree_of_page_scale_application_layer;
35 bool should_flatten; 37 bool should_flatten;
36 bool ancestor_clips_subtree; 38 bool ancestor_clips_subtree;
37 const gfx::Transform* device_transform; 39 const gfx::Transform* device_transform;
38 gfx::Vector2dF scroll_compensation_adjustment; 40 gfx::Vector2dF scroll_compensation_adjustment;
39 }; 41 };
40 42
41 static Layer* GetTransformParent(const DataForRecursion& data, Layer* layer) { 43 template <typename LayerType>
44 static LayerType* GetTransformParent(const DataForRecursion<LayerType>& data,
45 LayerType* layer) {
42 return layer->position_constraint().is_fixed_position() 46 return layer->position_constraint().is_fixed_position()
43 ? data.transform_fixed_parent 47 ? data.transform_fixed_parent
44 : data.transform_tree_parent; 48 : data.transform_tree_parent;
45 } 49 }
46 50
47 static ClipNode* GetClipParent(const DataForRecursion& data, Layer* layer) { 51 template <typename LayerType>
52 static ClipNode* GetClipParent(const DataForRecursion<LayerType>& data,
53 LayerType* layer) {
48 const bool inherits_clip = !layer->parent() || !layer->clip_parent(); 54 const bool inherits_clip = !layer->parent() || !layer->clip_parent();
49 const int id = inherits_clip ? data.clip_tree_parent 55 const int id = inherits_clip ? data.clip_tree_parent
50 : layer->clip_parent()->clip_tree_index(); 56 : layer->clip_parent()->clip_tree_index();
51 return data.clip_tree->Node(id); 57 return data.clip_tree->Node(id);
52 } 58 }
53 59
54 static bool RequiresClipNode(Layer* layer, 60 template <typename LayerType>
55 const DataForRecursion& data, 61 static bool RequiresClipNode(LayerType* layer,
62 const DataForRecursion<LayerType>& data,
56 int parent_transform_id, 63 int parent_transform_id,
57 bool is_clipped) { 64 bool is_clipped) {
58 const bool render_surface_applies_clip = 65 const bool render_surface_applies_clip =
59 layer->render_surface() && is_clipped; 66 layer->render_surface() && is_clipped;
60 const bool render_surface_may_grow_due_to_clip_children = 67 const bool render_surface_may_grow_due_to_clip_children =
61 layer->render_surface() && layer->num_unclipped_descendants() > 0; 68 layer->render_surface() && layer->num_unclipped_descendants() > 0;
62 69
63 if (!layer->parent() || layer->masks_to_bounds() || layer->mask_layer() || 70 if (!layer->parent() || layer->masks_to_bounds() || layer->mask_layer() ||
64 render_surface_may_grow_due_to_clip_children) 71 render_surface_may_grow_due_to_clip_children)
65 return true; 72 return true;
66 73
67 if (!render_surface_applies_clip) 74 if (!render_surface_applies_clip)
68 return false; 75 return false;
69 76
70 bool axis_aligned_with_respect_to_parent = 77 bool axis_aligned_with_respect_to_parent =
71 data.transform_tree->Are2DAxisAligned(layer->transform_tree_index(), 78 data.transform_tree->Are2DAxisAligned(layer->transform_tree_index(),
72 parent_transform_id); 79 parent_transform_id);
73 80
74 return !axis_aligned_with_respect_to_parent; 81 return !axis_aligned_with_respect_to_parent;
75 } 82 }
76 83
77 static bool LayerClipsSubtree(Layer* layer) { 84 template <typename LayerType>
85 static bool LayerClipsSubtree(LayerType* layer) {
78 return layer->masks_to_bounds() || layer->mask_layer(); 86 return layer->masks_to_bounds() || layer->mask_layer();
79 } 87 }
80 88
81 void AddClipNodeIfNeeded(const DataForRecursion& data_from_ancestor, 89 template <typename LayerType>
82 Layer* layer, 90 void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor,
91 LayerType* layer,
83 bool created_transform_node, 92 bool created_transform_node,
84 DataForRecursion* data_for_children) { 93 DataForRecursion<LayerType>* data_for_children) {
85 ClipNode* parent = GetClipParent(data_from_ancestor, layer); 94 ClipNode* parent = GetClipParent(data_from_ancestor, layer);
86 int parent_id = parent->id; 95 int parent_id = parent->id;
87 96
88 bool ancestor_clips_subtree = 97 bool ancestor_clips_subtree =
89 data_from_ancestor.ancestor_clips_subtree || layer->clip_parent(); 98 data_from_ancestor.ancestor_clips_subtree || layer->clip_parent();
90 99
91 data_for_children->ancestor_clips_subtree = false; 100 data_for_children->ancestor_clips_subtree = false;
92 bool has_unclipped_surface = false; 101 bool has_unclipped_surface = false;
93 102
94 if (layer->has_render_surface()) { 103 if (layer->has_render_surface()) {
(...skipping 10 matching lines...) Expand all
105 114
106 if (has_unclipped_surface) 115 if (has_unclipped_surface)
107 parent_id = 0; 116 parent_id = 0;
108 117
109 if (!RequiresClipNode(layer, data_from_ancestor, parent->data.transform_id, 118 if (!RequiresClipNode(layer, data_from_ancestor, parent->data.transform_id,
110 data_for_children->ancestor_clips_subtree)) { 119 data_for_children->ancestor_clips_subtree)) {
111 // Unclipped surfaces reset the clip rect. 120 // Unclipped surfaces reset the clip rect.
112 data_for_children->clip_tree_parent = parent_id; 121 data_for_children->clip_tree_parent = parent_id;
113 } else if (layer->parent()) { 122 } else if (layer->parent()) {
114 // Note the root clip gets handled elsewhere. 123 // Note the root clip gets handled elsewhere.
115 Layer* transform_parent = data_for_children->transform_tree_parent; 124 LayerType* transform_parent = data_for_children->transform_tree_parent;
116 if (layer->position_constraint().is_fixed_position() && 125 if (layer->position_constraint().is_fixed_position() &&
117 !created_transform_node) { 126 !created_transform_node) {
118 transform_parent = data_for_children->transform_fixed_parent; 127 transform_parent = data_for_children->transform_fixed_parent;
119 } 128 }
120 ClipNode node; 129 ClipNode node;
121 node.data.clip = gfx::RectF( 130 node.data.clip = gfx::RectF(
122 gfx::PointF() + layer->offset_to_transform_parent(), layer->bounds()); 131 gfx::PointF() + layer->offset_to_transform_parent(), layer->bounds());
123 node.data.transform_id = transform_parent->transform_tree_index(); 132 node.data.transform_id = transform_parent->transform_tree_index();
124 node.data.target_id = 133 node.data.target_id =
125 data_for_children->render_target->transform_tree_index(); 134 data_for_children->render_target->transform_tree_index();
126 135
127 data_for_children->clip_tree_parent = 136 data_for_children->clip_tree_parent =
128 data_for_children->clip_tree->Insert(node, parent_id); 137 data_for_children->clip_tree->Insert(node, parent_id);
129 } 138 }
130 139
131 layer->set_clip_tree_index( 140 layer->set_clip_tree_index(
132 has_unclipped_surface ? 0 : data_for_children->clip_tree_parent); 141 has_unclipped_surface ? 0 : data_for_children->clip_tree_parent);
133 142
134 // TODO(awoloszyn): Right now when we hit a node with a replica, we reset the 143 // TODO(awoloszyn): Right now when we hit a node with a replica, we reset the
135 // clip for all children since we may need to draw. We need to figure out a 144 // clip for all children since we may need to draw. We need to figure out a
136 // better way, since we will need both the clipped and unclipped versions. 145 // better way, since we will need both the clipped and unclipped versions.
137 } 146 }
138 147
139 bool AddTransformNodeIfNeeded(const DataForRecursion& data_from_ancestor, 148 template <typename LayerType>
140 Layer* layer, 149 bool AddTransformNodeIfNeeded(
141 DataForRecursion* data_for_children) { 150 const DataForRecursion<LayerType>& data_from_ancestor,
151 LayerType* layer,
152 DataForRecursion<LayerType>* data_for_children) {
142 const bool is_root = !layer->parent(); 153 const bool is_root = !layer->parent();
143 const bool is_page_scale_application_layer = 154 const bool is_page_scale_application_layer =
144 layer->parent() && layer->parent() == data_from_ancestor.page_scale_layer; 155 layer->parent() && layer->parent() == data_from_ancestor.page_scale_layer;
145 const bool is_scrollable = layer->scrollable(); 156 const bool is_scrollable = layer->scrollable();
146 const bool is_fixed = layer->position_constraint().is_fixed_position(); 157 const bool is_fixed = layer->position_constraint().is_fixed_position();
147 158
148 const bool has_significant_transform = 159 const bool has_significant_transform =
149 !layer->transform().IsIdentityOr2DTranslation(); 160 !layer->transform().IsIdentityOr2DTranslation();
150 161
151 const bool has_animated_transform = 162 const bool has_animated_transform =
152 layer->layer_animation_controller()->IsAnimatingProperty( 163 layer->layer_animation_controller()->IsAnimatingProperty(
153 Animation::TRANSFORM); 164 Animation::TRANSFORM);
154 165
155 const bool has_surface = !!layer->render_surface(); 166 const bool has_surface = !!layer->render_surface();
156 167
157 bool requires_node = is_root || is_scrollable || has_significant_transform || 168 bool requires_node = is_root || is_scrollable || has_significant_transform ||
158 has_animated_transform || has_surface || 169 has_animated_transform || has_surface ||
159 is_page_scale_application_layer; 170 is_page_scale_application_layer;
160 171
161 Layer* transform_parent = GetTransformParent(data_from_ancestor, layer); 172 LayerType* transform_parent = GetTransformParent(data_from_ancestor, layer);
162 173
163 gfx::Vector2dF parent_offset; 174 gfx::Vector2dF parent_offset;
164 if (transform_parent) { 175 if (transform_parent) {
165 if (layer->scroll_parent()) { 176 if (layer->scroll_parent()) {
166 gfx::Transform to_parent; 177 gfx::Transform to_parent;
167 Layer* source = layer->parent(); 178 LayerType* source = layer->parent();
168 parent_offset += source->offset_to_transform_parent(); 179 parent_offset += source->offset_to_transform_parent();
169 data_from_ancestor.transform_tree->ComputeTransform( 180 data_from_ancestor.transform_tree->ComputeTransform(
170 source->transform_tree_index(), 181 source->transform_tree_index(),
171 transform_parent->transform_tree_index(), &to_parent); 182 transform_parent->transform_tree_index(), &to_parent);
172 parent_offset += to_parent.To2dTranslation(); 183 parent_offset += to_parent.To2dTranslation();
173 } else if (!is_fixed) { 184 } else if (!is_fixed) {
174 parent_offset = transform_parent->offset_to_transform_parent(); 185 parent_offset = transform_parent->offset_to_transform_parent();
175 } else { 186 } else {
176 if (data_from_ancestor.transform_tree_parent != 187 if (data_from_ancestor.transform_tree_parent !=
177 data_from_ancestor.transform_fixed_parent) { 188 data_from_ancestor.transform_fixed_parent) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 layer->set_offset_to_transform_parent(gfx::Vector2dF()); 279 layer->set_offset_to_transform_parent(gfx::Vector2dF());
269 280
270 // Flattening (if needed) will be handled by |node|. 281 // Flattening (if needed) will be handled by |node|.
271 layer->set_should_flatten_transform_from_property_tree(false); 282 layer->set_should_flatten_transform_from_property_tree(false);
272 283
273 data_for_children->scroll_compensation_adjustment += 284 data_for_children->scroll_compensation_adjustment +=
274 layer->ScrollCompensationAdjustment() - node->data.scroll_snap; 285 layer->ScrollCompensationAdjustment() - node->data.scroll_snap;
275 return true; 286 return true;
276 } 287 }
277 288
278 void AddOpacityNodeIfNeeded(const DataForRecursion& data_from_ancestor, 289 bool IsAnimatingOpacity(Layer* layer) {
279 Layer* layer, 290 return layer->layer_animation_controller()->IsAnimatingProperty(
280 DataForRecursion* data_for_children) { 291 Animation::OPACITY) ||
292 layer->OpacityCanAnimateOnImplThread();
293 }
294
295 bool IsAnimatingOpacity(LayerImpl* layer) {
296 return layer->layer_animation_controller()->IsAnimatingProperty(
297 Animation::OPACITY);
298 }
299
300 template <typename LayerType>
301 void AddOpacityNodeIfNeeded(
302 const DataForRecursion<LayerType>& data_from_ancestor,
303 LayerType* layer,
304 DataForRecursion<LayerType>* data_for_children) {
281 const bool is_root = !layer->parent(); 305 const bool is_root = !layer->parent();
282 const bool has_transparency = layer->opacity() != 1.f; 306 const bool has_transparency = layer->opacity() != 1.f;
283 const bool has_animated_opacity = 307 const bool has_animated_opacity = IsAnimatingOpacity(layer);
284 layer->layer_animation_controller()->IsAnimatingProperty(
285 Animation::OPACITY) ||
286 layer->OpacityCanAnimateOnImplThread();
287 bool requires_node = is_root || has_transparency || has_animated_opacity; 308 bool requires_node = is_root || has_transparency || has_animated_opacity;
288 309
289 int parent_id = data_from_ancestor.opacity_tree_parent; 310 int parent_id = data_from_ancestor.opacity_tree_parent;
290 311
291 if (!requires_node) { 312 if (!requires_node) {
292 layer->set_opacity_tree_index(parent_id); 313 layer->set_opacity_tree_index(parent_id);
293 data_for_children->opacity_tree_parent = parent_id; 314 data_for_children->opacity_tree_parent = parent_id;
294 return; 315 return;
295 } 316 }
296 317
297 OpacityNode node; 318 OpacityNode node;
298 node.data = layer->opacity(); 319 node.data = layer->opacity();
299 data_for_children->opacity_tree_parent = 320 data_for_children->opacity_tree_parent =
300 data_for_children->opacity_tree->Insert(node, parent_id); 321 data_for_children->opacity_tree->Insert(node, parent_id);
301 layer->set_opacity_tree_index(data_for_children->opacity_tree_parent); 322 layer->set_opacity_tree_index(data_for_children->opacity_tree_parent);
302 } 323 }
303 324
304 void BuildPropertyTreesInternal(Layer* layer, 325 template <typename LayerType>
305 const DataForRecursion& data_from_parent) { 326 void BuildPropertyTreesInternal(
306 DataForRecursion data_for_children(data_from_parent); 327 LayerType* layer,
328 const DataForRecursion<LayerType>& data_from_parent) {
329 DataForRecursion<LayerType> data_for_children(data_from_parent);
307 if (layer->render_surface()) 330 if (layer->render_surface())
308 data_for_children.render_target = layer; 331 data_for_children.render_target = layer;
309 332
310 bool created_transform_node = 333 bool created_transform_node =
311 AddTransformNodeIfNeeded(data_from_parent, layer, &data_for_children); 334 AddTransformNodeIfNeeded(data_from_parent, layer, &data_for_children);
312 AddClipNodeIfNeeded(data_from_parent, layer, created_transform_node, 335 AddClipNodeIfNeeded(data_from_parent, layer, created_transform_node,
313 &data_for_children); 336 &data_for_children);
314 337
315 if (data_from_parent.opacity_tree) 338 if (data_from_parent.opacity_tree)
316 AddOpacityNodeIfNeeded(data_from_parent, layer, &data_for_children); 339 AddOpacityNodeIfNeeded(data_from_parent, layer, &data_for_children);
317 340
318 if (layer == data_from_parent.page_scale_layer) 341 if (layer == data_from_parent.page_scale_layer)
319 data_for_children.in_subtree_of_page_scale_application_layer = true; 342 data_for_children.in_subtree_of_page_scale_application_layer = true;
320 343
321 for (size_t i = 0; i < layer->children().size(); ++i) { 344 for (size_t i = 0; i < layer->children().size(); ++i) {
322 if (!layer->children()[i]->scroll_parent()) 345 if (!layer->child_at(i)->scroll_parent())
323 BuildPropertyTreesInternal(layer->children()[i].get(), data_for_children); 346 BuildPropertyTreesInternal(layer->child_at(i), data_for_children);
324 } 347 }
325 348
326 if (layer->scroll_children()) { 349 if (layer->scroll_children()) {
327 for (Layer* scroll_child : *layer->scroll_children()) { 350 for (LayerType* scroll_child : *layer->scroll_children()) {
328 BuildPropertyTreesInternal(scroll_child, data_for_children); 351 BuildPropertyTreesInternal(scroll_child, data_for_children);
329 } 352 }
330 } 353 }
331 354
332 if (layer->has_replica()) 355 if (layer->has_replica())
333 BuildPropertyTreesInternal(layer->replica_layer(), data_for_children); 356 BuildPropertyTreesInternal(layer->replica_layer(), data_for_children);
334 } 357 }
335 358
336 } // namespace 359 } // namespace
337 360
338 void PropertyTreeBuilder::BuildPropertyTrees( 361 template <typename LayerType>
339 Layer* root_layer, 362 void BuildPropertyTreesTopLevelInternal(LayerType* root_layer,
340 const Layer* page_scale_layer, 363 const LayerType* page_scale_layer,
341 float page_scale_factor, 364 float page_scale_factor,
342 float device_scale_factor, 365 float device_scale_factor,
343 const gfx::Rect& viewport, 366 const gfx::Rect& viewport,
344 const gfx::Transform& device_transform, 367 const gfx::Transform& device_transform,
345 PropertyTrees* property_trees) { 368 PropertyTrees* property_trees) {
346 DataForRecursion data_for_recursion; 369 DataForRecursion<LayerType> data_for_recursion;
347 data_for_recursion.transform_tree = &property_trees->transform_tree; 370 data_for_recursion.transform_tree = &property_trees->transform_tree;
348 data_for_recursion.clip_tree = &property_trees->clip_tree; 371 data_for_recursion.clip_tree = &property_trees->clip_tree;
349 data_for_recursion.opacity_tree = &property_trees->opacity_tree; 372 data_for_recursion.opacity_tree = &property_trees->opacity_tree;
350 data_for_recursion.transform_tree_parent = nullptr; 373 data_for_recursion.transform_tree_parent = nullptr;
351 data_for_recursion.transform_fixed_parent = nullptr; 374 data_for_recursion.transform_fixed_parent = nullptr;
352 data_for_recursion.render_target = root_layer; 375 data_for_recursion.render_target = root_layer;
353 data_for_recursion.clip_tree_parent = 0; 376 data_for_recursion.clip_tree_parent = 0;
354 data_for_recursion.opacity_tree_parent = -1; 377 data_for_recursion.opacity_tree_parent = -1;
355 data_for_recursion.page_scale_layer = page_scale_layer; 378 data_for_recursion.page_scale_layer = page_scale_layer;
356 data_for_recursion.page_scale_factor = page_scale_factor; 379 data_for_recursion.page_scale_factor = page_scale_factor;
357 data_for_recursion.device_scale_factor = device_scale_factor; 380 data_for_recursion.device_scale_factor = device_scale_factor;
358 data_for_recursion.in_subtree_of_page_scale_application_layer = false; 381 data_for_recursion.in_subtree_of_page_scale_application_layer = false;
359 data_for_recursion.should_flatten = false; 382 data_for_recursion.should_flatten = false;
360 data_for_recursion.ancestor_clips_subtree = true; 383 data_for_recursion.ancestor_clips_subtree = true;
361 data_for_recursion.device_transform = &device_transform; 384 data_for_recursion.device_transform = &device_transform;
362 385
363 ClipNode root_clip; 386 ClipNode root_clip;
364 root_clip.data.clip = viewport; 387 root_clip.data.clip = viewport;
365 root_clip.data.transform_id = 0; 388 root_clip.data.transform_id = 0;
366 data_for_recursion.clip_tree_parent = 389 data_for_recursion.clip_tree_parent =
367 data_for_recursion.clip_tree->Insert(root_clip, 0); 390 data_for_recursion.clip_tree->Insert(root_clip, 0);
368 BuildPropertyTreesInternal(root_layer, data_for_recursion); 391 BuildPropertyTreesInternal(root_layer, data_for_recursion);
369 } 392 }
370 393
394 void PropertyTreeBuilder::BuildPropertyTrees(
395 Layer* root_layer,
396 const Layer* page_scale_layer,
397 float page_scale_factor,
398 float device_scale_factor,
399 const gfx::Rect& viewport,
400 const gfx::Transform& device_transform,
401 PropertyTrees* property_trees) {
402 BuildPropertyTreesTopLevelInternal(
403 root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
404 viewport, device_transform, property_trees);
405 }
406
407 void PropertyTreeBuilder::BuildPropertyTrees(
408 LayerImpl* root_layer,
409 const LayerImpl* page_scale_layer,
410 float page_scale_factor,
411 float device_scale_factor,
412 const gfx::Rect& viewport,
413 const gfx::Transform& device_transform,
414 PropertyTrees* property_trees) {
415 BuildPropertyTreesTopLevelInternal(
416 root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
417 viewport, device_transform, property_trees);
418 }
419
371 } // namespace cc 420 } // namespace cc
OLDNEW
« cc/layers/layer.h ('K') | « cc/trees/property_tree_builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698