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

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

Issue 2734983004: cc: Add a helper function for transforming rects between surface spaces (Closed)
Patch Set: Created 3 years, 9 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 | « no previous file | cc/trees/layer_tree_host_common_unittest.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 25 matching lines...) Expand all
36 36
37 static const EffectNode* ContentsTargetEffectNode( 37 static const EffectNode* ContentsTargetEffectNode(
38 const int effect_tree_index, 38 const int effect_tree_index,
39 const EffectTree& effect_tree) { 39 const EffectTree& effect_tree) {
40 const EffectNode* effect_node = effect_tree.Node(effect_tree_index); 40 const EffectNode* effect_node = effect_tree.Node(effect_tree_index);
41 return effect_tree.GetRenderSurface(effect_tree_index) 41 return effect_tree.GetRenderSurface(effect_tree_index)
42 ? effect_node 42 ? effect_node
43 : effect_tree.Node(effect_node->target_id); 43 : effect_tree.Node(effect_node->target_id);
44 } 44 }
45 45
46 static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees,
47 int source_effect_id,
48 int dest_effect_id,
49 gfx::RectF clip_in_source_space,
50 gfx::RectF* clip_in_dest_space) {
51 const EffectNode* source_effect_node =
52 property_trees->effect_tree.Node(source_effect_id);
53 int source_transform_id = source_effect_node->transform_id;
54 const EffectNode* dest_effect_node =
55 property_trees->effect_tree.Node(dest_effect_id);
56 int dest_transform_id = dest_effect_node->transform_id;
57 gfx::Transform source_to_dest;
58 if (source_transform_id > dest_transform_id) {
59 if (property_trees->GetToTarget(source_transform_id, dest_effect_id,
60 &source_to_dest)) {
61 ConcatInverseSurfaceContentsScale(source_effect_node, &source_to_dest);
62 *clip_in_dest_space =
63 MathUtil::MapClippedRect(source_to_dest, clip_in_source_space);
64 } else {
65 return false;
66 }
67 } else {
68 if (property_trees->GetFromTarget(dest_transform_id, source_effect_id,
69 &source_to_dest)) {
70 PostConcatSurfaceContentsScale(dest_effect_node, &source_to_dest);
71 *clip_in_dest_space =
72 MathUtil::ProjectClippedRect(source_to_dest, clip_in_source_space);
73 } else {
74 return false;
75 }
76 }
77 return true;
78 }
79
46 bool ComputeClipRectInTargetSpace(const LayerImpl* layer, 80 bool ComputeClipRectInTargetSpace(const LayerImpl* layer,
47 const ClipNode* clip_node, 81 const ClipNode* clip_node,
48 const PropertyTrees* property_trees, 82 const PropertyTrees* property_trees,
49 int target_node_id, 83 int target_node_id,
50 bool for_visible_rect_calculation, 84 bool for_visible_rect_calculation,
51 gfx::RectF* clip_rect_in_target_space) { 85 gfx::RectF* clip_rect_in_target_space) {
52 DCHECK(layer->clip_tree_index() == clip_node->id); 86 DCHECK(layer->clip_tree_index() == clip_node->id);
53 DCHECK(clip_node->target_transform_id != target_node_id); 87 DCHECK(clip_node->target_transform_id != target_node_id);
54 88
55 const EffectTree& effect_tree = property_trees->effect_tree; 89 const EffectTree& effect_tree = property_trees->effect_tree;
56 const EffectNode* target_effect_node = 90 const EffectNode* target_effect_node =
57 ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree); 91 ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree);
58 gfx::Transform clip_to_target; 92 gfx::Transform clip_to_target;
59 // We use the local clip for clip rect calculation and combined clip for 93 // We use the local clip for clip rect calculation and combined clip for
60 // visible rect calculation. 94 // visible rect calculation.
61 gfx::RectF clip_from_clip_node = 95 gfx::RectF clip_from_clip_node =
62 for_visible_rect_calculation ? clip_node->combined_clip_in_target_space 96 for_visible_rect_calculation ? clip_node->combined_clip_in_target_space
63 : clip_node->clip_in_target_space; 97 : clip_node->clip_in_target_space;
64 98
65 if (clip_node->target_transform_id > target_node_id) { 99 return ConvertRectBetweenSurfaceSpaces(
66 // In this case, layer has a scroll parent. We need to keep the scale 100 property_trees, clip_node->target_effect_id, target_effect_node->id,
67 // at the layer's target but remove the scale at the scroll parent's 101 clip_from_clip_node, clip_rect_in_target_space);
68 // target.
69 if (property_trees->GetToTarget(clip_node->target_transform_id,
70 target_effect_node->id, &clip_to_target)) {
71 const EffectNode* source_node =
72 effect_tree.Node(clip_node->target_effect_id);
73 ConcatInverseSurfaceContentsScale(source_node, &clip_to_target);
74 *clip_rect_in_target_space =
75 MathUtil::MapClippedRect(clip_to_target, clip_from_clip_node);
76 } else {
77 return false;
78 }
79 } else {
80 if (property_trees->GetFromTarget(
81 target_node_id, clip_node->target_effect_id, &clip_to_target)) {
82 PostConcatSurfaceContentsScale(target_effect_node, &clip_to_target);
83 *clip_rect_in_target_space =
84 MathUtil::ProjectClippedRect(clip_to_target, clip_from_clip_node);
85 } else {
86 return false;
87 }
88 }
89 return true;
90 } 102 }
91 103
92 struct ConditionalClip { 104 struct ConditionalClip {
93 bool is_clipped; 105 bool is_clipped;
94 gfx::RectF clip_rect; 106 gfx::RectF clip_rect;
95 }; 107 };
96 108
97 static ConditionalClip ComputeTargetRectInLocalSpace( 109 static ConditionalClip ComputeTargetRectInLocalSpace(
98 gfx::RectF rect, 110 gfx::RectF rect,
99 const PropertyTrees* property_trees, 111 const PropertyTrees* property_trees,
100 int target_transform_id, 112 int target_transform_id,
101 int local_transform_id, 113 int local_transform_id,
102 const int target_effect_id) { 114 const int target_effect_id) {
103 gfx::Transform target_to_local; 115 gfx::Transform target_to_local;
104 bool success = property_trees->GetFromTarget( 116 bool success = property_trees->GetFromTarget(
105 local_transform_id, target_effect_id, &target_to_local); 117 local_transform_id, target_effect_id, &target_to_local);
106 if (!success) 118 if (!success)
107 // If transform is not invertible, cannot apply clip. 119 // If transform is not invertible, cannot apply clip.
108 return ConditionalClip{false, gfx::RectF()}; 120 return ConditionalClip{false, gfx::RectF()};
109 121
110 if (target_transform_id > local_transform_id) 122 if (target_transform_id > local_transform_id)
111 return ConditionalClip{true, // is_clipped. 123 return ConditionalClip{true, // is_clipped.
112 MathUtil::MapClippedRect(target_to_local, rect)}; 124 MathUtil::MapClippedRect(target_to_local, rect)};
113 125
114 return ConditionalClip{true, // is_clipped. 126 return ConditionalClip{true, // is_clipped.
115 MathUtil::ProjectClippedRect(target_to_local, rect)}; 127 MathUtil::ProjectClippedRect(target_to_local, rect)};
116 } 128 }
117 129
118 static ConditionalClip ConvertRectBetweenSurfaceSpaces(
119 gfx::RectF rect,
120 const PropertyTrees* property_trees,
121 int source_transform_id,
122 int source_effect_id,
123 int dest_transform_id,
124 int dest_effect_id) {
125 gfx::Transform source_to_dest;
126 bool success = property_trees->GetToTarget(source_transform_id,
127 dest_effect_id, &source_to_dest);
128 if (!success)
129 return ConditionalClip{false, gfx::RectF()};
130 const EffectTree& effect_tree = property_trees->effect_tree;
131 const EffectNode* source_effect_node = effect_tree.Node(source_effect_id);
132 ConcatInverseSurfaceContentsScale(source_effect_node, &source_to_dest);
133 if (source_transform_id > dest_transform_id) {
134 return ConditionalClip{true, // is_clipped
135 MathUtil::MapClippedRect(source_to_dest, rect)};
136 }
137 return ConditionalClip{true, // is_clipped
138 MathUtil::ProjectClippedRect(source_to_dest, rect)};
139 }
140
141 static ConditionalClip ComputeLocalRectInTargetSpace( 130 static ConditionalClip ComputeLocalRectInTargetSpace(
142 gfx::RectF rect, 131 gfx::RectF rect,
143 const PropertyTrees* property_trees, 132 const PropertyTrees* property_trees,
144 int current_transform_id, 133 int current_transform_id,
145 int target_transform_id, 134 int target_transform_id,
146 int target_effect_id) { 135 int target_effect_id) {
147 gfx::Transform current_to_target; 136 gfx::Transform current_to_target;
148 if (!property_trees->GetToTarget(current_transform_id, target_effect_id, 137 if (!property_trees->GetToTarget(current_transform_id, target_effect_id,
149 &current_to_target)) { 138 &current_to_target)) {
150 // If transform is not invertible, cannot apply clip. 139 // If transform is not invertible, cannot apply clip.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 return true; 188 return true;
200 } 189 }
201 case ClipNode::ClipType::EXPANDS_CLIP: { 190 case ClipNode::ClipType::EXPANDS_CLIP: {
202 if (!include_expanding_clips) 191 if (!include_expanding_clips)
203 return true; 192 return true;
204 193
205 // Bring the accumulated clip to the space of the expanding effect. 194 // Bring the accumulated clip to the space of the expanding effect.
206 const EffectNode* expanding_effect_node = 195 const EffectNode* expanding_effect_node =
207 property_trees->effect_tree.Node( 196 property_trees->effect_tree.Node(
208 clip_node->clip_expander->target_effect_id()); 197 clip_node->clip_expander->target_effect_id());
209 ConditionalClip accumulated_clip_in_expanding_space = 198 gfx::RectF accumulated_clip_rect_in_expanding_space;
210 ConvertRectBetweenSurfaceSpaces( 199 bool success = ConvertRectBetweenSurfaceSpaces(
211 *accumulated_clip, property_trees, target_transform_id, target_id, 200 property_trees, target_id, expanding_effect_node->id,
212 expanding_effect_node->transform_id, expanding_effect_node->id); 201 *accumulated_clip, &accumulated_clip_rect_in_expanding_space);
213 // If transform is not invertible, no clip will be applied. 202 // If transform is not invertible, no clip will be applied.
214 if (!accumulated_clip_in_expanding_space.is_clipped) 203 if (!success)
215 return false; 204 return false;
216 205
217 // Do the expansion. 206 // Do the expansion.
218 gfx::RectF expanded_clip_in_expanding_space = 207 gfx::RectF expanded_clip_in_expanding_space =
219 gfx::RectF(clip_node->clip_expander->MapRectReverse( 208 gfx::RectF(clip_node->clip_expander->MapRectReverse(
220 gfx::ToEnclosingRect( 209 gfx::ToEnclosingRect(accumulated_clip_rect_in_expanding_space),
221 accumulated_clip_in_expanding_space.clip_rect),
222 property_trees)); 210 property_trees));
223 211
224 // Put the expanded clip back into the original target space. 212 // Put the expanded clip back into the original target space.
225 ConditionalClip expanded_clip_in_target_space = 213 success = ConvertRectBetweenSurfaceSpaces(
226 ConvertRectBetweenSurfaceSpaces( 214 property_trees, expanding_effect_node->id, target_id,
227 expanded_clip_in_expanding_space, property_trees, 215 expanded_clip_in_expanding_space, accumulated_clip);
228 expanding_effect_node->transform_id, expanding_effect_node->id,
229 target_transform_id, target_id);
230 // If transform is not invertible, no clip will be applied. 216 // If transform is not invertible, no clip will be applied.
231 if (!expanded_clip_in_target_space.is_clipped) 217 if (!success)
232 return false; 218 return false;
233 *accumulated_clip = expanded_clip_in_target_space.clip_rect;
234 return true; 219 return true;
235 } 220 }
236 case ClipNode::ClipType::NONE: 221 case ClipNode::ClipType::NONE:
237 return true; 222 return true;
238 } 223 }
239 NOTREACHED(); 224 NOTREACHED();
240 return true; 225 return true;
241 } 226 }
242 227
243 static ConditionalClip ComputeAccumulatedClip( 228 static ConditionalClip ComputeAccumulatedClip(
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 // must combine clips. For each clip node, we save the clip rects in its 796 // must combine clips. For each clip node, we save the clip rects in its
812 // target space. So, we need to get the ancestor clip rect in the current 797 // target space. So, we need to get the ancestor clip rect in the current
813 // clip node's target space. 798 // clip node's target space.
814 gfx::RectF parent_combined_clip_in_target_space = 799 gfx::RectF parent_combined_clip_in_target_space =
815 parent_clip_node->combined_clip_in_target_space; 800 parent_clip_node->combined_clip_in_target_space;
816 gfx::RectF parent_clip_in_target_space = 801 gfx::RectF parent_clip_in_target_space =
817 parent_clip_node->clip_in_target_space; 802 parent_clip_node->clip_in_target_space;
818 if (parent_target_transform_node && 803 if (parent_target_transform_node &&
819 parent_target_transform_node->id != clip_node->target_transform_id && 804 parent_target_transform_node->id != clip_node->target_transform_id &&
820 non_root_surfaces_enabled) { 805 non_root_surfaces_enabled) {
821 success &= property_trees->GetFromTarget( 806 success &= ConvertRectBetweenSurfaceSpaces(
822 clip_node->target_transform_id, parent_clip_node->target_effect_id, 807 property_trees, parent_clip_node->target_effect_id,
823 &parent_to_current); 808 clip_node->target_effect_id,
824 const EffectNode* target_effect_node = 809 parent_clip_node->combined_clip_in_target_space,
825 effect_tree.Node(clip_node->target_effect_id); 810 &parent_combined_clip_in_target_space);
826 PostConcatSurfaceContentsScale(target_effect_node, &parent_to_current);
827 // If we can't compute a transform, it's because we had to use the inverse 811 // If we can't compute a transform, it's because we had to use the inverse
828 // of a singular transform. We won't draw in this case, so there's no need 812 // of a singular transform. We won't draw in this case, so there's no need
829 // to compute clips. 813 // to compute clips.
830 if (!success) 814 if (!success)
831 continue; 815 continue;
832 parent_combined_clip_in_target_space = MathUtil::ProjectClippedRect(
833 parent_to_current, parent_clip_node->combined_clip_in_target_space);
834 if (clip_node->clip_type == ClipNode::ClipType::EXPANDS_CLIP) { 816 if (clip_node->clip_type == ClipNode::ClipType::EXPANDS_CLIP) {
835 parent_combined_clip_in_target_space = 817 parent_combined_clip_in_target_space =
836 gfx::RectF(clip_node->clip_expander->MapRectReverse( 818 gfx::RectF(clip_node->clip_expander->MapRectReverse(
837 gfx::ToEnclosingRect(parent_combined_clip_in_target_space), 819 gfx::ToEnclosingRect(parent_combined_clip_in_target_space),
838 property_trees)); 820 property_trees));
839 } 821 }
840 parent_clip_in_target_space = MathUtil::ProjectClippedRect( 822 ConvertRectBetweenSurfaceSpaces(
841 parent_to_current, parent_clip_node->clip_in_target_space); 823 property_trees, parent_clip_node->target_effect_id,
824 clip_node->target_effect_id, parent_clip_node->clip_in_target_space,
825 &parent_clip_in_target_space);
842 } 826 }
843 // Only nodes affected by ancestor clips will have their clip adjusted due 827 // Only nodes affected by ancestor clips will have their clip adjusted due
844 // to intersecting with an ancestor clip. But, we still need to propagate 828 // to intersecting with an ancestor clip. But, we still need to propagate
845 // the combined clip to our children because if they are clipped, they may 829 // the combined clip to our children because if they are clipped, they may
846 // need to clip using our parent clip and if we don't propagate it here, 830 // need to clip using our parent clip and if we don't propagate it here,
847 // it will be lost. 831 // it will be lost.
848 if (clip_node->resets_clip && non_root_surfaces_enabled) { 832 if (clip_node->resets_clip && non_root_surfaces_enabled) {
849 if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) { 833 if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) {
850 gfx::Transform to_target; 834 gfx::Transform to_target;
851 property_trees->GetToTarget(clip_node->transform_id, 835 property_trees->GetToTarget(clip_node->transform_id,
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 if (transform_tree.TargetId(transform_node->id) == 1232 if (transform_tree.TargetId(transform_node->id) ==
1249 parent_clip_node->target_transform_id) { 1233 parent_clip_node->target_transform_id) {
1250 render_surface->SetClipRect( 1234 render_surface->SetClipRect(
1251 gfx::ToEnclosingRect(parent_clip_node->clip_in_target_space)); 1235 gfx::ToEnclosingRect(parent_clip_node->clip_in_target_space));
1252 return; 1236 return;
1253 } 1237 }
1254 1238
1255 // 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
1256 // 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
1257 // 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.
1258 gfx::Transform clip_parent_target_to_target;
1259 const EffectNode* effect_node = 1242 const EffectNode* effect_node =
1260 effect_tree.Node(render_surface->EffectTreeIndex()); 1243 effect_tree.Node(render_surface->EffectTreeIndex());
1261 int target_effect_id = effect_node->target_id; 1244 int target_effect_id = effect_node->target_id;
1262 const bool success = property_trees->GetToTarget( 1245 gfx::RectF clip_rect;
1263 parent_clip_node->target_transform_id, target_effect_id, 1246 const bool success = ConvertRectBetweenSurfaceSpaces(
1264 &clip_parent_target_to_target); 1247 property_trees, parent_clip_node->target_effect_id, target_effect_id,
1248 parent_clip_node->clip_in_target_space, &clip_rect);
1265 1249
1266 if (!success) { 1250 if (!success) {
1267 render_surface->SetClipRect(gfx::Rect()); 1251 render_surface->SetClipRect(gfx::Rect());
1268 return; 1252 return;
1269 } 1253 }
1270 1254 render_surface->SetClipRect(gfx::ToEnclosingRect(clip_rect));
1271 if (parent_clip_node->target_transform_id <
1272 transform_tree.TargetId(transform_node->id)) {
1273 render_surface->SetClipRect(gfx::ToEnclosingRect(
1274 MathUtil::ProjectClippedRect(clip_parent_target_to_target,
1275 parent_clip_node->clip_in_target_space)));
1276 } else {
1277 render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::MapClippedRect(
1278 clip_parent_target_to_target, parent_clip_node->clip_in_target_space)));
1279 }
1280 } 1255 }
1281 1256
1282 template <typename LayerType> 1257 template <typename LayerType>
1283 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, 1258 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer,
1284 const TransformTree& tree) { 1259 const TransformTree& tree) {
1285 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), 1260 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(),
1286 layer->offset_to_transform_parent().y()); 1261 layer->offset_to_transform_parent().y());
1287 gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); 1262 gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index());
1288 xform.ConcatTransform(ssxform); 1263 xform.ConcatTransform(ssxform);
1289 if (layer->should_flatten_transform_from_property_tree()) 1264 if (layer->should_flatten_transform_from_property_tree())
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 void UpdateElasticOverscroll(PropertyTrees* property_trees, 1471 void UpdateElasticOverscroll(PropertyTrees* property_trees,
1497 const Layer* overscroll_elasticity_layer, 1472 const Layer* overscroll_elasticity_layer,
1498 const gfx::Vector2dF& elastic_overscroll) { 1473 const gfx::Vector2dF& elastic_overscroll) {
1499 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, 1474 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer,
1500 elastic_overscroll); 1475 elastic_overscroll);
1501 } 1476 }
1502 1477
1503 } // namespace draw_property_utils 1478 } // namespace draw_property_utils
1504 1479
1505 } // namespace cc 1480 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | cc/trees/layer_tree_host_common_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698