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

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

Issue 2015653002: cc: Visible Rect Calculation use RectF between transformations (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@separateclipvis
Patch Set: rebase Created 4 years, 6 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 DCHECK(!layer->replica_layer()) << "layer: " << layer->id(); 55 DCHECK(!layer->replica_layer()) << "layer: " << layer->id();
56 } 56 }
57 57
58 #endif 58 #endif
59 59
60 template <typename LayerType> 60 template <typename LayerType>
61 bool ComputeClipRectInTargetSpace(const LayerType* layer, 61 bool ComputeClipRectInTargetSpace(const LayerType* layer,
62 const ClipNode* clip_node, 62 const ClipNode* clip_node,
63 const TransformTree& transform_tree, 63 const TransformTree& transform_tree,
64 int target_node_id, 64 int target_node_id,
65 gfx::Rect* clip_rect_in_target_space) { 65 gfx::RectF* clip_rect_in_target_space) {
66 DCHECK(layer->clip_tree_index() == clip_node->id); 66 DCHECK(layer->clip_tree_index() == clip_node->id);
67 DCHECK(clip_node->data.target_id != target_node_id); 67 DCHECK(clip_node->data.target_id != target_node_id);
68 68
69 gfx::Transform clip_to_target; 69 gfx::Transform clip_to_target;
70 if (clip_node->data.target_id > target_node_id) { 70 if (clip_node->data.target_id > target_node_id) {
71 // In this case, layer has a scroll parent. We need to keep the scale 71 // In this case, layer has a scroll parent. We need to keep the scale
72 // at the layer's target but remove the scale at the scroll parent's 72 // at the layer's target but remove the scale at the scroll parent's
73 // target. 73 // target.
74 if (transform_tree.ComputeTransformWithDestinationSublayerScale( 74 if (transform_tree.ComputeTransformWithDestinationSublayerScale(
75 clip_node->data.target_id, target_node_id, &clip_to_target)) { 75 clip_node->data.target_id, target_node_id, &clip_to_target)) {
76 const TransformNode* source_node = 76 const TransformNode* source_node =
77 transform_tree.Node(clip_node->data.target_id); 77 transform_tree.Node(clip_node->data.target_id);
78 if (source_node->data.sublayer_scale.x() != 0.f && 78 if (source_node->data.sublayer_scale.x() != 0.f &&
79 source_node->data.sublayer_scale.y() != 0.f) 79 source_node->data.sublayer_scale.y() != 0.f)
80 clip_to_target.Scale(1.0f / source_node->data.sublayer_scale.x(), 80 clip_to_target.Scale(1.0f / source_node->data.sublayer_scale.x(),
81 1.0f / source_node->data.sublayer_scale.y()); 81 1.0f / source_node->data.sublayer_scale.y());
82 *clip_rect_in_target_space = 82 *clip_rect_in_target_space = MathUtil::MapClippedRect(
83 gfx::ToEnclosingRect(MathUtil::MapClippedRect( 83 clip_to_target, clip_node->data.clip_in_target_space);
84 clip_to_target, clip_node->data.clip_in_target_space));
85 } else { 84 } else {
86 return false; 85 return false;
87 } 86 }
88 } else { 87 } else {
89 if (transform_tree.ComputeTransform(clip_node->data.target_id, 88 if (transform_tree.ComputeTransform(clip_node->data.target_id,
90 target_node_id, &clip_to_target)) { 89 target_node_id, &clip_to_target)) {
91 *clip_rect_in_target_space = 90 *clip_rect_in_target_space = MathUtil::ProjectClippedRect(
92 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( 91 clip_to_target, clip_node->data.clip_in_target_space);
93 clip_to_target, clip_node->data.clip_in_target_space));
94 } else { 92 } else {
95 return false; 93 return false;
96 } 94 }
97 } 95 }
98 return true; 96 return true;
99 } 97 }
100 98
101 template <typename LayerType> 99 template <typename LayerType>
102 void CalculateClipRects( 100 void CalculateClipRects(
103 const typename LayerType::LayerListType& visible_layer_list, 101 const typename LayerType::LayerListType& visible_layer_list,
(...skipping 20 matching lines...) Expand all
124 // content rect is visible. 122 // content rect is visible.
125 const bool fully_visible = !clip_node->data.layers_are_clipped && 123 const bool fully_visible = !clip_node->data.layers_are_clipped &&
126 !clip_node->data.target_is_clipped; 124 !clip_node->data.target_is_clipped;
127 125
128 if (!fully_visible) { 126 if (!fully_visible) {
129 const TransformNode* transform_node = 127 const TransformNode* transform_node =
130 transform_tree.Node(layer->transform_tree_index()); 128 transform_tree.Node(layer->transform_tree_index());
131 int target_node_id = transform_node->data.content_target_id; 129 int target_node_id = transform_node->data.content_target_id;
132 130
133 // The clip node stores clip rect in its target space. 131 // The clip node stores clip rect in its target space.
134 gfx::Rect clip_rect_in_target_space = 132 gfx::RectF clip_rect_in_target_space =
135 gfx::ToEnclosingRect(clip_node->data.clip_in_target_space); 133 clip_node->data.clip_in_target_space;
136 134
137 // If required, this clip rect should be mapped to the current layer's 135 // If required, this clip rect should be mapped to the current layer's
138 // target space. 136 // target space.
139 if (clip_node->data.target_id != target_node_id) { 137 if (clip_node->data.target_id != target_node_id) {
140 // In this case, layer has a clip parent or scroll parent (or shares the 138 // In this case, layer has a clip parent or scroll parent (or shares the
141 // target with an ancestor layer that has clip parent) and the clip 139 // target with an ancestor layer that has clip parent) and the clip
142 // parent's target is different from the layer's target. As the layer's 140 // parent's target is different from the layer's target. As the layer's
143 // target has unclippped descendants, it is unclippped. 141 // target has unclippped descendants, it is unclippped.
144 if (!clip_node->data.layers_are_clipped) 142 if (!clip_node->data.layers_are_clipped)
145 continue; 143 continue;
146 144
147 // Compute the clip rect in target space and store it. 145 // Compute the clip rect in target space and store it.
148 if (!ComputeClipRectInTargetSpace(layer, clip_node, transform_tree, 146 if (!ComputeClipRectInTargetSpace(layer, clip_node, transform_tree,
149 target_node_id, 147 target_node_id,
150 &clip_rect_in_target_space)) 148 &clip_rect_in_target_space))
151 continue; 149 continue;
152 } 150 }
153 151
154 if (!clip_rect_in_target_space.IsEmpty()) { 152 if (!clip_rect_in_target_space.IsEmpty()) {
155 layer->set_clip_rect(clip_rect_in_target_space); 153 layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space));
156 } else { 154 } else {
157 layer->set_clip_rect(gfx::Rect()); 155 layer->set_clip_rect(gfx::Rect());
158 } 156 }
159 } 157 }
160 } 158 }
161 } 159 }
162 160
163 bool GetLayerClipRect(const scoped_refptr<Layer> layer, 161 bool GetLayerClipRect(const scoped_refptr<Layer> layer,
164 const ClipNode* clip_node, 162 const ClipNode* clip_node,
165 const TransformTree& transform_tree, 163 const TransformTree& transform_tree,
166 int target_node_id, 164 int target_node_id,
167 gfx::Rect* clip_rect_in_target_space) { 165 gfx::RectF* clip_rect_in_target_space) {
168 return ComputeClipRectInTargetSpace(layer.get(), clip_node, transform_tree, 166 return ComputeClipRectInTargetSpace(layer.get(), clip_node, transform_tree,
169 target_node_id, 167 target_node_id,
170 clip_rect_in_target_space); 168 clip_rect_in_target_space);
171 } 169 }
172 170
173 bool GetLayerClipRect(const LayerImpl* layer, 171 bool GetLayerClipRect(const LayerImpl* layer,
174 const ClipNode* clip_node, 172 const ClipNode* clip_node,
175 const TransformTree& transform_tree, 173 const TransformTree& transform_tree,
176 int target_node_id, 174 int target_node_id,
177 gfx::Rect* clip_rect_in_target_space) { 175 gfx::RectF* clip_rect_in_target_space) {
178 // This is equivalent of calling ComputeClipRectInTargetSpace. 176 // This is equivalent of calling ComputeClipRectInTargetSpace.
179 *clip_rect_in_target_space = layer->clip_rect(); 177 *clip_rect_in_target_space = gfx::RectF(layer->clip_rect());
180 return transform_tree.Node(target_node_id)->data.ancestors_are_invertible; 178 return transform_tree.Node(target_node_id)->data.ancestors_are_invertible;
181 } 179 }
182 180
183 template <typename LayerType> 181 template <typename LayerType>
184 void CalculateVisibleRects( 182 void CalculateVisibleRects(
185 const typename LayerType::LayerListType& visible_layer_list, 183 const typename LayerType::LayerListType& visible_layer_list,
186 const ClipTree& clip_tree, 184 const ClipTree& clip_tree,
187 const TransformTree& transform_tree, 185 const TransformTree& transform_tree,
188 const EffectTree& effect_tree, 186 const EffectTree& effect_tree,
189 bool non_root_surfaces_enabled) { 187 bool non_root_surfaces_enabled) {
190 for (auto& layer : visible_layer_list) { 188 for (auto& layer : visible_layer_list) {
191 gfx::Size layer_bounds = layer->bounds(); 189 gfx::Size layer_bounds = layer->bounds();
192 190
193 const EffectNode* effect_node = 191 const EffectNode* effect_node =
194 effect_tree.Node(layer->effect_tree_index()); 192 effect_tree.Node(layer->effect_tree_index());
195 if (effect_node->data.has_copy_request && 193 if (effect_node->data.has_copy_request &&
196 effect_node->owner_id == layer->id()) { 194 effect_node->owner_id == layer->id()) {
197 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); 195 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
198 continue; 196 continue;
199 } 197 }
200 198
201 const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index()); 199 const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index());
202 const TransformNode* transform_node = 200 const TransformNode* transform_node =
203 transform_tree.Node(layer->transform_tree_index()); 201 transform_tree.Node(layer->transform_tree_index());
204 if (!non_root_surfaces_enabled) { 202 if (!non_root_surfaces_enabled) {
205 // When we only have a root surface, the clip node and the layer must 203 // When we only have a root surface, the clip node and the layer must
206 // necessarily have the same target (the root). 204 // necessarily have the same target (the root).
207 if (transform_node->data.ancestors_are_invertible) { 205 if (transform_node->data.ancestors_are_invertible) {
208 gfx::Rect combined_clip_rect_in_target_space = 206 gfx::RectF combined_clip_rect_in_target_space =
209 gfx::ToEnclosingRect(clip_node->data.combined_clip_in_target_space); 207 clip_node->data.combined_clip_in_target_space;
210 gfx::Transform target_to_content; 208 gfx::Transform target_to_content;
211 target_to_content.Translate(-layer->offset_to_transform_parent().x(), 209 target_to_content.Translate(-layer->offset_to_transform_parent().x(),
212 -layer->offset_to_transform_parent().y()); 210 -layer->offset_to_transform_parent().y());
213 target_to_content.PreconcatTransform(transform_node->data.from_screen); 211 target_to_content.PreconcatTransform(transform_node->data.from_screen);
214 212
215 gfx::Rect visible_rect = MathUtil::ProjectEnclosingClippedRect( 213 gfx::Rect visible_rect =
216 target_to_content, combined_clip_rect_in_target_space); 214 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
215 target_to_content, combined_clip_rect_in_target_space));
217 visible_rect.Intersect(gfx::Rect(layer_bounds)); 216 visible_rect.Intersect(gfx::Rect(layer_bounds));
218 layer->set_visible_layer_rect(visible_rect); 217 layer->set_visible_layer_rect(visible_rect);
219 } else { 218 } else {
220 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); 219 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
221 } 220 }
222 continue; 221 continue;
223 } 222 }
224 223
225 // When both the layer and the target are unclipped, the entire layer 224 // When both the layer and the target are unclipped, the entire layer
226 // content rect is visible. 225 // content rect is visible.
227 const bool fully_visible = !clip_node->data.layers_are_clipped && 226 const bool fully_visible = !clip_node->data.layers_are_clipped &&
228 !clip_node->data.target_is_clipped; 227 !clip_node->data.target_is_clipped;
229 228
230 if (fully_visible) { 229 if (fully_visible) {
231 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); 230 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
232 continue; 231 continue;
233 } 232 }
234 233
235 int target_node_id = transform_node->data.content_target_id; 234 int target_node_id = transform_node->data.content_target_id;
236 235
237 // The clip node stores clip rect in its target space. If required, 236 // The clip node stores clip rect in its target space. If required,
238 // this clip rect should be mapped to the current layer's target space. 237 // this clip rect should be mapped to the current layer's target space.
239 gfx::Rect combined_clip_rect_in_target_space; 238 gfx::RectF combined_clip_rect_in_target_space;
240 239
241 if (clip_node->data.target_id != target_node_id) { 240 if (clip_node->data.target_id != target_node_id) {
242 // In this case, layer has a clip parent or scroll parent (or shares the 241 // In this case, layer has a clip parent or scroll parent (or shares the
243 // target with an ancestor layer that has clip parent) and the clip 242 // target with an ancestor layer that has clip parent) and the clip
244 // parent's target is different from the layer's target. As the layer's 243 // parent's target is different from the layer's target. As the layer's
245 // target has unclippped descendants, it is unclippped. 244 // target has unclippped descendants, it is unclippped.
246 if (!clip_node->data.layers_are_clipped) { 245 if (!clip_node->data.layers_are_clipped) {
247 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); 246 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
248 continue; 247 continue;
249 } 248 }
250 249
251 // We use the clip node's clip_in_target_space (and not 250 // We use the clip node's clip_in_target_space (and not
252 // combined_clip_in_target_space) here because we want to clip 251 // combined_clip_in_target_space) here because we want to clip
253 // with respect to clip parent's local clip and not its combined clip as 252 // with respect to clip parent's local clip and not its combined clip as
254 // the combined clip has even the clip parent's target's clip baked into 253 // the combined clip has even the clip parent's target's clip baked into
255 // it and as our target is different, we don't want to use it in our 254 // it and as our target is different, we don't want to use it in our
256 // visible rect computation. 255 // visible rect computation.
257 if (!GetLayerClipRect(layer, clip_node, transform_tree, target_node_id, 256 if (!GetLayerClipRect(layer, clip_node, transform_tree, target_node_id,
258 &combined_clip_rect_in_target_space)) { 257 &combined_clip_rect_in_target_space)) {
259 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); 258 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
260 continue; 259 continue;
261 } 260 }
262 } else { 261 } else {
263 if (clip_node->data.target_is_clipped) { 262 if (clip_node->data.target_is_clipped) {
264 combined_clip_rect_in_target_space = 263 combined_clip_rect_in_target_space =
265 gfx::ToEnclosingRect(clip_node->data.combined_clip_in_target_space); 264 clip_node->data.combined_clip_in_target_space;
266 } else { 265 } else {
267 combined_clip_rect_in_target_space = 266 combined_clip_rect_in_target_space =
268 gfx::ToEnclosingRect(clip_node->data.clip_in_target_space); 267 clip_node->data.clip_in_target_space;
269 } 268 }
270 } 269 }
271 270
272 // The clip rect should be intersected with layer rect in target space. 271 // The clip rect should be intersected with layer rect in target space.
273 gfx::Transform content_to_target = transform_node->data.to_target; 272 gfx::Transform content_to_target = transform_node->data.to_target;
274 content_to_target.Translate(layer->offset_to_transform_parent().x(), 273 content_to_target.Translate(layer->offset_to_transform_parent().x(),
275 layer->offset_to_transform_parent().y()); 274 layer->offset_to_transform_parent().y());
276 gfx::Rect layer_content_rect = gfx::Rect(layer_bounds); 275 gfx::Rect layer_content_rect = gfx::Rect(layer_bounds);
277 gfx::Rect layer_content_bounds_in_target_space = 276 gfx::RectF layer_content_bounds_in_target_space = MathUtil::MapClippedRect(
278 MathUtil::MapEnclosingClippedRect(content_to_target, 277 content_to_target, gfx::RectF(layer_content_rect));
279 layer_content_rect); 278 // If the layer is fully contained within the clip, treat it as fully
279 // visible.
280 if (!layer_content_bounds_in_target_space.IsEmpty() &&
281 combined_clip_rect_in_target_space.Contains(
282 layer_content_bounds_in_target_space)) {
283 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
284 continue;
285 }
286
280 combined_clip_rect_in_target_space.Intersect( 287 combined_clip_rect_in_target_space.Intersect(
281 layer_content_bounds_in_target_space); 288 layer_content_bounds_in_target_space);
282 if (combined_clip_rect_in_target_space.IsEmpty()) { 289 if (combined_clip_rect_in_target_space.IsEmpty()) {
283 layer->set_visible_layer_rect(gfx::Rect()); 290 layer->set_visible_layer_rect(gfx::Rect());
284 continue; 291 continue;
285 } 292 }
286 293
287 // If the layer is fully contained within the clip, treat it as fully
288 // visible. Since clip_rect_in_target_space has already been intersected
289 // with layer_content_bounds_in_target_space, the layer is fully contained
290 // within the clip iff these rects are equal.
291 if (combined_clip_rect_in_target_space ==
292 layer_content_bounds_in_target_space) {
293 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
294 continue;
295 }
296
297 gfx::Transform target_to_layer; 294 gfx::Transform target_to_layer;
298 if (transform_node->data.ancestors_are_invertible) { 295 if (transform_node->data.ancestors_are_invertible) {
299 target_to_layer = transform_node->data.from_target; 296 target_to_layer = transform_node->data.from_target;
300 } else { 297 } else {
301 if (!transform_tree.ComputeTransformWithSourceSublayerScale( 298 if (!transform_tree.ComputeTransformWithSourceSublayerScale(
302 target_node_id, transform_node->id, &target_to_layer)) { 299 target_node_id, transform_node->id, &target_to_layer)) {
303 // An animated singular transform may become non-singular during the 300 // An animated singular transform may become non-singular during the
304 // animation, so we still need to compute a visible rect. In this 301 // animation, so we still need to compute a visible rect. In this
305 // situation, we treat the entire layer as visible. 302 // situation, we treat the entire layer as visible.
306 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); 303 layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
307 continue; 304 continue;
308 } 305 }
309 } 306 }
310 307
311 gfx::Transform target_to_content; 308 gfx::Transform target_to_content;
312 target_to_content.Translate(-layer->offset_to_transform_parent().x(), 309 target_to_content.Translate(-layer->offset_to_transform_parent().x(),
313 -layer->offset_to_transform_parent().y()); 310 -layer->offset_to_transform_parent().y());
314 target_to_content.PreconcatTransform(target_to_layer); 311 target_to_content.PreconcatTransform(target_to_layer);
315 312
316 gfx::Rect visible_rect = MathUtil::ProjectEnclosingClippedRect( 313 gfx::Rect visible_rect = gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
317 target_to_content, combined_clip_rect_in_target_space); 314 target_to_content, combined_clip_rect_in_target_space));
318 visible_rect.Intersect(gfx::Rect(layer_bounds)); 315 visible_rect.Intersect(gfx::Rect(layer_bounds));
319 layer->set_visible_layer_rect(visible_rect); 316 layer->set_visible_layer_rect(visible_rect);
320 } 317 }
321 } 318 }
322 319
323 static bool HasSingularTransform(int transform_tree_index, 320 static bool HasSingularTransform(int transform_tree_index,
324 const TransformTree& tree) { 321 const TransformTree& tree) {
325 const TransformNode* node = tree.Node(transform_tree_index); 322 const TransformNode* node = tree.Node(transform_tree_index);
326 return !node->data.is_invertible || !node->data.ancestors_are_invertible; 323 return !node->data.is_invertible || !node->data.ancestors_are_invertible;
327 } 324 }
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 void UpdateElasticOverscroll(PropertyTrees* property_trees, 1305 void UpdateElasticOverscroll(PropertyTrees* property_trees,
1309 const Layer* overscroll_elasticity_layer, 1306 const Layer* overscroll_elasticity_layer,
1310 const gfx::Vector2dF& elastic_overscroll) { 1307 const gfx::Vector2dF& elastic_overscroll) {
1311 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, 1308 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer,
1312 elastic_overscroll); 1309 elastic_overscroll);
1313 } 1310 }
1314 1311
1315 } // namespace draw_property_utils 1312 } // namespace draw_property_utils
1316 1313
1317 } // namespace cc 1314 } // 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