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

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

Issue 2127323002: cc: Use sublayer scale from effect tree (1) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: PAC Created 4 years, 5 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
« no previous file with comments | « cc/proto/property_tree.proto ('k') | cc/trees/layer_tree_impl.cc » ('j') | 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/draw_property_utils.h" 5 #include "cc/trees/draw_property_utils.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 layer->effect_tree_index()); 46 layer->effect_tree_index());
47 if (effect_node->owner_id != layer->id()) 47 if (effect_node->owner_id != layer->id())
48 return; 48 return;
49 DCHECK_EQ(effect_node->data.mask_layer_id, -1) << "layer: " << layer->id(); 49 DCHECK_EQ(effect_node->data.mask_layer_id, -1) << "layer: " << layer->id();
50 DCHECK_EQ(effect_node->data.replica_layer_id, -1) << "layer: " << layer->id(); 50 DCHECK_EQ(effect_node->data.replica_layer_id, -1) << "layer: " << layer->id();
51 DCHECK(effect_node->data.background_filters.IsEmpty()); 51 DCHECK(effect_node->data.background_filters.IsEmpty());
52 } 52 }
53 53
54 #endif 54 #endif
55 55
56 static void AddSublayerScaleToTransform(const int effect_node_id, 56 static void AddSublayerScaleToTransform(const int effect_node_id,
weiliangc 2016/07/08 19:19:03 nit: ApplySublayerScale?
jaydasika 2016/07/08 19:44:25 Done.
57 const EffectTree& effect_tree, 57 const EffectTree& effect_tree,
58 gfx::Transform* transform) { 58 gfx::Transform* transform) {
59 const EffectNode* effect_node = effect_tree.Node(effect_node_id); 59 const EffectNode* effect_node = effect_tree.Node(effect_node_id);
60 const EffectNode* target_effect_node = 60 const EffectNode* target_effect_node =
61 effect_node->data.has_render_surface 61 effect_node->data.has_render_surface
weiliangc 2016/07/08 19:19:03 I think when we call this function, the effect_nod
jaydasika 2016/07/08 19:30:47 We may call this function when effect_node may not
62 ? effect_node 62 ? effect_node
63 : effect_tree.Node(effect_node->data.target_id); 63 : effect_tree.Node(effect_node->data.target_id);
64 transform->matrix().postScale(target_effect_node->data.sublayer_scale.x(), 64 transform->matrix().postScale(target_effect_node->data.sublayer_scale.x(),
65 target_effect_node->data.sublayer_scale.y(), 65 target_effect_node->data.sublayer_scale.y(),
66 1.f); 66 1.f);
67 } 67 }
68 68
69 #if DCHECK_IS_ON() 69 #if DCHECK_IS_ON()
70 void VerifySublayerScalesMatch(const int effect_node_id, 70 void VerifySublayerScalesMatch(const int effect_node_id,
71 const int target_transform_id, 71 const int target_transform_id,
(...skipping 16 matching lines...) Expand all
88 #endif 88 #endif
89 89
90 template <typename LayerType> 90 template <typename LayerType>
91 bool ComputeClipRectInTargetSpace(const LayerType* layer, 91 bool ComputeClipRectInTargetSpace(const LayerType* layer,
92 const ClipNode* clip_node, 92 const ClipNode* clip_node,
93 const TransformTree& transform_tree, 93 const TransformTree& transform_tree,
94 const EffectTree& effect_tree, 94 const EffectTree& effect_tree,
95 int target_node_id, 95 int target_node_id,
96 gfx::RectF* clip_rect_in_target_space) { 96 gfx::RectF* clip_rect_in_target_space) {
97 DCHECK(layer->clip_tree_index() == clip_node->id); 97 DCHECK(layer->clip_tree_index() == clip_node->id);
98 DCHECK(clip_node->data.target_id != target_node_id); 98 DCHECK(clip_node->data.target_transform_id != target_node_id);
99 99
100 gfx::Transform clip_to_target; 100 gfx::Transform clip_to_target;
101 if (clip_node->data.target_id > target_node_id) { 101 if (clip_node->data.target_transform_id > target_node_id) {
102 // In this case, layer has a scroll parent. We need to keep the scale 102 // In this case, layer has a scroll parent. We need to keep the scale
103 // at the layer's target but remove the scale at the scroll parent's 103 // at the layer's target but remove the scale at the scroll parent's
104 // target. 104 // target.
105 if (transform_tree.ComputeTransform(clip_node->data.target_id, 105 if (transform_tree.ComputeTransform(clip_node->data.target_transform_id,
106 target_node_id, &clip_to_target)) { 106 target_node_id, &clip_to_target)) {
107 // We don't have to apply sublayer scale when target is root. 107 // We don't have to apply sublayer scale when target is root.
108 if (target_node_id != 0) { 108 if (target_node_id != 0) {
109 AddSublayerScaleToTransform(layer->effect_tree_index(), effect_tree, 109 AddSublayerScaleToTransform(layer->effect_tree_index(), effect_tree,
110 &clip_to_target); 110 &clip_to_target);
111 #if DCHECK_IS_ON() 111 #if DCHECK_IS_ON()
112 VerifySublayerScalesMatch(layer->effect_tree_index(), target_node_id, 112 VerifySublayerScalesMatch(layer->effect_tree_index(), target_node_id,
113 effect_tree, transform_tree); 113 effect_tree, transform_tree);
114 #endif 114 #endif
115 } 115 }
116 116
117 const TransformNode* source_node = 117 const TransformNode* source_node =
118 transform_tree.Node(clip_node->data.target_id); 118 transform_tree.Node(clip_node->data.target_transform_id);
119 if (source_node->data.sublayer_scale.x() != 0.f && 119 if (source_node->data.sublayer_scale.x() != 0.f &&
120 source_node->data.sublayer_scale.y() != 0.f) 120 source_node->data.sublayer_scale.y() != 0.f)
121 clip_to_target.Scale(1.0f / source_node->data.sublayer_scale.x(), 121 clip_to_target.Scale(1.0f / source_node->data.sublayer_scale.x(),
122 1.0f / source_node->data.sublayer_scale.y()); 122 1.0f / source_node->data.sublayer_scale.y());
123 *clip_rect_in_target_space = MathUtil::MapClippedRect( 123 *clip_rect_in_target_space = MathUtil::MapClippedRect(
124 clip_to_target, clip_node->data.clip_in_target_space); 124 clip_to_target, clip_node->data.clip_in_target_space);
125 } else { 125 } else {
126 return false; 126 return false;
127 } 127 }
128 } else { 128 } else {
129 if (transform_tree.ComputeTransform(clip_node->data.target_id, 129 if (transform_tree.ComputeTransform(clip_node->data.target_transform_id,
130 target_node_id, &clip_to_target)) { 130 target_node_id, &clip_to_target)) {
131 *clip_rect_in_target_space = MathUtil::ProjectClippedRect( 131 *clip_rect_in_target_space = MathUtil::ProjectClippedRect(
132 clip_to_target, clip_node->data.clip_in_target_space); 132 clip_to_target, clip_node->data.clip_in_target_space);
133 } else { 133 } else {
134 return false; 134 return false;
135 } 135 }
136 } 136 }
137 return true; 137 return true;
138 } 138 }
139 139
(...skipping 17 matching lines...) Expand all
157 return ConditionalClip{true, // is_clipped. 157 return ConditionalClip{true, // is_clipped.
158 MathUtil::MapClippedRect(current_to_target, rect)}; 158 MathUtil::MapClippedRect(current_to_target, rect)};
159 159
160 return ConditionalClip{true, // is_clipped. 160 return ConditionalClip{true, // is_clipped.
161 MathUtil::ProjectClippedRect(current_to_target, rect)}; 161 MathUtil::ProjectClippedRect(current_to_target, rect)};
162 } 162 }
163 163
164 static ConditionalClip ComputeLocalRectInTargetSpace( 164 static ConditionalClip ComputeLocalRectInTargetSpace(
165 gfx::RectF rect, 165 gfx::RectF rect,
166 const TransformTree& transform_tree, 166 const TransformTree& transform_tree,
167 const EffectTree& effect_tree,
167 int current_transform_id, 168 int current_transform_id,
168 int target_transform_id) { 169 int target_transform_id,
170 int target_effect_id) {
169 gfx::Transform current_to_target; 171 gfx::Transform current_to_target;
170 if (!transform_tree.ComputeTransformWithDestinationSublayerScale( 172 if (!transform_tree.ComputeTransform(current_transform_id,
171 current_transform_id, target_transform_id, &current_to_target)) 173 target_transform_id, &current_to_target))
172 // If transform is not invertible, cannot apply clip. 174 // If transform is not invertible, cannot apply clip.
173 return ConditionalClip{false, gfx::RectF()}; 175 return ConditionalClip{false, gfx::RectF()};
176 // We don't have to apply sublayer scale when target is root.
177 if (target_transform_id != 0) {
178 AddSublayerScaleToTransform(target_effect_id, effect_tree,
179 &current_to_target);
180 #if DCHECK_IS_ON()
181 VerifySublayerScalesMatch(target_effect_id, target_transform_id,
182 effect_tree, transform_tree);
183 #endif
184 }
174 185
175 if (current_transform_id > target_transform_id) 186 if (current_transform_id > target_transform_id)
176 return ConditionalClip{true, // is_clipped. 187 return ConditionalClip{true, // is_clipped.
177 MathUtil::MapClippedRect(current_to_target, rect)}; 188 MathUtil::MapClippedRect(current_to_target, rect)};
178 189
179 return ConditionalClip{true, // is_clipped. 190 return ConditionalClip{true, // is_clipped.
180 MathUtil::ProjectClippedRect(current_to_target, rect)}; 191 MathUtil::ProjectClippedRect(current_to_target, rect)};
181 } 192 }
182 193
183 static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, 194 static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node,
184 const TransformTree& transform_tree, 195 const TransformTree& transform_tree,
185 int target_transform_id) { 196 const EffectTree& effect_tree,
197 int target_transform_id,
198 int target_effect_id) {
186 if (clip_node->data.transform_id != target_transform_id) 199 if (clip_node->data.transform_id != target_transform_id)
187 return ComputeLocalRectInTargetSpace(clip_node->data.clip, transform_tree, 200 return ComputeLocalRectInTargetSpace(
188 clip_node->data.transform_id, 201 clip_node->data.clip, transform_tree, effect_tree,
189 target_transform_id); 202 clip_node->data.transform_id, target_transform_id, target_effect_id);
190 203
191 gfx::RectF current_clip = clip_node->data.clip; 204 gfx::RectF current_clip = clip_node->data.clip;
192 gfx::Vector2dF sublayer_scale = 205 gfx::Vector2dF sublayer_scale =
193 transform_tree.Node(target_transform_id)->data.sublayer_scale; 206 transform_tree.Node(target_transform_id)->data.sublayer_scale;
194 if (sublayer_scale.x() > 0 && sublayer_scale.y() > 0) 207 if (sublayer_scale.x() > 0 && sublayer_scale.y() > 0)
195 current_clip.Scale(sublayer_scale.x(), sublayer_scale.y()); 208 current_clip.Scale(sublayer_scale.x(), sublayer_scale.y());
196 return ConditionalClip{true /* is_clipped */, current_clip}; 209 return ConditionalClip{true /* is_clipped */, current_clip};
197 } 210 }
198 211
199 static ConditionalClip ComputeAccumulatedClip( 212 static ConditionalClip ComputeAccumulatedClip(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 // to check applies_local_clip. 250 // to check applies_local_clip.
238 while (!clip_node->data.applies_local_clip && parent_chain.size() > 0) { 251 while (!clip_node->data.applies_local_clip && parent_chain.size() > 0) {
239 clip_node = parent_chain.top(); 252 clip_node = parent_chain.top();
240 parent_chain.pop(); 253 parent_chain.pop();
241 } 254 }
242 255
243 if (!clip_node->data.applies_local_clip) 256 if (!clip_node->data.applies_local_clip)
244 // No clip node applying clip in between. 257 // No clip node applying clip in between.
245 return ConditionalClip{false, gfx::RectF()}; 258 return ConditionalClip{false, gfx::RectF()};
246 259
247 ConditionalClip current_clip = 260 ConditionalClip current_clip = ComputeCurrentClip(
248 ComputeCurrentClip(clip_node, transform_tree, target_transform_id); 261 clip_node, transform_tree, effect_tree, target_transform_id, target_id);
249 is_clipped = current_clip.is_clipped; 262 is_clipped = current_clip.is_clipped;
250 gfx::RectF accumulated_clip = current_clip.clip_rect; 263 gfx::RectF accumulated_clip = current_clip.clip_rect;
251 264
252 while (parent_chain.size() > 0) { 265 while (parent_chain.size() > 0) {
253 clip_node = parent_chain.top(); 266 clip_node = parent_chain.top();
254 parent_chain.pop(); 267 parent_chain.pop();
255 if (!clip_node->data.applies_local_clip) { 268 if (!clip_node->data.applies_local_clip) {
256 continue; 269 continue;
257 } 270 }
258 ConditionalClip current_clip = 271 ConditionalClip current_clip = ComputeCurrentClip(
259 ComputeCurrentClip(clip_node, transform_tree, target_transform_id); 272 clip_node, transform_tree, effect_tree, target_transform_id, target_id);
260 273
261 // If transform is not invertible, no clip will be applied. 274 // If transform is not invertible, no clip will be applied.
262 if (!current_clip.is_clipped) 275 if (!current_clip.is_clipped)
263 return ConditionalClip{false, gfx::RectF()}; 276 return ConditionalClip{false, gfx::RectF()};
264 277
265 is_clipped = true; 278 is_clipped = true;
266 accumulated_clip = 279 accumulated_clip =
267 gfx::IntersectRects(accumulated_clip, current_clip.clip_rect); 280 gfx::IntersectRects(accumulated_clip, current_clip.clip_rect);
268 } 281 }
269 282
(...skipping 25 matching lines...) Expand all
295 const TransformNode* transform_node = 308 const TransformNode* transform_node =
296 transform_tree.Node(layer->transform_tree_index()); 309 transform_tree.Node(layer->transform_tree_index());
297 int target_node_id = transform_tree.ContentTargetId(transform_node->id); 310 int target_node_id = transform_tree.ContentTargetId(transform_node->id);
298 311
299 // The clip node stores clip rect in its target space. 312 // The clip node stores clip rect in its target space.
300 gfx::RectF clip_rect_in_target_space = 313 gfx::RectF clip_rect_in_target_space =
301 clip_node->data.clip_in_target_space; 314 clip_node->data.clip_in_target_space;
302 315
303 // If required, this clip rect should be mapped to the current layer's 316 // If required, this clip rect should be mapped to the current layer's
304 // target space. 317 // target space.
305 if (clip_node->data.target_id != target_node_id) { 318 if (clip_node->data.target_transform_id != target_node_id) {
306 // In this case, layer has a clip parent or scroll parent (or shares the 319 // In this case, layer has a clip parent or scroll parent (or shares the
307 // target with an ancestor layer that has clip parent) and the clip 320 // target with an ancestor layer that has clip parent) and the clip
308 // parent's target is different from the layer's target. As the layer's 321 // parent's target is different from the layer's target. As the layer's
309 // target has unclippped descendants, it is unclippped. 322 // target has unclippped descendants, it is unclippped.
310 if (!clip_node->data.layers_are_clipped) 323 if (!clip_node->data.layers_are_clipped)
311 continue; 324 continue;
312 325
313 // Compute the clip rect in target space and store it. 326 // Compute the clip rect in target space and store it.
314 if (!ComputeClipRectInTargetSpace(layer, clip_node, transform_tree, 327 if (!ComputeClipRectInTargetSpace(layer, clip_node, transform_tree,
315 effect_tree, target_node_id, 328 effect_tree, target_node_id,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); 440 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
428 continue; 441 continue;
429 } 442 }
430 443
431 int target_node_id = transform_tree.ContentTargetId(transform_node->id); 444 int target_node_id = transform_tree.ContentTargetId(transform_node->id);
432 445
433 // The clip node stores clip rect in its target space. If required, 446 // The clip node stores clip rect in its target space. If required,
434 // this clip rect should be mapped to the current layer's target space. 447 // this clip rect should be mapped to the current layer's target space.
435 gfx::RectF combined_clip_rect_in_target_space; 448 gfx::RectF combined_clip_rect_in_target_space;
436 449
437 if (clip_node->data.target_id != target_node_id) { 450 if (clip_node->data.target_transform_id != target_node_id) {
438 // In this case, layer has a clip parent or scroll parent (or shares the 451 // In this case, layer has a clip parent or scroll parent (or shares the
439 // target with an ancestor layer that has clip parent) and the clip 452 // target with an ancestor layer that has clip parent) and the clip
440 // parent's target is different from the layer's target. As the layer's 453 // parent's target is different from the layer's target. As the layer's
441 // target has unclippped descendants, it is unclippped. 454 // target has unclippped descendants, it is unclippped.
442 if (!clip_node->data.layers_are_clipped) { 455 if (!clip_node->data.layers_are_clipped) {
443 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); 456 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
444 continue; 457 continue;
445 } 458 }
446 459
447 // We use the clip node's clip_in_target_space (and not 460 // We use the clip node's clip_in_target_space (and not
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 } 712 }
700 713
701 static void ResetIfHasNanCoordinate(gfx::RectF* rect) { 714 static void ResetIfHasNanCoordinate(gfx::RectF* rect) {
702 if (std::isnan(rect->x()) || std::isnan(rect->y()) || 715 if (std::isnan(rect->x()) || std::isnan(rect->y()) ||
703 std::isnan(rect->right()) || std::isnan(rect->bottom())) 716 std::isnan(rect->right()) || std::isnan(rect->bottom()))
704 *rect = gfx::RectF(); 717 *rect = gfx::RectF();
705 } 718 }
706 719
707 void ComputeClips(ClipTree* clip_tree, 720 void ComputeClips(ClipTree* clip_tree,
708 const TransformTree& transform_tree, 721 const TransformTree& transform_tree,
722 const EffectTree& effect_tree,
709 bool non_root_surfaces_enabled) { 723 bool non_root_surfaces_enabled) {
710 if (!clip_tree->needs_update()) 724 if (!clip_tree->needs_update())
711 return; 725 return;
712 for (int i = 1; i < static_cast<int>(clip_tree->size()); ++i) { 726 for (int i = 1; i < static_cast<int>(clip_tree->size()); ++i) {
713 ClipNode* clip_node = clip_tree->Node(i); 727 ClipNode* clip_node = clip_tree->Node(i);
714 728
715 if (clip_node->id == 1) { 729 if (clip_node->id == 1) {
716 ResetIfHasNanCoordinate(&clip_node->data.clip); 730 ResetIfHasNanCoordinate(&clip_node->data.clip);
717 clip_node->data.clip_in_target_space = clip_node->data.clip; 731 clip_node->data.clip_in_target_space = clip_node->data.clip;
718 clip_node->data.combined_clip_in_target_space = clip_node->data.clip; 732 clip_node->data.combined_clip_in_target_space = clip_node->data.clip;
719 continue; 733 continue;
720 } 734 }
721 const TransformNode* transform_node = 735 const TransformNode* transform_node =
722 transform_tree.Node(clip_node->data.transform_id); 736 transform_tree.Node(clip_node->data.transform_id);
723 ClipNode* parent_clip_node = clip_tree->parent(clip_node); 737 ClipNode* parent_clip_node = clip_tree->parent(clip_node);
724 738
725 gfx::Transform parent_to_current; 739 gfx::Transform parent_to_current;
726 const TransformNode* parent_target_transform_node = 740 const TransformNode* parent_target_transform_node =
727 transform_tree.Node(parent_clip_node->data.target_id); 741 transform_tree.Node(parent_clip_node->data.target_transform_id);
728 bool success = true; 742 bool success = true;
729 743
730 // Clips must be combined in target space. We cannot, for example, combine 744 // Clips must be combined in target space. We cannot, for example, combine
731 // clips in the space of the child clip. The reason is non-affine 745 // clips in the space of the child clip. The reason is non-affine
732 // transforms. Say we have the following tree T->A->B->C, and B clips C, but 746 // transforms. Say we have the following tree T->A->B->C, and B clips C, but
733 // draw into target T. It may be the case that A applies a perspective 747 // draw into target T. It may be the case that A applies a perspective
734 // transform, and B and C are at different z positions. When projected into 748 // transform, and B and C are at different z positions. When projected into
735 // target space, the relative sizes and positions of B and C can shift. 749 // target space, the relative sizes and positions of B and C can shift.
736 // Since it's the relationship in target space that matters, that's where we 750 // Since it's the relationship in target space that matters, that's where we
737 // must combine clips. For each clip node, we save the clip rects in its 751 // must combine clips. For each clip node, we save the clip rects in its
738 // target space. So, we need to get the ancestor clip rect in the current 752 // target space. So, we need to get the ancestor clip rect in the current
739 // clip node's target space. 753 // clip node's target space.
740 gfx::RectF parent_combined_clip_in_target_space = 754 gfx::RectF parent_combined_clip_in_target_space =
741 parent_clip_node->data.combined_clip_in_target_space; 755 parent_clip_node->data.combined_clip_in_target_space;
742 gfx::RectF parent_clip_in_target_space = 756 gfx::RectF parent_clip_in_target_space =
743 parent_clip_node->data.clip_in_target_space; 757 parent_clip_node->data.clip_in_target_space;
744 if (parent_target_transform_node && 758 if (parent_target_transform_node &&
745 parent_target_transform_node->id != clip_node->data.target_id && 759 parent_target_transform_node->id !=
760 clip_node->data.target_transform_id &&
746 non_root_surfaces_enabled) { 761 non_root_surfaces_enabled) {
747 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( 762 success &= transform_tree.ComputeTransform(
748 parent_target_transform_node->id, clip_node->data.target_id, 763 parent_target_transform_node->id, clip_node->data.target_transform_id,
749 &parent_to_current); 764 &parent_to_current);
765 // We don't have to apply sublayer scale when target is root.
766 if (clip_node->data.target_transform_id != 0) {
767 AddSublayerScaleToTransform(clip_node->data.target_effect_id,
768 effect_tree, &parent_to_current);
769 #if DCHECK_IS_ON()
770 VerifySublayerScalesMatch(clip_node->data.target_effect_id,
771 clip_node->data.target_transform_id,
772 effect_tree, transform_tree);
773 #endif
774 }
750 if (parent_target_transform_node->data.sublayer_scale.x() > 0 && 775 if (parent_target_transform_node->data.sublayer_scale.x() > 0 &&
751 parent_target_transform_node->data.sublayer_scale.y() > 0) 776 parent_target_transform_node->data.sublayer_scale.y() > 0)
752 parent_to_current.Scale( 777 parent_to_current.Scale(
753 1.f / parent_target_transform_node->data.sublayer_scale.x(), 778 1.f / parent_target_transform_node->data.sublayer_scale.x(),
754 1.f / parent_target_transform_node->data.sublayer_scale.y()); 779 1.f / parent_target_transform_node->data.sublayer_scale.y());
755 // If we can't compute a transform, it's because we had to use the inverse 780 // If we can't compute a transform, it's because we had to use the inverse
756 // of a singular transform. We won't draw in this case, so there's no need 781 // of a singular transform. We won't draw in this case, so there's no need
757 // to compute clips. 782 // to compute clips.
758 if (!success) 783 if (!success)
759 continue; 784 continue;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 // it to an empty rect. 826 // it to an empty rect.
802 clip_node->data.clip_in_target_space = gfx::RectF(); 827 clip_node->data.clip_in_target_space = gfx::RectF();
803 } 828 }
804 } else { 829 } else {
805 gfx::Transform source_to_target; 830 gfx::Transform source_to_target;
806 831
807 if (!non_root_surfaces_enabled) { 832 if (!non_root_surfaces_enabled) {
808 source_to_target = 833 source_to_target =
809 transform_tree.ToScreen(clip_node->data.transform_id); 834 transform_tree.ToScreen(clip_node->data.transform_id);
810 } else if (transform_tree.ContentTargetId(transform_node->id) == 835 } else if (transform_tree.ContentTargetId(transform_node->id) ==
811 clip_node->data.target_id) { 836 clip_node->data.target_transform_id) {
812 source_to_target = 837 source_to_target =
813 transform_tree.ToTarget(clip_node->data.transform_id); 838 transform_tree.ToTarget(clip_node->data.transform_id);
814 } else { 839 } else {
815 success = transform_tree.ComputeTransformWithDestinationSublayerScale( 840 success = transform_tree.ComputeTransform(
816 transform_node->id, clip_node->data.target_id, &source_to_target); 841 transform_node->id, clip_node->data.target_transform_id,
842 &source_to_target);
843 // We don't have to apply sublayer scale when target is root.
844 if (clip_node->data.target_transform_id != 0) {
845 AddSublayerScaleToTransform(clip_node->data.target_effect_id,
846 effect_tree, &source_to_target);
847 #if DCHECK_IS_ON()
848 VerifySublayerScalesMatch(clip_node->data.target_effect_id,
849 clip_node->data.target_transform_id,
850 effect_tree, transform_tree);
851 #endif
852 }
817 // source_to_target computation should be successful as target is an 853 // source_to_target computation should be successful as target is an
818 // ancestor of the transform node. 854 // ancestor of the transform node.
819 DCHECK(success); 855 DCHECK(success);
820 } 856 }
821 857
822 gfx::RectF source_clip_in_target_space = 858 gfx::RectF source_clip_in_target_space =
823 MathUtil::MapClippedRect(source_to_target, clip_node->data.clip); 859 MathUtil::MapClippedRect(source_to_target, clip_node->data.clip);
824 860
825 // With surfaces disabled, the only case where we use only the local clip 861 // With surfaces disabled, the only case where we use only the local clip
826 // for layer clipping is the case where no non-viewport ancestor node 862 // for layer clipping is the case where no non-viewport ancestor node
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; 1037 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface;
1002 property_trees->transform_tree.set_needs_update(true); 1038 property_trees->transform_tree.set_needs_update(true);
1003 } 1039 }
1004 if (property_trees->transform_tree.needs_update()) { 1040 if (property_trees->transform_tree.needs_update()) {
1005 property_trees->clip_tree.set_needs_update(true); 1041 property_trees->clip_tree.set_needs_update(true);
1006 property_trees->effect_tree.set_needs_update(true); 1042 property_trees->effect_tree.set_needs_update(true);
1007 } 1043 }
1008 UpdateRenderTarget(&property_trees->effect_tree, 1044 UpdateRenderTarget(&property_trees->effect_tree,
1009 property_trees->non_root_surfaces_enabled); 1045 property_trees->non_root_surfaces_enabled);
1010 ComputeTransforms(&property_trees->transform_tree); 1046 ComputeTransforms(&property_trees->transform_tree);
1047 // Computation of clips uses sublayer scale which is updated while computing
1048 // effects. So, ComputeEffects should be before ComputeClips.
1049 ComputeEffects(&property_trees->effect_tree);
1011 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, 1050 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree,
1012 can_render_to_separate_surface); 1051 property_trees->effect_tree, can_render_to_separate_surface);
1013 ComputeEffects(&property_trees->effect_tree);
1014 1052
1015 FindLayersThatNeedUpdates(root_layer->layer_tree_impl(), 1053 FindLayersThatNeedUpdates(root_layer->layer_tree_impl(),
1016 property_trees->transform_tree, 1054 property_trees->transform_tree,
1017 property_trees->effect_tree, visible_layer_list); 1055 property_trees->effect_tree, visible_layer_list);
1018 CalculateClipRects<LayerImpl>(*visible_layer_list, property_trees->clip_tree, 1056 CalculateClipRects<LayerImpl>(*visible_layer_list, property_trees->clip_tree,
1019 property_trees->transform_tree, 1057 property_trees->transform_tree,
1020 property_trees->effect_tree, 1058 property_trees->effect_tree,
1021 can_render_to_separate_surface); 1059 can_render_to_separate_surface);
1022 CalculateVisibleRects<LayerImpl>( 1060 CalculateVisibleRects<LayerImpl>(
1023 *visible_layer_list, property_trees->clip_tree, 1061 *visible_layer_list, property_trees->clip_tree,
1024 property_trees->transform_tree, property_trees->effect_tree, 1062 property_trees->transform_tree, property_trees->effect_tree,
1025 can_render_to_separate_surface); 1063 can_render_to_separate_surface);
1026 } 1064 }
1027 1065
1028 void UpdatePropertyTrees(PropertyTrees* property_trees, 1066 void UpdatePropertyTrees(PropertyTrees* property_trees,
1029 bool can_render_to_separate_surface) { 1067 bool can_render_to_separate_surface) {
1030 if (property_trees->non_root_surfaces_enabled != 1068 if (property_trees->non_root_surfaces_enabled !=
1031 can_render_to_separate_surface) { 1069 can_render_to_separate_surface) {
1032 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; 1070 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface;
1033 property_trees->transform_tree.set_needs_update(true); 1071 property_trees->transform_tree.set_needs_update(true);
1034 } 1072 }
1035 if (property_trees->transform_tree.needs_update()) { 1073 if (property_trees->transform_tree.needs_update()) {
1036 property_trees->clip_tree.set_needs_update(true); 1074 property_trees->clip_tree.set_needs_update(true);
1037 property_trees->effect_tree.set_needs_update(true); 1075 property_trees->effect_tree.set_needs_update(true);
1038 } 1076 }
1039 ComputeTransforms(&property_trees->transform_tree); 1077 ComputeTransforms(&property_trees->transform_tree);
1078 // Computation of clips uses sublayer scale which is updated while computing
1079 // effects. So, ComputeEffects should be before ComputeClips.
1080 ComputeEffects(&property_trees->effect_tree);
1040 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, 1081 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree,
1041 can_render_to_separate_surface); 1082 property_trees->effect_tree, can_render_to_separate_surface);
1042 ComputeEffects(&property_trees->effect_tree);
1043 } 1083 }
1044 1084
1045 void ComputeVisibleRectsForTesting(PropertyTrees* property_trees, 1085 void ComputeVisibleRectsForTesting(PropertyTrees* property_trees,
1046 bool can_render_to_separate_surface, 1086 bool can_render_to_separate_surface,
1047 LayerList* update_layer_list) { 1087 LayerList* update_layer_list) {
1048 CalculateVisibleRects<Layer>(*update_layer_list, property_trees->clip_tree, 1088 CalculateVisibleRects<Layer>(*update_layer_list, property_trees->clip_tree,
1049 property_trees->transform_tree, 1089 property_trees->transform_tree,
1050 property_trees->effect_tree, 1090 property_trees->effect_tree,
1051 can_render_to_separate_surface); 1091 can_render_to_separate_surface);
1052 } 1092 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 static void SetSurfaceIsClipped(const ClipNode* clip_node, 1224 static void SetSurfaceIsClipped(const ClipNode* clip_node,
1185 RenderSurfaceImpl* render_surface) { 1225 RenderSurfaceImpl* render_surface) {
1186 DCHECK(render_surface->OwningLayerId() == clip_node->owner_id) 1226 DCHECK(render_surface->OwningLayerId() == clip_node->owner_id)
1187 << "we now create clip node for every render surface"; 1227 << "we now create clip node for every render surface";
1188 1228
1189 render_surface->SetIsClipped(clip_node->data.target_is_clipped); 1229 render_surface->SetIsClipped(clip_node->data.target_is_clipped);
1190 } 1230 }
1191 1231
1192 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, 1232 static void SetSurfaceClipRect(const ClipNode* parent_clip_node,
1193 const TransformTree& transform_tree, 1233 const TransformTree& transform_tree,
1234 const EffectTree& effect_tree,
1194 RenderSurfaceImpl* render_surface) { 1235 RenderSurfaceImpl* render_surface) {
1195 if (!render_surface->is_clipped()) { 1236 if (!render_surface->is_clipped()) {
1196 render_surface->SetClipRect(gfx::Rect()); 1237 render_surface->SetClipRect(gfx::Rect());
1197 return; 1238 return;
1198 } 1239 }
1199 1240
1200 const TransformNode* transform_node = 1241 const TransformNode* transform_node =
1201 transform_tree.Node(render_surface->TransformTreeIndex()); 1242 transform_tree.Node(render_surface->TransformTreeIndex());
1202 if (transform_tree.TargetId(transform_node->id) == 1243 if (transform_tree.TargetId(transform_node->id) ==
1203 parent_clip_node->data.target_id) { 1244 parent_clip_node->data.target_transform_id) {
1204 render_surface->SetClipRect( 1245 render_surface->SetClipRect(
1205 gfx::ToEnclosingRect(parent_clip_node->data.clip_in_target_space)); 1246 gfx::ToEnclosingRect(parent_clip_node->data.clip_in_target_space));
1206 return; 1247 return;
1207 } 1248 }
1208 1249
1209 // In this case, the clip child has reset the clip node for subtree and hence 1250 // In this case, the clip child has reset the clip node for subtree and hence
1210 // the parent clip node's clip rect is in clip parent's target space and not 1251 // the parent clip node's clip rect is in clip parent's target space and not
1211 // our target space. We need to transform it to our target space. 1252 // our target space. We need to transform it to our target space.
1212 gfx::Transform clip_parent_target_to_target; 1253 gfx::Transform clip_parent_target_to_target;
1213 const bool success = 1254 const bool success = transform_tree.ComputeTransform(
1214 transform_tree.ComputeTransformWithDestinationSublayerScale( 1255 parent_clip_node->data.target_transform_id,
1215 parent_clip_node->data.target_id, 1256 transform_tree.TargetId(transform_node->id),
1216 transform_tree.TargetId(transform_node->id), 1257 &clip_parent_target_to_target);
1217 &clip_parent_target_to_target);
1218 1258
1219 if (!success) { 1259 if (!success) {
1220 render_surface->SetClipRect(gfx::Rect()); 1260 render_surface->SetClipRect(gfx::Rect());
1221 return; 1261 return;
1222 } 1262 }
1223 1263
1224 DCHECK_LT(parent_clip_node->data.target_id, 1264 // We don't have to apply sublayer scale when target is root.
1265 if (transform_tree.TargetId(transform_node->id) != 0) {
1266 AddSublayerScaleToTransform(render_surface->EffectTreeIndex(), effect_tree,
1267 &clip_parent_target_to_target);
1268 #if DCHECK_IS_ON()
1269 VerifySublayerScalesMatch(render_surface->EffectTreeIndex(),
1270 transform_tree.TargetId(transform_node->id),
1271 effect_tree, transform_tree);
1272 #endif
1273 }
1274
1275 DCHECK_LT(parent_clip_node->data.target_transform_id,
1225 transform_tree.TargetId(transform_node->id)); 1276 transform_tree.TargetId(transform_node->id));
1226 render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( 1277 render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
1227 clip_parent_target_to_target, 1278 clip_parent_target_to_target,
1228 parent_clip_node->data.clip_in_target_space))); 1279 parent_clip_node->data.clip_in_target_space)));
1229 } 1280 }
1230 1281
1231 template <typename LayerType> 1282 template <typename LayerType>
1232 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, 1283 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer,
1233 const TransformTree& tree) { 1284 const TransformTree& tree) {
1234 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), 1285 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(),
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 render_surface->SetReplicaDrawTransform(render_surface->draw_transform() * 1434 render_surface->SetReplicaDrawTransform(render_surface->draw_transform() *
1384 replica_to_surface); 1435 replica_to_surface);
1385 render_surface->SetReplicaScreenSpaceTransform( 1436 render_surface->SetReplicaScreenSpaceTransform(
1386 render_surface->screen_space_transform() * replica_to_surface); 1437 render_surface->screen_space_transform() * replica_to_surface);
1387 } else { 1438 } else {
1388 render_surface->SetReplicaDrawTransform(gfx::Transform()); 1439 render_surface->SetReplicaDrawTransform(gfx::Transform());
1389 render_surface->SetReplicaScreenSpaceTransform(gfx::Transform()); 1440 render_surface->SetReplicaScreenSpaceTransform(gfx::Transform());
1390 } 1441 }
1391 1442
1392 SetSurfaceClipRect(property_trees->clip_tree.parent(clip_node), 1443 SetSurfaceClipRect(property_trees->clip_tree.parent(clip_node),
1393 property_trees->transform_tree, render_surface); 1444 property_trees->transform_tree,
1445 property_trees->effect_tree, render_surface);
1394 } 1446 }
1395 1447
1396 #if DCHECK_IS_ON() 1448 #if DCHECK_IS_ON()
1397 static void ValidatePageScaleLayer(const Layer* page_scale_layer) { 1449 static void ValidatePageScaleLayer(const Layer* page_scale_layer) {
1398 DCHECK_EQ(page_scale_layer->position().ToString(), gfx::PointF().ToString()); 1450 DCHECK_EQ(page_scale_layer->position().ToString(), gfx::PointF().ToString());
1399 DCHECK_EQ(page_scale_layer->transform_origin().ToString(), 1451 DCHECK_EQ(page_scale_layer->transform_origin().ToString(),
1400 gfx::Point3F().ToString()); 1452 gfx::Point3F().ToString());
1401 } 1453 }
1402 1454
1403 static void ValidatePageScaleLayer(const LayerImpl* page_scale_layer) {} 1455 static void ValidatePageScaleLayer(const LayerImpl* page_scale_layer) {}
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 void UpdateElasticOverscroll(PropertyTrees* property_trees, 1541 void UpdateElasticOverscroll(PropertyTrees* property_trees,
1490 const Layer* overscroll_elasticity_layer, 1542 const Layer* overscroll_elasticity_layer,
1491 const gfx::Vector2dF& elastic_overscroll) { 1543 const gfx::Vector2dF& elastic_overscroll) {
1492 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, 1544 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer,
1493 elastic_overscroll); 1545 elastic_overscroll);
1494 } 1546 }
1495 1547
1496 } // namespace draw_property_utils 1548 } // namespace draw_property_utils
1497 1549
1498 } // namespace cc 1550 } // namespace cc
OLDNEW
« no previous file with comments | « cc/proto/property_tree.proto ('k') | cc/trees/layer_tree_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698