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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 layer->effect_tree_index()); | 49 layer->effect_tree_index()); |
50 if (effect_node->owner_id != layer->id()) | 50 if (effect_node->owner_id != layer->id()) |
51 return; | 51 return; |
52 DCHECK_EQ(effect_node->mask_layer_id, -1) << "layer: " << layer->id(); | 52 DCHECK_EQ(effect_node->mask_layer_id, -1) << "layer: " << layer->id(); |
53 DCHECK_EQ(effect_node->replica_layer_id, -1) << "layer: " << layer->id(); | 53 DCHECK_EQ(effect_node->replica_layer_id, -1) << "layer: " << layer->id(); |
54 DCHECK(effect_node->background_filters.IsEmpty()); | 54 DCHECK(effect_node->background_filters.IsEmpty()); |
55 } | 55 } |
56 | 56 |
57 #endif | 57 #endif |
58 | 58 |
59 static void AddSublayerScaleToTransform(const int effect_node_id, | 59 static void ApplySublayerScale(const int effect_node_id, |
60 const EffectTree& effect_tree, | 60 const EffectTree& effect_tree, |
61 gfx::Transform* transform) { | 61 gfx::Transform* transform) { |
62 const EffectNode* effect_node = effect_tree.Node(effect_node_id); | 62 const EffectNode* effect_node = effect_tree.Node(effect_node_id); |
63 const EffectNode* target_effect_node = | 63 const EffectNode* target_effect_node = |
64 effect_node->has_render_surface | 64 effect_node->has_render_surface |
65 ? effect_node | 65 ? effect_node |
66 : effect_tree.Node(effect_node->target_id); | 66 : effect_tree.Node(effect_node->target_id); |
67 transform->matrix().postScale(target_effect_node->sublayer_scale.x(), | 67 transform->matrix().postScale(target_effect_node->sublayer_scale.x(), |
68 target_effect_node->sublayer_scale.y(), 1.f); | 68 target_effect_node->sublayer_scale.y(), 1.f); |
69 } | 69 } |
70 | 70 |
71 #if DCHECK_IS_ON() | 71 #if DCHECK_IS_ON() |
(...skipping 18 matching lines...) Expand all Loading... |
90 #endif | 90 #endif |
91 | 91 |
92 template <typename LayerType> | 92 template <typename LayerType> |
93 bool ComputeClipRectInTargetSpace(const LayerType* layer, | 93 bool ComputeClipRectInTargetSpace(const LayerType* layer, |
94 const ClipNode* clip_node, | 94 const ClipNode* clip_node, |
95 const TransformTree& transform_tree, | 95 const TransformTree& transform_tree, |
96 const EffectTree& effect_tree, | 96 const EffectTree& effect_tree, |
97 int target_node_id, | 97 int target_node_id, |
98 gfx::RectF* clip_rect_in_target_space) { | 98 gfx::RectF* clip_rect_in_target_space) { |
99 DCHECK(layer->clip_tree_index() == clip_node->id); | 99 DCHECK(layer->clip_tree_index() == clip_node->id); |
100 DCHECK(clip_node->target_id != target_node_id); | 100 DCHECK(clip_node->target_transform_id != target_node_id); |
101 | 101 |
102 gfx::Transform clip_to_target; | 102 gfx::Transform clip_to_target; |
103 if (clip_node->target_id > target_node_id) { | 103 if (clip_node->target_transform_id > target_node_id) { |
104 // In this case, layer has a scroll parent. We need to keep the scale | 104 // In this case, layer has a scroll parent. We need to keep the scale |
105 // at the layer's target but remove the scale at the scroll parent's | 105 // at the layer's target but remove the scale at the scroll parent's |
106 // target. | 106 // target. |
107 if (transform_tree.ComputeTransform(clip_node->target_id, target_node_id, | 107 if (transform_tree.ComputeTransform(clip_node->target_transform_id, |
108 &clip_to_target)) { | 108 target_node_id, &clip_to_target)) { |
109 // We don't have to apply sublayer scale when target is root. | 109 // We don't have to apply sublayer scale when target is root. |
110 if (target_node_id != 0) { | 110 if (target_node_id != 0) { |
111 AddSublayerScaleToTransform(layer->effect_tree_index(), effect_tree, | 111 ApplySublayerScale(layer->effect_tree_index(), effect_tree, |
112 &clip_to_target); | 112 &clip_to_target); |
113 #if DCHECK_IS_ON() | 113 #if DCHECK_IS_ON() |
114 VerifySublayerScalesMatch(layer->effect_tree_index(), target_node_id, | 114 VerifySublayerScalesMatch(layer->effect_tree_index(), target_node_id, |
115 effect_tree, transform_tree); | 115 effect_tree, transform_tree); |
116 #endif | 116 #endif |
117 } | 117 } |
118 | 118 |
119 const TransformNode* source_node = | 119 const TransformNode* source_node = |
120 transform_tree.Node(clip_node->target_id); | 120 transform_tree.Node(clip_node->target_transform_id); |
121 if (source_node->sublayer_scale.x() != 0.f && | 121 if (source_node->sublayer_scale.x() != 0.f && |
122 source_node->sublayer_scale.y() != 0.f) | 122 source_node->sublayer_scale.y() != 0.f) |
123 clip_to_target.Scale(1.0f / source_node->sublayer_scale.x(), | 123 clip_to_target.Scale(1.0f / source_node->sublayer_scale.x(), |
124 1.0f / source_node->sublayer_scale.y()); | 124 1.0f / source_node->sublayer_scale.y()); |
125 *clip_rect_in_target_space = MathUtil::MapClippedRect( | 125 *clip_rect_in_target_space = MathUtil::MapClippedRect( |
126 clip_to_target, clip_node->clip_in_target_space); | 126 clip_to_target, clip_node->clip_in_target_space); |
127 } else { | 127 } else { |
128 return false; | 128 return false; |
129 } | 129 } |
130 } else { | 130 } else { |
131 if (transform_tree.ComputeTransform(clip_node->target_id, target_node_id, | 131 if (transform_tree.ComputeTransform(clip_node->target_transform_id, |
132 &clip_to_target)) { | 132 target_node_id, &clip_to_target)) { |
133 *clip_rect_in_target_space = MathUtil::ProjectClippedRect( | 133 *clip_rect_in_target_space = MathUtil::ProjectClippedRect( |
134 clip_to_target, clip_node->clip_in_target_space); | 134 clip_to_target, clip_node->clip_in_target_space); |
135 } else { | 135 } else { |
136 return false; | 136 return false; |
137 } | 137 } |
138 } | 138 } |
139 return true; | 139 return true; |
140 } | 140 } |
141 | 141 |
142 struct ConditionalClip { | 142 struct ConditionalClip { |
(...skipping 16 matching lines...) Expand all Loading... |
159 return ConditionalClip{true, // is_clipped. | 159 return ConditionalClip{true, // is_clipped. |
160 MathUtil::MapClippedRect(current_to_target, rect)}; | 160 MathUtil::MapClippedRect(current_to_target, rect)}; |
161 | 161 |
162 return ConditionalClip{true, // is_clipped. | 162 return ConditionalClip{true, // is_clipped. |
163 MathUtil::ProjectClippedRect(current_to_target, rect)}; | 163 MathUtil::ProjectClippedRect(current_to_target, rect)}; |
164 } | 164 } |
165 | 165 |
166 static ConditionalClip ComputeLocalRectInTargetSpace( | 166 static ConditionalClip ComputeLocalRectInTargetSpace( |
167 gfx::RectF rect, | 167 gfx::RectF rect, |
168 const TransformTree& transform_tree, | 168 const TransformTree& transform_tree, |
| 169 const EffectTree& effect_tree, |
169 int current_transform_id, | 170 int current_transform_id, |
170 int target_transform_id) { | 171 int target_transform_id, |
| 172 int target_effect_id) { |
171 gfx::Transform current_to_target; | 173 gfx::Transform current_to_target; |
172 if (!transform_tree.ComputeTransformWithDestinationSublayerScale( | 174 if (!transform_tree.ComputeTransform(current_transform_id, |
173 current_transform_id, target_transform_id, ¤t_to_target)) | 175 target_transform_id, ¤t_to_target)) |
174 // If transform is not invertible, cannot apply clip. | 176 // If transform is not invertible, cannot apply clip. |
175 return ConditionalClip{false, gfx::RectF()}; | 177 return ConditionalClip{false, gfx::RectF()}; |
| 178 // We don't have to apply sublayer scale when target is root. |
| 179 if (target_transform_id != 0) { |
| 180 ApplySublayerScale(target_effect_id, effect_tree, ¤t_to_target); |
| 181 #if DCHECK_IS_ON() |
| 182 VerifySublayerScalesMatch(target_effect_id, target_transform_id, |
| 183 effect_tree, transform_tree); |
| 184 #endif |
| 185 } |
176 | 186 |
177 if (current_transform_id > target_transform_id) | 187 if (current_transform_id > target_transform_id) |
178 return ConditionalClip{true, // is_clipped. | 188 return ConditionalClip{true, // is_clipped. |
179 MathUtil::MapClippedRect(current_to_target, rect)}; | 189 MathUtil::MapClippedRect(current_to_target, rect)}; |
180 | 190 |
181 return ConditionalClip{true, // is_clipped. | 191 return ConditionalClip{true, // is_clipped. |
182 MathUtil::ProjectClippedRect(current_to_target, rect)}; | 192 MathUtil::ProjectClippedRect(current_to_target, rect)}; |
183 } | 193 } |
184 | 194 |
185 static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, | 195 static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, |
186 const TransformTree& transform_tree, | 196 const TransformTree& transform_tree, |
187 int target_transform_id) { | 197 const EffectTree& effect_tree, |
| 198 int target_transform_id, |
| 199 int target_effect_id) { |
188 if (clip_node->transform_id != target_transform_id) | 200 if (clip_node->transform_id != target_transform_id) |
189 return ComputeLocalRectInTargetSpace(clip_node->clip, transform_tree, | 201 return ComputeLocalRectInTargetSpace(clip_node->clip, transform_tree, |
190 clip_node->transform_id, | 202 effect_tree, clip_node->transform_id, |
191 target_transform_id); | 203 target_transform_id, target_effect_id); |
192 | 204 |
193 gfx::RectF current_clip = clip_node->clip; | 205 gfx::RectF current_clip = clip_node->clip; |
194 gfx::Vector2dF sublayer_scale = | 206 gfx::Vector2dF sublayer_scale = |
195 transform_tree.Node(target_transform_id)->sublayer_scale; | 207 transform_tree.Node(target_transform_id)->sublayer_scale; |
196 if (sublayer_scale.x() > 0 && sublayer_scale.y() > 0) | 208 if (sublayer_scale.x() > 0 && sublayer_scale.y() > 0) |
197 current_clip.Scale(sublayer_scale.x(), sublayer_scale.y()); | 209 current_clip.Scale(sublayer_scale.x(), sublayer_scale.y()); |
198 return ConditionalClip{true /* is_clipped */, current_clip}; | 210 return ConditionalClip{true /* is_clipped */, current_clip}; |
199 } | 211 } |
200 | 212 |
201 static ConditionalClip ComputeAccumulatedClip( | 213 static ConditionalClip ComputeAccumulatedClip( |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 // to check applies_local_clip. | 251 // to check applies_local_clip. |
240 while (!clip_node->applies_local_clip && parent_chain.size() > 0) { | 252 while (!clip_node->applies_local_clip && parent_chain.size() > 0) { |
241 clip_node = parent_chain.top(); | 253 clip_node = parent_chain.top(); |
242 parent_chain.pop(); | 254 parent_chain.pop(); |
243 } | 255 } |
244 | 256 |
245 if (!clip_node->applies_local_clip) | 257 if (!clip_node->applies_local_clip) |
246 // No clip node applying clip in between. | 258 // No clip node applying clip in between. |
247 return ConditionalClip{false, gfx::RectF()}; | 259 return ConditionalClip{false, gfx::RectF()}; |
248 | 260 |
249 ConditionalClip current_clip = | 261 ConditionalClip current_clip = ComputeCurrentClip( |
250 ComputeCurrentClip(clip_node, transform_tree, target_transform_id); | 262 clip_node, transform_tree, effect_tree, target_transform_id, target_id); |
251 is_clipped = current_clip.is_clipped; | 263 is_clipped = current_clip.is_clipped; |
252 gfx::RectF accumulated_clip = current_clip.clip_rect; | 264 gfx::RectF accumulated_clip = current_clip.clip_rect; |
253 | 265 |
254 while (parent_chain.size() > 0) { | 266 while (parent_chain.size() > 0) { |
255 clip_node = parent_chain.top(); | 267 clip_node = parent_chain.top(); |
256 parent_chain.pop(); | 268 parent_chain.pop(); |
257 if (!clip_node->applies_local_clip) { | 269 if (!clip_node->applies_local_clip) { |
258 continue; | 270 continue; |
259 } | 271 } |
260 ConditionalClip current_clip = | 272 ConditionalClip current_clip = ComputeCurrentClip( |
261 ComputeCurrentClip(clip_node, transform_tree, target_transform_id); | 273 clip_node, transform_tree, effect_tree, target_transform_id, target_id); |
262 | 274 |
263 // If transform is not invertible, no clip will be applied. | 275 // If transform is not invertible, no clip will be applied. |
264 if (!current_clip.is_clipped) | 276 if (!current_clip.is_clipped) |
265 return ConditionalClip{false, gfx::RectF()}; | 277 return ConditionalClip{false, gfx::RectF()}; |
266 | 278 |
267 is_clipped = true; | 279 is_clipped = true; |
268 accumulated_clip = | 280 accumulated_clip = |
269 gfx::IntersectRects(accumulated_clip, current_clip.clip_rect); | 281 gfx::IntersectRects(accumulated_clip, current_clip.clip_rect); |
270 } | 282 } |
271 | 283 |
(...skipping 24 matching lines...) Expand all Loading... |
296 if (!fully_visible) { | 308 if (!fully_visible) { |
297 const TransformNode* transform_node = | 309 const TransformNode* transform_node = |
298 transform_tree.Node(layer->transform_tree_index()); | 310 transform_tree.Node(layer->transform_tree_index()); |
299 int target_node_id = transform_tree.ContentTargetId(transform_node->id); | 311 int target_node_id = transform_tree.ContentTargetId(transform_node->id); |
300 | 312 |
301 // The clip node stores clip rect in its target space. | 313 // The clip node stores clip rect in its target space. |
302 gfx::RectF clip_rect_in_target_space = clip_node->clip_in_target_space; | 314 gfx::RectF clip_rect_in_target_space = clip_node->clip_in_target_space; |
303 | 315 |
304 // 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 |
305 // target space. | 317 // target space. |
306 if (clip_node->target_id != target_node_id) { | 318 if (clip_node->target_transform_id != target_node_id) { |
307 // 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 |
308 // 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 |
309 // 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 |
310 // target has unclippped descendants, it is unclippped. | 322 // target has unclippped descendants, it is unclippped. |
311 if (!clip_node->layers_are_clipped) | 323 if (!clip_node->layers_are_clipped) |
312 continue; | 324 continue; |
313 | 325 |
314 // Compute the clip rect in target space and store it. | 326 // Compute the clip rect in target space and store it. |
315 if (!ComputeClipRectInTargetSpace(layer, clip_node, transform_tree, | 327 if (!ComputeClipRectInTargetSpace(layer, clip_node, transform_tree, |
316 effect_tree, target_node_id, | 328 effect_tree, target_node_id, |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | 440 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); |
429 continue; | 441 continue; |
430 } | 442 } |
431 | 443 |
432 int target_node_id = transform_tree.ContentTargetId(transform_node->id); | 444 int target_node_id = transform_tree.ContentTargetId(transform_node->id); |
433 | 445 |
434 // 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, |
435 // 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. |
436 gfx::RectF combined_clip_rect_in_target_space; | 448 gfx::RectF combined_clip_rect_in_target_space; |
437 | 449 |
438 if (clip_node->target_id != target_node_id) { | 450 if (clip_node->target_transform_id != target_node_id) { |
439 // 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 |
440 // 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 |
441 // 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 |
442 // target has unclippped descendants, it is unclippped. | 454 // target has unclippped descendants, it is unclippped. |
443 if (!clip_node->layers_are_clipped) { | 455 if (!clip_node->layers_are_clipped) { |
444 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | 456 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); |
445 continue; | 457 continue; |
446 } | 458 } |
447 | 459 |
448 // 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 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 } | 710 } |
699 | 711 |
700 static void ResetIfHasNanCoordinate(gfx::RectF* rect) { | 712 static void ResetIfHasNanCoordinate(gfx::RectF* rect) { |
701 if (std::isnan(rect->x()) || std::isnan(rect->y()) || | 713 if (std::isnan(rect->x()) || std::isnan(rect->y()) || |
702 std::isnan(rect->right()) || std::isnan(rect->bottom())) | 714 std::isnan(rect->right()) || std::isnan(rect->bottom())) |
703 *rect = gfx::RectF(); | 715 *rect = gfx::RectF(); |
704 } | 716 } |
705 | 717 |
706 void ComputeClips(ClipTree* clip_tree, | 718 void ComputeClips(ClipTree* clip_tree, |
707 const TransformTree& transform_tree, | 719 const TransformTree& transform_tree, |
| 720 const EffectTree& effect_tree, |
708 bool non_root_surfaces_enabled) { | 721 bool non_root_surfaces_enabled) { |
709 if (!clip_tree->needs_update()) | 722 if (!clip_tree->needs_update()) |
710 return; | 723 return; |
711 for (int i = 1; i < static_cast<int>(clip_tree->size()); ++i) { | 724 for (int i = 1; i < static_cast<int>(clip_tree->size()); ++i) { |
712 ClipNode* clip_node = clip_tree->Node(i); | 725 ClipNode* clip_node = clip_tree->Node(i); |
713 | 726 |
714 if (clip_node->id == 1) { | 727 if (clip_node->id == 1) { |
715 ResetIfHasNanCoordinate(&clip_node->clip); | 728 ResetIfHasNanCoordinate(&clip_node->clip); |
716 clip_node->clip_in_target_space = clip_node->clip; | 729 clip_node->clip_in_target_space = clip_node->clip; |
717 clip_node->combined_clip_in_target_space = clip_node->clip; | 730 clip_node->combined_clip_in_target_space = clip_node->clip; |
718 continue; | 731 continue; |
719 } | 732 } |
720 const TransformNode* transform_node = | 733 const TransformNode* transform_node = |
721 transform_tree.Node(clip_node->transform_id); | 734 transform_tree.Node(clip_node->transform_id); |
722 ClipNode* parent_clip_node = clip_tree->parent(clip_node); | 735 ClipNode* parent_clip_node = clip_tree->parent(clip_node); |
723 | 736 |
724 gfx::Transform parent_to_current; | 737 gfx::Transform parent_to_current; |
725 const TransformNode* parent_target_transform_node = | 738 const TransformNode* parent_target_transform_node = |
726 transform_tree.Node(parent_clip_node->target_id); | 739 transform_tree.Node(parent_clip_node->target_transform_id); |
727 bool success = true; | 740 bool success = true; |
728 | 741 |
729 // Clips must be combined in target space. We cannot, for example, combine | 742 // Clips must be combined in target space. We cannot, for example, combine |
730 // clips in the space of the child clip. The reason is non-affine | 743 // clips in the space of the child clip. The reason is non-affine |
731 // transforms. Say we have the following tree T->A->B->C, and B clips C, but | 744 // transforms. Say we have the following tree T->A->B->C, and B clips C, but |
732 // draw into target T. It may be the case that A applies a perspective | 745 // draw into target T. It may be the case that A applies a perspective |
733 // transform, and B and C are at different z positions. When projected into | 746 // transform, and B and C are at different z positions. When projected into |
734 // target space, the relative sizes and positions of B and C can shift. | 747 // target space, the relative sizes and positions of B and C can shift. |
735 // Since it's the relationship in target space that matters, that's where we | 748 // Since it's the relationship in target space that matters, that's where we |
736 // must combine clips. For each clip node, we save the clip rects in its | 749 // must combine clips. For each clip node, we save the clip rects in its |
737 // target space. So, we need to get the ancestor clip rect in the current | 750 // target space. So, we need to get the ancestor clip rect in the current |
738 // clip node's target space. | 751 // clip node's target space. |
739 gfx::RectF parent_combined_clip_in_target_space = | 752 gfx::RectF parent_combined_clip_in_target_space = |
740 parent_clip_node->combined_clip_in_target_space; | 753 parent_clip_node->combined_clip_in_target_space; |
741 gfx::RectF parent_clip_in_target_space = | 754 gfx::RectF parent_clip_in_target_space = |
742 parent_clip_node->clip_in_target_space; | 755 parent_clip_node->clip_in_target_space; |
743 if (parent_target_transform_node && | 756 if (parent_target_transform_node && |
744 parent_target_transform_node->id != clip_node->target_id && | 757 parent_target_transform_node->id != clip_node->target_transform_id && |
745 non_root_surfaces_enabled) { | 758 non_root_surfaces_enabled) { |
746 success &= transform_tree.ComputeTransformWithDestinationSublayerScale( | 759 success &= transform_tree.ComputeTransform( |
747 parent_target_transform_node->id, clip_node->target_id, | 760 parent_target_transform_node->id, clip_node->target_transform_id, |
748 &parent_to_current); | 761 &parent_to_current); |
| 762 // We don't have to apply sublayer scale when target is root. |
| 763 if (clip_node->target_transform_id != 0) { |
| 764 ApplySublayerScale(clip_node->target_effect_id, effect_tree, |
| 765 &parent_to_current); |
| 766 #if DCHECK_IS_ON() |
| 767 VerifySublayerScalesMatch(clip_node->target_effect_id, |
| 768 clip_node->target_transform_id, effect_tree, |
| 769 transform_tree); |
| 770 #endif |
| 771 } |
749 if (parent_target_transform_node->sublayer_scale.x() > 0 && | 772 if (parent_target_transform_node->sublayer_scale.x() > 0 && |
750 parent_target_transform_node->sublayer_scale.y() > 0) | 773 parent_target_transform_node->sublayer_scale.y() > 0) |
751 parent_to_current.Scale( | 774 parent_to_current.Scale( |
752 1.f / parent_target_transform_node->sublayer_scale.x(), | 775 1.f / parent_target_transform_node->sublayer_scale.x(), |
753 1.f / parent_target_transform_node->sublayer_scale.y()); | 776 1.f / parent_target_transform_node->sublayer_scale.y()); |
754 // If we can't compute a transform, it's because we had to use the inverse | 777 // If we can't compute a transform, it's because we had to use the inverse |
755 // of a singular transform. We won't draw in this case, so there's no need | 778 // of a singular transform. We won't draw in this case, so there's no need |
756 // to compute clips. | 779 // to compute clips. |
757 if (!success) | 780 if (!success) |
758 continue; | 781 continue; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 // no clip. So, clip_in_target_space is not used and hence we can set | 820 // no clip. So, clip_in_target_space is not used and hence we can set |
798 // it to an empty rect. | 821 // it to an empty rect. |
799 clip_node->clip_in_target_space = gfx::RectF(); | 822 clip_node->clip_in_target_space = gfx::RectF(); |
800 } | 823 } |
801 } else { | 824 } else { |
802 gfx::Transform source_to_target; | 825 gfx::Transform source_to_target; |
803 | 826 |
804 if (!non_root_surfaces_enabled) { | 827 if (!non_root_surfaces_enabled) { |
805 source_to_target = transform_tree.ToScreen(clip_node->transform_id); | 828 source_to_target = transform_tree.ToScreen(clip_node->transform_id); |
806 } else if (transform_tree.ContentTargetId(transform_node->id) == | 829 } else if (transform_tree.ContentTargetId(transform_node->id) == |
807 clip_node->target_id) { | 830 clip_node->target_transform_id) { |
808 source_to_target = transform_tree.ToTarget(clip_node->transform_id); | 831 source_to_target = transform_tree.ToTarget(clip_node->transform_id); |
809 } else { | 832 } else { |
810 success = transform_tree.ComputeTransformWithDestinationSublayerScale( | 833 success = transform_tree.ComputeTransform( |
811 transform_node->id, clip_node->target_id, &source_to_target); | 834 transform_node->id, clip_node->target_transform_id, |
| 835 &source_to_target); |
| 836 // We don't have to apply sublayer scale when target is root. |
| 837 if (clip_node->target_transform_id != 0) { |
| 838 ApplySublayerScale(clip_node->target_effect_id, effect_tree, |
| 839 &source_to_target); |
| 840 #if DCHECK_IS_ON() |
| 841 VerifySublayerScalesMatch(clip_node->target_effect_id, |
| 842 clip_node->target_transform_id, effect_tree, |
| 843 transform_tree); |
| 844 #endif |
| 845 } |
812 // source_to_target computation should be successful as target is an | 846 // source_to_target computation should be successful as target is an |
813 // ancestor of the transform node. | 847 // ancestor of the transform node. |
814 DCHECK(success); | 848 DCHECK(success); |
815 } | 849 } |
816 | 850 |
817 gfx::RectF source_clip_in_target_space = | 851 gfx::RectF source_clip_in_target_space = |
818 MathUtil::MapClippedRect(source_to_target, clip_node->clip); | 852 MathUtil::MapClippedRect(source_to_target, clip_node->clip); |
819 | 853 |
820 // With surfaces disabled, the only case where we use only the local clip | 854 // With surfaces disabled, the only case where we use only the local clip |
821 // for layer clipping is the case where no non-viewport ancestor node | 855 // for layer clipping is the case where no non-viewport ancestor node |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 static void VerifyDrawTransformsMatch(LayerImpl* layer, | 990 static void VerifyDrawTransformsMatch(LayerImpl* layer, |
957 PropertyTrees* property_trees) { | 991 PropertyTrees* property_trees) { |
958 const int source_id = layer->transform_tree_index(); | 992 const int source_id = layer->transform_tree_index(); |
959 int destination_id = FindTargetTransformTreeIndexFromEffectTree( | 993 int destination_id = FindTargetTransformTreeIndexFromEffectTree( |
960 property_trees->effect_tree, layer->effect_tree_index()); | 994 property_trees->effect_tree, layer->effect_tree_index()); |
961 gfx::Transform draw_transform; | 995 gfx::Transform draw_transform; |
962 property_trees->transform_tree.ComputeTransform(source_id, destination_id, | 996 property_trees->transform_tree.ComputeTransform(source_id, destination_id, |
963 &draw_transform); | 997 &draw_transform); |
964 // We don't have to apply sublayer scale when target is root. | 998 // We don't have to apply sublayer scale when target is root. |
965 if (destination_id != 0) { | 999 if (destination_id != 0) { |
966 AddSublayerScaleToTransform(layer->effect_tree_index(), | 1000 ApplySublayerScale(layer->effect_tree_index(), property_trees->effect_tree, |
967 property_trees->effect_tree, &draw_transform); | 1001 &draw_transform); |
968 #if DCHECK_IS_ON() | 1002 #if DCHECK_IS_ON() |
969 VerifySublayerScalesMatch(layer->effect_tree_index(), destination_id, | 1003 VerifySublayerScalesMatch(layer->effect_tree_index(), destination_id, |
970 property_trees->effect_tree, | 1004 property_trees->effect_tree, |
971 property_trees->transform_tree); | 1005 property_trees->transform_tree); |
972 #endif | 1006 #endif |
973 } | 1007 } |
974 if (layer->should_flatten_transform_from_property_tree()) | 1008 if (layer->should_flatten_transform_from_property_tree()) |
975 draw_transform.FlattenTo2d(); | 1009 draw_transform.FlattenTo2d(); |
976 draw_transform.Translate(layer->offset_to_transform_parent().x(), | 1010 draw_transform.Translate(layer->offset_to_transform_parent().x(), |
977 layer->offset_to_transform_parent().y()); | 1011 layer->offset_to_transform_parent().y()); |
(...skipping 16 matching lines...) Expand all Loading... |
994 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | 1028 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; |
995 property_trees->transform_tree.set_needs_update(true); | 1029 property_trees->transform_tree.set_needs_update(true); |
996 } | 1030 } |
997 if (property_trees->transform_tree.needs_update()) { | 1031 if (property_trees->transform_tree.needs_update()) { |
998 property_trees->clip_tree.set_needs_update(true); | 1032 property_trees->clip_tree.set_needs_update(true); |
999 property_trees->effect_tree.set_needs_update(true); | 1033 property_trees->effect_tree.set_needs_update(true); |
1000 } | 1034 } |
1001 UpdateRenderTarget(&property_trees->effect_tree, | 1035 UpdateRenderTarget(&property_trees->effect_tree, |
1002 property_trees->non_root_surfaces_enabled); | 1036 property_trees->non_root_surfaces_enabled); |
1003 ComputeTransforms(&property_trees->transform_tree); | 1037 ComputeTransforms(&property_trees->transform_tree); |
| 1038 // Computation of clips uses sublayer scale which is updated while computing |
| 1039 // effects. So, ComputeEffects should be before ComputeClips. |
| 1040 ComputeEffects(&property_trees->effect_tree); |
1004 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, | 1041 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, |
1005 can_render_to_separate_surface); | 1042 property_trees->effect_tree, can_render_to_separate_surface); |
1006 ComputeEffects(&property_trees->effect_tree); | |
1007 | 1043 |
1008 FindLayersThatNeedUpdates(root_layer->layer_tree_impl(), | 1044 FindLayersThatNeedUpdates(root_layer->layer_tree_impl(), |
1009 property_trees->transform_tree, | 1045 property_trees->transform_tree, |
1010 property_trees->effect_tree, visible_layer_list); | 1046 property_trees->effect_tree, visible_layer_list); |
1011 CalculateClipRects<LayerImpl>(*visible_layer_list, property_trees->clip_tree, | 1047 CalculateClipRects<LayerImpl>(*visible_layer_list, property_trees->clip_tree, |
1012 property_trees->transform_tree, | 1048 property_trees->transform_tree, |
1013 property_trees->effect_tree, | 1049 property_trees->effect_tree, |
1014 can_render_to_separate_surface); | 1050 can_render_to_separate_surface); |
1015 CalculateVisibleRects<LayerImpl>( | 1051 CalculateVisibleRects<LayerImpl>( |
1016 *visible_layer_list, property_trees->clip_tree, | 1052 *visible_layer_list, property_trees->clip_tree, |
1017 property_trees->transform_tree, property_trees->effect_tree, | 1053 property_trees->transform_tree, property_trees->effect_tree, |
1018 can_render_to_separate_surface); | 1054 can_render_to_separate_surface); |
1019 } | 1055 } |
1020 | 1056 |
1021 void UpdatePropertyTrees(PropertyTrees* property_trees, | 1057 void UpdatePropertyTrees(PropertyTrees* property_trees, |
1022 bool can_render_to_separate_surface) { | 1058 bool can_render_to_separate_surface) { |
1023 if (property_trees->non_root_surfaces_enabled != | 1059 if (property_trees->non_root_surfaces_enabled != |
1024 can_render_to_separate_surface) { | 1060 can_render_to_separate_surface) { |
1025 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | 1061 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; |
1026 property_trees->transform_tree.set_needs_update(true); | 1062 property_trees->transform_tree.set_needs_update(true); |
1027 } | 1063 } |
1028 if (property_trees->transform_tree.needs_update()) { | 1064 if (property_trees->transform_tree.needs_update()) { |
1029 property_trees->clip_tree.set_needs_update(true); | 1065 property_trees->clip_tree.set_needs_update(true); |
1030 property_trees->effect_tree.set_needs_update(true); | 1066 property_trees->effect_tree.set_needs_update(true); |
1031 } | 1067 } |
1032 ComputeTransforms(&property_trees->transform_tree); | 1068 ComputeTransforms(&property_trees->transform_tree); |
| 1069 // Computation of clips uses sublayer scale which is updated while computing |
| 1070 // effects. So, ComputeEffects should be before ComputeClips. |
| 1071 ComputeEffects(&property_trees->effect_tree); |
1033 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, | 1072 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, |
1034 can_render_to_separate_surface); | 1073 property_trees->effect_tree, can_render_to_separate_surface); |
1035 ComputeEffects(&property_trees->effect_tree); | |
1036 } | 1074 } |
1037 | 1075 |
1038 void ComputeVisibleRectsForTesting(PropertyTrees* property_trees, | 1076 void ComputeVisibleRectsForTesting(PropertyTrees* property_trees, |
1039 bool can_render_to_separate_surface, | 1077 bool can_render_to_separate_surface, |
1040 LayerList* update_layer_list) { | 1078 LayerList* update_layer_list) { |
1041 CalculateVisibleRects<Layer>(*update_layer_list, property_trees->clip_tree, | 1079 CalculateVisibleRects<Layer>(*update_layer_list, property_trees->clip_tree, |
1042 property_trees->transform_tree, | 1080 property_trees->transform_tree, |
1043 property_trees->effect_tree, | 1081 property_trees->effect_tree, |
1044 can_render_to_separate_surface); | 1082 can_render_to_separate_surface); |
1045 } | 1083 } |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 return; | 1187 return; |
1150 } | 1188 } |
1151 | 1189 |
1152 gfx::Transform render_surface_transform; | 1190 gfx::Transform render_surface_transform; |
1153 const TransformNode* target_transform_node = | 1191 const TransformNode* target_transform_node = |
1154 transform_tree.Node(transform_tree.TargetId(transform_node->id)); | 1192 transform_tree.Node(transform_tree.TargetId(transform_node->id)); |
1155 transform_tree.ComputeTransform(transform_node->id, target_transform_node->id, | 1193 transform_tree.ComputeTransform(transform_node->id, target_transform_node->id, |
1156 &render_surface_transform); | 1194 &render_surface_transform); |
1157 // We don't have to apply sublayer scale when target is root. | 1195 // We don't have to apply sublayer scale when target is root. |
1158 if (target_transform_node->id != 0) { | 1196 if (target_transform_node->id != 0) { |
1159 AddSublayerScaleToTransform(effect_node->target_id, effect_tree, | 1197 ApplySublayerScale(effect_node->target_id, effect_tree, |
1160 &render_surface_transform); | 1198 &render_surface_transform); |
1161 #if DCHECK_IS_ON() | 1199 #if DCHECK_IS_ON() |
1162 VerifySublayerScalesMatch(effect_node->target_id, target_transform_node->id, | 1200 VerifySublayerScalesMatch(effect_node->target_id, target_transform_node->id, |
1163 effect_tree, transform_tree); | 1201 effect_tree, transform_tree); |
1164 #endif | 1202 #endif |
1165 } | 1203 } |
1166 | 1204 |
1167 DCHECK(transform_node->sublayer_scale == effect_node->sublayer_scale); | 1205 DCHECK(transform_node->sublayer_scale == effect_node->sublayer_scale); |
1168 if (effect_node->sublayer_scale.x() != 0.0 && | 1206 if (effect_node->sublayer_scale.x() != 0.0 && |
1169 effect_node->sublayer_scale.y() != 0.0) | 1207 effect_node->sublayer_scale.y() != 0.0) |
1170 render_surface_transform.Scale(1.0 / effect_node->sublayer_scale.x(), | 1208 render_surface_transform.Scale(1.0 / effect_node->sublayer_scale.x(), |
1171 1.0 / effect_node->sublayer_scale.y()); | 1209 1.0 / effect_node->sublayer_scale.y()); |
1172 render_surface->SetDrawTransform(render_surface_transform); | 1210 render_surface->SetDrawTransform(render_surface_transform); |
1173 } | 1211 } |
1174 | 1212 |
1175 static void SetSurfaceIsClipped(const ClipNode* clip_node, | 1213 static void SetSurfaceIsClipped(const ClipNode* clip_node, |
1176 RenderSurfaceImpl* render_surface) { | 1214 RenderSurfaceImpl* render_surface) { |
1177 DCHECK(render_surface->OwningLayerId() == clip_node->owner_id) | 1215 DCHECK(render_surface->OwningLayerId() == clip_node->owner_id) |
1178 << "we now create clip node for every render surface"; | 1216 << "we now create clip node for every render surface"; |
1179 | 1217 |
1180 render_surface->SetIsClipped(clip_node->target_is_clipped); | 1218 render_surface->SetIsClipped(clip_node->target_is_clipped); |
1181 } | 1219 } |
1182 | 1220 |
1183 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, | 1221 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, |
1184 const TransformTree& transform_tree, | 1222 const TransformTree& transform_tree, |
| 1223 const EffectTree& effect_tree, |
1185 RenderSurfaceImpl* render_surface) { | 1224 RenderSurfaceImpl* render_surface) { |
1186 if (!render_surface->is_clipped()) { | 1225 if (!render_surface->is_clipped()) { |
1187 render_surface->SetClipRect(gfx::Rect()); | 1226 render_surface->SetClipRect(gfx::Rect()); |
1188 return; | 1227 return; |
1189 } | 1228 } |
1190 | 1229 |
1191 const TransformNode* transform_node = | 1230 const TransformNode* transform_node = |
1192 transform_tree.Node(render_surface->TransformTreeIndex()); | 1231 transform_tree.Node(render_surface->TransformTreeIndex()); |
1193 if (transform_tree.TargetId(transform_node->id) == | 1232 if (transform_tree.TargetId(transform_node->id) == |
1194 parent_clip_node->target_id) { | 1233 parent_clip_node->target_transform_id) { |
1195 render_surface->SetClipRect( | 1234 render_surface->SetClipRect( |
1196 gfx::ToEnclosingRect(parent_clip_node->clip_in_target_space)); | 1235 gfx::ToEnclosingRect(parent_clip_node->clip_in_target_space)); |
1197 return; | 1236 return; |
1198 } | 1237 } |
1199 | 1238 |
1200 // In this case, the clip child has reset the clip node for subtree and hence | 1239 // In this case, the clip child has reset the clip node for subtree and hence |
1201 // the parent clip node's clip rect is in clip parent's target space and not | 1240 // the parent clip node's clip rect is in clip parent's target space and not |
1202 // our target space. We need to transform it to our target space. | 1241 // our target space. We need to transform it to our target space. |
1203 gfx::Transform clip_parent_target_to_target; | 1242 gfx::Transform clip_parent_target_to_target; |
1204 const bool success = | 1243 const bool success = transform_tree.ComputeTransform( |
1205 transform_tree.ComputeTransformWithDestinationSublayerScale( | 1244 parent_clip_node->target_transform_id, |
1206 parent_clip_node->target_id, | 1245 transform_tree.TargetId(transform_node->id), |
1207 transform_tree.TargetId(transform_node->id), | 1246 &clip_parent_target_to_target); |
1208 &clip_parent_target_to_target); | |
1209 | 1247 |
1210 if (!success) { | 1248 if (!success) { |
1211 render_surface->SetClipRect(gfx::Rect()); | 1249 render_surface->SetClipRect(gfx::Rect()); |
1212 return; | 1250 return; |
1213 } | 1251 } |
1214 | 1252 |
1215 DCHECK_LT(parent_clip_node->target_id, | 1253 // We don't have to apply sublayer scale when target is root. |
| 1254 if (transform_tree.TargetId(transform_node->id) != 0) { |
| 1255 ApplySublayerScale(render_surface->EffectTreeIndex(), effect_tree, |
| 1256 &clip_parent_target_to_target); |
| 1257 #if DCHECK_IS_ON() |
| 1258 VerifySublayerScalesMatch(render_surface->EffectTreeIndex(), |
| 1259 transform_tree.TargetId(transform_node->id), |
| 1260 effect_tree, transform_tree); |
| 1261 #endif |
| 1262 } |
| 1263 |
| 1264 DCHECK_LT(parent_clip_node->target_transform_id, |
1216 transform_tree.TargetId(transform_node->id)); | 1265 transform_tree.TargetId(transform_node->id)); |
1217 render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | 1266 render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( |
1218 clip_parent_target_to_target, parent_clip_node->clip_in_target_space))); | 1267 clip_parent_target_to_target, parent_clip_node->clip_in_target_space))); |
1219 } | 1268 } |
1220 | 1269 |
1221 template <typename LayerType> | 1270 template <typename LayerType> |
1222 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, | 1271 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, |
1223 const TransformTree& tree) { | 1272 const TransformTree& tree) { |
1224 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), | 1273 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), |
1225 layer->offset_to_transform_parent().y()); | 1274 layer->offset_to_transform_parent().y()); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 render_surface->SetReplicaDrawTransform(render_surface->draw_transform() * | 1421 render_surface->SetReplicaDrawTransform(render_surface->draw_transform() * |
1373 replica_to_surface); | 1422 replica_to_surface); |
1374 render_surface->SetReplicaScreenSpaceTransform( | 1423 render_surface->SetReplicaScreenSpaceTransform( |
1375 render_surface->screen_space_transform() * replica_to_surface); | 1424 render_surface->screen_space_transform() * replica_to_surface); |
1376 } else { | 1425 } else { |
1377 render_surface->SetReplicaDrawTransform(gfx::Transform()); | 1426 render_surface->SetReplicaDrawTransform(gfx::Transform()); |
1378 render_surface->SetReplicaScreenSpaceTransform(gfx::Transform()); | 1427 render_surface->SetReplicaScreenSpaceTransform(gfx::Transform()); |
1379 } | 1428 } |
1380 | 1429 |
1381 SetSurfaceClipRect(property_trees->clip_tree.parent(clip_node), | 1430 SetSurfaceClipRect(property_trees->clip_tree.parent(clip_node), |
1382 property_trees->transform_tree, render_surface); | 1431 property_trees->transform_tree, |
| 1432 property_trees->effect_tree, render_surface); |
1383 } | 1433 } |
1384 | 1434 |
1385 #if DCHECK_IS_ON() | 1435 #if DCHECK_IS_ON() |
1386 static void ValidatePageScaleLayer(const Layer* page_scale_layer) { | 1436 static void ValidatePageScaleLayer(const Layer* page_scale_layer) { |
1387 DCHECK_EQ(page_scale_layer->position().ToString(), gfx::PointF().ToString()); | 1437 DCHECK_EQ(page_scale_layer->position().ToString(), gfx::PointF().ToString()); |
1388 DCHECK_EQ(page_scale_layer->transform_origin().ToString(), | 1438 DCHECK_EQ(page_scale_layer->transform_origin().ToString(), |
1389 gfx::Point3F().ToString()); | 1439 gfx::Point3F().ToString()); |
1390 } | 1440 } |
1391 | 1441 |
1392 static void ValidatePageScaleLayer(const LayerImpl* page_scale_layer) {} | 1442 static void ValidatePageScaleLayer(const LayerImpl* page_scale_layer) {} |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1477 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1527 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
1478 const Layer* overscroll_elasticity_layer, | 1528 const Layer* overscroll_elasticity_layer, |
1479 const gfx::Vector2dF& elastic_overscroll) { | 1529 const gfx::Vector2dF& elastic_overscroll) { |
1480 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1530 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
1481 elastic_overscroll); | 1531 elastic_overscroll); |
1482 } | 1532 } |
1483 | 1533 |
1484 } // namespace draw_property_utils | 1534 } // namespace draw_property_utils |
1485 | 1535 |
1486 } // namespace cc | 1536 } // namespace cc |
OLD | NEW |