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/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 Loading... | |
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 Loading... | |
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 Loading... | |
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, ¤t_to_target)) | 173 target_transform_id, ¤t_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 ¤t_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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |