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 17 matching lines...) Expand all Loading... |
28 namespace { | 28 namespace { |
29 | 29 |
30 static bool IsRootLayer(const Layer* layer) { | 30 static bool IsRootLayer(const Layer* layer) { |
31 return !layer->parent(); | 31 return !layer->parent(); |
32 } | 32 } |
33 | 33 |
34 static bool IsRootLayer(const LayerImpl* layer) { | 34 static bool IsRootLayer(const LayerImpl* layer) { |
35 return layer->layer_tree_impl()->IsRootLayer(layer); | 35 return layer->layer_tree_impl()->IsRootLayer(layer); |
36 } | 36 } |
37 | 37 |
38 static const EffectNode* ContentsTargetEffectNode( | |
39 const int effect_tree_index, | |
40 const EffectTree& effect_tree) { | |
41 const EffectNode* effect_node = effect_tree.Node(effect_tree_index); | |
42 return effect_tree.GetRenderSurface(effect_tree_index) | |
43 ? effect_node | |
44 : effect_tree.Node(effect_node->target_id); | |
45 } | |
46 | |
47 static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, | 38 static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, |
48 int source_effect_id, | 39 int source_effect_id, |
49 int dest_effect_id, | 40 int dest_effect_id, |
50 gfx::RectF clip_in_source_space, | 41 gfx::RectF clip_in_source_space, |
51 gfx::RectF* clip_in_dest_space) { | 42 gfx::RectF* clip_in_dest_space) { |
52 const EffectNode* source_effect_node = | 43 const EffectNode* source_effect_node = |
53 property_trees->effect_tree.Node(source_effect_id); | 44 property_trees->effect_tree.Node(source_effect_id); |
54 int source_transform_id = source_effect_node->transform_id; | 45 int source_transform_id = source_effect_node->transform_id; |
55 const EffectNode* dest_effect_node = | 46 const EffectNode* dest_effect_node = |
56 property_trees->effect_tree.Node(dest_effect_id); | 47 property_trees->effect_tree.Node(dest_effect_id); |
(...skipping 14 matching lines...) Expand all Loading... |
71 PostConcatSurfaceContentsScale(dest_effect_node, &source_to_dest); | 62 PostConcatSurfaceContentsScale(dest_effect_node, &source_to_dest); |
72 *clip_in_dest_space = | 63 *clip_in_dest_space = |
73 MathUtil::ProjectClippedRect(source_to_dest, clip_in_source_space); | 64 MathUtil::ProjectClippedRect(source_to_dest, clip_in_source_space); |
74 } else { | 65 } else { |
75 return false; | 66 return false; |
76 } | 67 } |
77 } | 68 } |
78 return true; | 69 return true; |
79 } | 70 } |
80 | 71 |
81 bool ComputeClipRectInTargetSpace(const LayerImpl* layer, | |
82 const ClipNode* clip_node, | |
83 const PropertyTrees* property_trees, | |
84 int target_node_id, | |
85 bool for_visible_rect_calculation, | |
86 gfx::RectF* clip_rect_in_target_space) { | |
87 DCHECK(layer->clip_tree_index() == clip_node->id); | |
88 DCHECK(clip_node->target_transform_id != target_node_id); | |
89 | |
90 const EffectTree& effect_tree = property_trees->effect_tree; | |
91 const EffectNode* target_effect_node = | |
92 ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree); | |
93 gfx::Transform clip_to_target; | |
94 // We use the local clip for clip rect calculation and combined clip for | |
95 // visible rect calculation. | |
96 gfx::RectF clip_from_clip_node = | |
97 for_visible_rect_calculation ? clip_node->combined_clip_in_target_space | |
98 : clip_node->clip_in_target_space; | |
99 | |
100 return ConvertRectBetweenSurfaceSpaces( | |
101 property_trees, clip_node->target_effect_id, target_effect_node->id, | |
102 clip_from_clip_node, clip_rect_in_target_space); | |
103 } | |
104 | |
105 struct ConditionalClip { | |
106 bool is_clipped; | |
107 gfx::RectF clip_rect; | |
108 }; | |
109 | |
110 static ConditionalClip ComputeTargetRectInLocalSpace( | 72 static ConditionalClip ComputeTargetRectInLocalSpace( |
111 gfx::RectF rect, | 73 gfx::RectF rect, |
112 const PropertyTrees* property_trees, | 74 const PropertyTrees* property_trees, |
113 int target_transform_id, | 75 int target_transform_id, |
114 int local_transform_id, | 76 int local_transform_id, |
115 const int target_effect_id) { | 77 const int target_effect_id) { |
116 gfx::Transform target_to_local; | 78 gfx::Transform target_to_local; |
117 bool success = property_trees->GetFromTarget( | 79 bool success = property_trees->GetFromTarget( |
118 local_transform_id, target_effect_id, &target_to_local); | 80 local_transform_id, target_effect_id, &target_to_local); |
| 81 // If transform is not invertible, cannot apply clip. |
119 if (!success) | 82 if (!success) |
120 // If transform is not invertible, cannot apply clip. | |
121 return ConditionalClip{false, gfx::RectF()}; | 83 return ConditionalClip{false, gfx::RectF()}; |
122 | 84 |
123 if (target_transform_id > local_transform_id) | 85 if (target_transform_id > local_transform_id) |
124 return ConditionalClip{true, // is_clipped. | 86 return ConditionalClip{true, // is_clipped. |
125 MathUtil::MapClippedRect(target_to_local, rect)}; | 87 MathUtil::MapClippedRect(target_to_local, rect)}; |
126 | 88 |
127 return ConditionalClip{true, // is_clipped. | 89 return ConditionalClip{true, // is_clipped. |
128 MathUtil::ProjectClippedRect(target_to_local, rect)}; | 90 MathUtil::ProjectClippedRect(target_to_local, rect)}; |
129 } | 91 } |
130 | 92 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 | 174 |
213 // Put the expanded clip back into the original target space. | 175 // Put the expanded clip back into the original target space. |
214 success = ConvertRectBetweenSurfaceSpaces( | 176 success = ConvertRectBetweenSurfaceSpaces( |
215 property_trees, expanding_effect_node->id, target_id, | 177 property_trees, expanding_effect_node->id, target_id, |
216 expanded_clip_in_expanding_space, accumulated_clip); | 178 expanded_clip_in_expanding_space, accumulated_clip); |
217 // If transform is not invertible, no clip will be applied. | 179 // If transform is not invertible, no clip will be applied. |
218 if (!success) | 180 if (!success) |
219 return false; | 181 return false; |
220 return true; | 182 return true; |
221 } | 183 } |
222 case ClipNode::ClipType::NONE: | |
223 return true; | |
224 } | 184 } |
225 NOTREACHED(); | 185 NOTREACHED(); |
226 return true; | 186 return true; |
227 } | 187 } |
228 | 188 |
229 static ConditionalClip ComputeAccumulatedClip( | 189 static ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees, |
230 const PropertyTrees* property_trees, | 190 bool include_expanding_clips, |
231 bool include_viewport_clip, | 191 int local_clip_id, |
232 bool include_expanding_clips, | 192 int target_id) { |
233 int local_clip_id, | 193 ClipRectData* cached_data = |
234 int target_id) { | 194 property_trees->FetchClipRectFromCache(local_clip_id, target_id); |
235 DCHECK(!include_viewport_clip || | 195 if (cached_data->target_id != EffectTree::kInvalidNodeId) { |
236 target_id == EffectTree::kContentsRootNodeId); | 196 // Cache hit |
| 197 return cached_data->clip; |
| 198 } |
| 199 cached_data->target_id = target_id; |
| 200 |
237 const ClipTree& clip_tree = property_trees->clip_tree; | 201 const ClipTree& clip_tree = property_trees->clip_tree; |
| 202 const ClipNode* clip_node = clip_tree.Node(local_clip_id); |
238 const EffectTree& effect_tree = property_trees->effect_tree; | 203 const EffectTree& effect_tree = property_trees->effect_tree; |
239 | |
240 const ClipNode* clip_node = clip_tree.Node(local_clip_id); | |
241 const EffectNode* target_node = effect_tree.Node(target_id); | 204 const EffectNode* target_node = effect_tree.Node(target_id); |
242 int target_transform_id = target_node->transform_id; | 205 int target_transform_id = target_node->transform_id; |
243 | 206 |
| 207 bool cache_hit = false; |
| 208 ConditionalClip cached_clip = ConditionalClip{false, gfx::RectF()}; |
| 209 ConditionalClip unclipped = ConditionalClip{false, gfx::RectF()}; |
| 210 |
244 // Collect all the clips that need to be accumulated. | 211 // Collect all the clips that need to be accumulated. |
245 std::stack<const ClipNode*> parent_chain; | 212 std::stack<const ClipNode*, std::vector<const ClipNode*>> parent_chain; |
246 | 213 |
247 // If target is not direct ancestor of clip, this will find least common | 214 // If target is not direct ancestor of clip, this will find least common |
248 // ancestor between the target and the clip. | 215 // ancestor between the target and the clip. |
249 while (target_node->clip_id > clip_node->id || | 216 while (target_node->clip_id > clip_node->id || |
250 target_node->has_unclipped_descendants) { | 217 target_node->has_unclipped_descendants) { |
251 target_node = effect_tree.Node(target_node->target_id); | 218 target_node = effect_tree.Node(target_node->target_id); |
252 } | 219 } |
253 | 220 |
254 // Collect clip nodes up to the least common ancestor. | 221 // Collect clip nodes up to the least common ancestor or till we get a cache |
| 222 // hit. |
255 while (target_node->clip_id < clip_node->id) { | 223 while (target_node->clip_id < clip_node->id) { |
| 224 if (parent_chain.size() > 0) { |
| 225 // Search the cache. |
| 226 for (auto& data : clip_node->cached_clip_rects) { |
| 227 if (data.target_id == target_id) { |
| 228 cache_hit = true; |
| 229 cached_clip = data.clip; |
| 230 } |
| 231 } |
| 232 } |
256 parent_chain.push(clip_node); | 233 parent_chain.push(clip_node); |
257 clip_node = clip_tree.parent(clip_node); | 234 clip_node = clip_tree.parent(clip_node); |
258 } | 235 } |
259 DCHECK_EQ(target_node->clip_id, clip_node->id); | |
260 | 236 |
261 if (!include_viewport_clip && parent_chain.size() == 0) { | 237 if (parent_chain.size() == 0) { |
262 // There aren't any clips to apply. | 238 // No accumulated clip nodes. |
263 return ConditionalClip{false, gfx::RectF()}; | 239 cached_data->clip = unclipped; |
| 240 return unclipped; |
264 } | 241 } |
265 | 242 |
266 if (!include_viewport_clip) { | 243 clip_node = parent_chain.top(); |
267 clip_node = parent_chain.top(); | 244 parent_chain.pop(); |
268 parent_chain.pop(); | 245 |
| 246 gfx::RectF accumulated_clip; |
| 247 if (cache_hit && cached_clip.is_clipped) { |
| 248 // Apply the first clip in parent_chain to the cached clip. |
| 249 accumulated_clip = cached_clip.clip_rect; |
| 250 bool success = ApplyClipNodeToAccumulatedClip( |
| 251 property_trees, include_expanding_clips, target_id, target_transform_id, |
| 252 clip_node, &accumulated_clip); |
| 253 if (!success) { |
| 254 // Singular transform |
| 255 cached_data->clip = unclipped; |
| 256 return unclipped; |
| 257 } |
| 258 } else { |
| 259 // No cache hit or the cached clip has no clip to apply. We need to find |
| 260 // the first clip that applies clip as there is no clip to expand. |
| 261 while (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP && |
| 262 parent_chain.size() > 0) { |
| 263 clip_node = parent_chain.top(); |
| 264 parent_chain.pop(); |
| 265 } |
| 266 |
| 267 if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) { |
| 268 // No clip to apply. |
| 269 cached_data->clip = unclipped; |
| 270 return unclipped; |
| 271 } |
| 272 ConditionalClip current_clip = ComputeCurrentClip( |
| 273 clip_node, property_trees, target_transform_id, target_id); |
| 274 if (!current_clip.is_clipped) { |
| 275 // Singular transform |
| 276 cached_data->clip = unclipped; |
| 277 return unclipped; |
| 278 } |
| 279 accumulated_clip = current_clip.clip_rect; |
269 } | 280 } |
270 | 281 |
271 // Find the first clip in the chain that we need to apply. | 282 // Apply remaining clips |
272 while (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP && | |
273 parent_chain.size() > 0) { | |
274 clip_node = parent_chain.top(); | |
275 parent_chain.pop(); | |
276 } | |
277 | |
278 if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) { | |
279 // No clip node applying clip in between. | |
280 return ConditionalClip{false, gfx::RectF()}; | |
281 } | |
282 | |
283 ConditionalClip current_clip = ComputeCurrentClip( | |
284 clip_node, property_trees, target_transform_id, target_id); | |
285 | |
286 // If transform is not invertible, no clip will be applied. | |
287 if (!current_clip.is_clipped) | |
288 return ConditionalClip{false, gfx::RectF()}; | |
289 gfx::RectF accumulated_clip = current_clip.clip_rect; | |
290 | |
291 while (parent_chain.size() > 0) { | 283 while (parent_chain.size() > 0) { |
292 clip_node = parent_chain.top(); | 284 clip_node = parent_chain.top(); |
293 parent_chain.pop(); | 285 parent_chain.pop(); |
294 bool success = ApplyClipNodeToAccumulatedClip( | 286 bool success = ApplyClipNodeToAccumulatedClip( |
295 property_trees, include_expanding_clips, target_id, target_transform_id, | 287 property_trees, include_expanding_clips, target_id, target_transform_id, |
296 clip_node, &accumulated_clip); | 288 clip_node, &accumulated_clip); |
297 | 289 if (!success) { |
298 // Failure to apply the clip means we encountered an uninvertible transform, | 290 // Singular transform |
299 // so no clip will be applied. | 291 cached_data->clip = unclipped; |
300 if (!success) | 292 return unclipped; |
301 return ConditionalClip{false /* is_clipped */, gfx::RectF()}; | 293 } |
302 } | 294 } |
303 | 295 |
304 return ConditionalClip{true /* is_clipped */, accumulated_clip.IsEmpty() | 296 ConditionalClip clip = ConditionalClip{ |
305 ? gfx::RectF() | 297 true /* is_clipped */, |
306 : accumulated_clip}; | 298 accumulated_clip.IsEmpty() ? gfx::RectF() : accumulated_clip}; |
307 } | 299 cached_data->clip = clip; |
308 | 300 return clip; |
309 static gfx::RectF ComputeAccumulatedClipInRootSpaceForVisibleRect( | |
310 const PropertyTrees* property_trees, | |
311 int local_clip_id) { | |
312 const int root_effect_id = EffectTree::kContentsRootNodeId; | |
313 bool include_viewport_clip = true; | |
314 bool include_expanding_clips = true; | |
315 ConditionalClip accumulated_clip = ComputeAccumulatedClip( | |
316 property_trees, include_viewport_clip, include_expanding_clips, | |
317 local_clip_id, root_effect_id); | |
318 DCHECK(accumulated_clip.is_clipped); | |
319 return accumulated_clip.clip_rect; | |
320 } | |
321 | |
322 void CalculateClipRects(const std::vector<LayerImpl*>& visible_layer_list, | |
323 const PropertyTrees* property_trees, | |
324 bool non_root_surfaces_enabled) { | |
325 const ClipTree& clip_tree = property_trees->clip_tree; | |
326 for (auto* layer : visible_layer_list) { | |
327 const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index()); | |
328 bool layer_needs_clip_rect = | |
329 non_root_surfaces_enabled | |
330 ? clip_node->layers_are_clipped | |
331 : clip_node->layers_are_clipped_when_surfaces_disabled; | |
332 if (!layer_needs_clip_rect) { | |
333 layer->set_clip_rect(gfx::Rect()); | |
334 continue; | |
335 } | |
336 if (!non_root_surfaces_enabled) { | |
337 layer->set_clip_rect( | |
338 gfx::ToEnclosingRect(clip_node->clip_in_target_space)); | |
339 continue; | |
340 } | |
341 | |
342 const TransformTree& transform_tree = property_trees->transform_tree; | |
343 const TransformNode* transform_node = | |
344 transform_tree.Node(layer->transform_tree_index()); | |
345 int target_node_id = transform_tree.ContentTargetId(transform_node->id); | |
346 | |
347 // The clip node stores clip rect in its target space. | |
348 gfx::RectF clip_rect_in_target_space = clip_node->clip_in_target_space; | |
349 | |
350 // If required, this clip rect should be mapped to the current layer's | |
351 // target space. | |
352 if (clip_node->target_transform_id != target_node_id) { | |
353 // In this case, layer has a clip parent or scroll parent (or shares the | |
354 // target with an ancestor layer that has clip parent) and the clip | |
355 // parent's target is different from the layer's target. As the layer's | |
356 // target has unclippped descendants, it is unclippped. | |
357 if (!clip_node->layers_are_clipped) | |
358 continue; | |
359 | |
360 // Compute the clip rect in target space and store it. | |
361 bool for_visible_rect_calculation = false; | |
362 if (!ComputeClipRectInTargetSpace( | |
363 layer, clip_node, property_trees, target_node_id, | |
364 for_visible_rect_calculation, &clip_rect_in_target_space)) | |
365 continue; | |
366 } | |
367 | |
368 if (!clip_rect_in_target_space.IsEmpty()) { | |
369 layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space)); | |
370 } else { | |
371 layer->set_clip_rect(gfx::Rect()); | |
372 } | |
373 } | |
374 } | |
375 | |
376 void CalculateVisibleRects(const LayerImplList& visible_layer_list, | |
377 const PropertyTrees* property_trees, | |
378 bool non_root_surfaces_enabled) { | |
379 const EffectTree& effect_tree = property_trees->effect_tree; | |
380 const TransformTree& transform_tree = property_trees->transform_tree; | |
381 const ClipTree& clip_tree = property_trees->clip_tree; | |
382 for (auto* layer : visible_layer_list) { | |
383 gfx::Size layer_bounds = layer->bounds(); | |
384 | |
385 int effect_ancestor_with_copy_request = | |
386 effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index()); | |
387 if (effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId) { | |
388 // Non root copy request. | |
389 bool include_viewport_clip = false; | |
390 bool include_expanding_clips = true; | |
391 ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( | |
392 property_trees, include_viewport_clip, include_expanding_clips, | |
393 layer->clip_tree_index(), effect_ancestor_with_copy_request); | |
394 if (!accumulated_clip_rect.is_clipped) { | |
395 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
396 continue; | |
397 } | |
398 | |
399 gfx::RectF accumulated_clip_in_copy_request_space = | |
400 accumulated_clip_rect.clip_rect; | |
401 | |
402 const EffectNode* copy_request_effect_node = | |
403 effect_tree.Node(effect_ancestor_with_copy_request); | |
404 ConditionalClip clip_in_layer_space = ComputeTargetRectInLocalSpace( | |
405 accumulated_clip_in_copy_request_space, property_trees, | |
406 copy_request_effect_node->transform_id, layer->transform_tree_index(), | |
407 copy_request_effect_node->id); | |
408 | |
409 if (clip_in_layer_space.is_clipped) { | |
410 gfx::RectF clip_rect = clip_in_layer_space.clip_rect; | |
411 clip_rect.Offset(-layer->offset_to_transform_parent()); | |
412 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect); | |
413 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
414 layer->set_visible_layer_rect(visible_rect); | |
415 } else { | |
416 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
417 } | |
418 continue; | |
419 } | |
420 | |
421 const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index()); | |
422 const TransformNode* transform_node = | |
423 transform_tree.Node(layer->transform_tree_index()); | |
424 if (!non_root_surfaces_enabled) { | |
425 // When we only have a root surface, the clip node and the layer must | |
426 // necessarily have the same target (the root). | |
427 if (transform_node->ancestors_are_invertible) { | |
428 gfx::RectF combined_clip_rect_in_target_space = | |
429 clip_node->combined_clip_in_target_space; | |
430 gfx::Transform target_to_content; | |
431 target_to_content.Translate(-layer->offset_to_transform_parent().x(), | |
432 -layer->offset_to_transform_parent().y()); | |
433 target_to_content.PreconcatTransform( | |
434 transform_tree.FromScreen(transform_node->id)); | |
435 | |
436 gfx::Rect visible_rect = | |
437 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | |
438 target_to_content, combined_clip_rect_in_target_space)); | |
439 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
440 layer->set_visible_layer_rect(visible_rect); | |
441 } else { | |
442 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
443 } | |
444 continue; | |
445 } | |
446 | |
447 // When both the layer and the target are unclipped, we only have to apply | |
448 // the viewport clip. | |
449 const bool fully_visible = | |
450 !clip_node->layers_are_clipped && | |
451 !effect_tree.Node(clip_node->target_effect_id)->surface_is_clipped; | |
452 | |
453 if (fully_visible) { | |
454 if (!transform_node->ancestors_are_invertible) { | |
455 // An animated singular transform may become non-singular during the | |
456 // animation, so we still need to compute a visible rect. In this | |
457 // situation, we treat the entire layer as visible. | |
458 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
459 } else { | |
460 gfx::Transform from_screen; | |
461 from_screen.Translate(-layer->offset_to_transform_parent().x(), | |
462 -layer->offset_to_transform_parent().y()); | |
463 from_screen.PreconcatTransform( | |
464 property_trees->transform_tree.FromScreen(transform_node->id)); | |
465 gfx::Rect visible_rect = | |
466 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | |
467 from_screen, property_trees->clip_tree.ViewportClip())); | |
468 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
469 layer->set_visible_layer_rect(visible_rect); | |
470 } | |
471 continue; | |
472 } | |
473 | |
474 int target_node_id = transform_tree.ContentTargetId(transform_node->id); | |
475 | |
476 // The clip node stores clip rect in its target space. If required, | |
477 // this clip rect should be mapped to the current layer's target space. | |
478 gfx::RectF combined_clip_rect_in_target_space; | |
479 | |
480 if (clip_node->target_transform_id != target_node_id) { | |
481 // In this case, layer has a clip parent or scroll parent (or shares the | |
482 // target with an ancestor layer that has clip parent) and the clip | |
483 // parent's target is different from the layer's target. As the layer's | |
484 // target has unclippped descendants, it is unclippped. | |
485 if (!clip_node->layers_are_clipped) { | |
486 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
487 continue; | |
488 } | |
489 | |
490 bool for_visible_rect_calculation = true; | |
491 if (!ComputeClipRectInTargetSpace(layer, clip_node, property_trees, | |
492 target_node_id, | |
493 for_visible_rect_calculation, | |
494 &combined_clip_rect_in_target_space)) { | |
495 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
496 continue; | |
497 } | |
498 } else { | |
499 combined_clip_rect_in_target_space = | |
500 clip_node->combined_clip_in_target_space; | |
501 } | |
502 | |
503 // The clip rect should be intersected with layer rect in target space. | |
504 gfx::Transform content_to_target; | |
505 property_trees->GetToTarget(transform_node->id, | |
506 layer->render_target_effect_tree_index(), | |
507 &content_to_target); | |
508 content_to_target.Translate(layer->offset_to_transform_parent().x(), | |
509 layer->offset_to_transform_parent().y()); | |
510 gfx::Rect layer_content_rect = gfx::Rect(layer_bounds); | |
511 gfx::RectF layer_content_bounds_in_target_space = MathUtil::MapClippedRect( | |
512 content_to_target, gfx::RectF(layer_content_rect)); | |
513 // If the layer is fully contained within the clip, treat it as fully | |
514 // visible. | |
515 if (!layer_content_bounds_in_target_space.IsEmpty() && | |
516 combined_clip_rect_in_target_space.Contains( | |
517 layer_content_bounds_in_target_space)) { | |
518 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
519 continue; | |
520 } | |
521 | |
522 combined_clip_rect_in_target_space.Intersect( | |
523 layer_content_bounds_in_target_space); | |
524 if (combined_clip_rect_in_target_space.IsEmpty()) { | |
525 layer->set_visible_layer_rect(gfx::Rect()); | |
526 continue; | |
527 } | |
528 | |
529 gfx::Transform target_to_layer; | |
530 const EffectNode* target_effect_node = | |
531 ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree); | |
532 bool success = property_trees->GetFromTarget( | |
533 transform_node->id, target_effect_node->id, &target_to_layer); | |
534 if (!success) { | |
535 // An animated singular transform may become non-singular during the | |
536 // animation, so we still need to compute a visible rect. In this | |
537 // situation, we treat the entire layer as visible. | |
538 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
539 continue; | |
540 } | |
541 gfx::Transform target_to_content; | |
542 target_to_content.Translate(-layer->offset_to_transform_parent().x(), | |
543 -layer->offset_to_transform_parent().y()); | |
544 target_to_content.PreconcatTransform(target_to_layer); | |
545 | |
546 gfx::Rect visible_rect = gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | |
547 target_to_content, combined_clip_rect_in_target_space)); | |
548 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
549 layer->set_visible_layer_rect(visible_rect); | |
550 } | |
551 } | 301 } |
552 | 302 |
553 static bool HasSingularTransform(int transform_tree_index, | 303 static bool HasSingularTransform(int transform_tree_index, |
554 const TransformTree& tree) { | 304 const TransformTree& tree) { |
555 const TransformNode* node = tree.Node(transform_tree_index); | 305 const TransformNode* node = tree.Node(transform_tree_index); |
556 return !node->is_invertible || !node->ancestors_are_invertible; | 306 return !node->is_invertible || !node->ancestors_are_invertible; |
557 } | 307 } |
558 | 308 |
559 template <typename LayerType> | 309 template <typename LayerType> |
560 static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, | 310 static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 // backface is not visible. | 397 // backface is not visible. |
648 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && | 398 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && |
649 !HasSingularTransform(backface_transform_id, tree) && | 399 !HasSingularTransform(backface_transform_id, tree) && |
650 IsLayerBackFaceVisible(layer, backface_transform_id, property_trees)) | 400 IsLayerBackFaceVisible(layer, backface_transform_id, property_trees)) |
651 return false; | 401 return false; |
652 } | 402 } |
653 | 403 |
654 return true; | 404 return true; |
655 } | 405 } |
656 | 406 |
657 void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, | |
658 const PropertyTrees* property_trees, | |
659 std::vector<LayerImpl*>* visible_layer_list) { | |
660 const TransformTree& transform_tree = property_trees->transform_tree; | |
661 const EffectTree& effect_tree = property_trees->effect_tree; | |
662 | 407 |
663 for (auto* layer_impl : *layer_tree_impl) { | |
664 if (!IsRootLayer(layer_impl) && | |
665 LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree)) | |
666 continue; | |
667 | |
668 bool layer_is_drawn = | |
669 effect_tree.Node(layer_impl->effect_tree_index())->is_drawn; | |
670 | |
671 if (LayerNeedsUpdate(layer_impl, layer_is_drawn, property_trees)) | |
672 visible_layer_list->push_back(layer_impl); | |
673 } | |
674 } | |
675 | 408 |
676 } // namespace | 409 } // namespace |
677 | 410 |
678 template <typename LayerType> | 411 template <typename LayerType> |
679 static inline bool LayerShouldBeSkippedInternal( | 412 static inline bool LayerShouldBeSkippedInternal( |
680 LayerType* layer, | 413 LayerType* layer, |
681 const TransformTree& transform_tree, | 414 const TransformTree& transform_tree, |
682 const EffectTree& effect_tree) { | 415 const EffectTree& effect_tree) { |
683 const TransformNode* transform_node = | 416 const TransformNode* transform_node = |
684 transform_tree.Node(layer->transform_tree_index()); | 417 transform_tree.Node(layer->transform_tree_index()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 update_layer_list->push_back(layer); | 457 update_layer_list->push_back(layer); |
725 } | 458 } |
726 | 459 |
727 // Append mask layers to the update layer list. They don't have valid | 460 // Append mask layers to the update layer list. They don't have valid |
728 // visible rects, so need to get added after the above calculation. | 461 // visible rects, so need to get added after the above calculation. |
729 if (Layer* mask_layer = layer->mask_layer()) | 462 if (Layer* mask_layer = layer->mask_layer()) |
730 update_layer_list->push_back(mask_layer); | 463 update_layer_list->push_back(mask_layer); |
731 } | 464 } |
732 } | 465 } |
733 | 466 |
734 static void ResetIfHasNanCoordinate(gfx::RectF* rect) { | 467 void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, |
735 if (std::isnan(rect->x()) || std::isnan(rect->y()) || | 468 const PropertyTrees* property_trees, |
736 std::isnan(rect->right()) || std::isnan(rect->bottom())) | 469 std::vector<LayerImpl*>* visible_layer_list) { |
737 *rect = gfx::RectF(); | 470 const TransformTree& transform_tree = property_trees->transform_tree; |
| 471 const EffectTree& effect_tree = property_trees->effect_tree; |
| 472 |
| 473 for (auto* layer_impl : *layer_tree_impl) { |
| 474 if (!IsRootLayer(layer_impl) && |
| 475 LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree)) |
| 476 continue; |
| 477 |
| 478 bool layer_is_drawn = |
| 479 effect_tree.Node(layer_impl->effect_tree_index())->is_drawn; |
| 480 |
| 481 if (LayerNeedsUpdate(layer_impl, layer_is_drawn, property_trees)) |
| 482 visible_layer_list->push_back(layer_impl); |
| 483 } |
738 } | 484 } |
739 | 485 |
740 void PostConcatSurfaceContentsScale(const EffectNode* effect_node, | 486 void PostConcatSurfaceContentsScale(const EffectNode* effect_node, |
741 gfx::Transform* transform) { | 487 gfx::Transform* transform) { |
742 if (!effect_node) { | 488 if (!effect_node) { |
743 // This can happen when PaintArtifactCompositor builds property trees as it | 489 // This can happen when PaintArtifactCompositor builds property trees as it |
744 // doesn't set effect ids on clip nodes. | 490 // doesn't set effect ids on clip nodes. |
745 return; | 491 return; |
746 } | 492 } |
747 DCHECK(effect_node->has_render_surface); | 493 DCHECK(effect_node->has_render_surface); |
748 transform->matrix().postScale(effect_node->surface_contents_scale.x(), | 494 transform->matrix().postScale(effect_node->surface_contents_scale.x(), |
749 effect_node->surface_contents_scale.y(), 1.f); | 495 effect_node->surface_contents_scale.y(), 1.f); |
750 } | 496 } |
751 | 497 |
752 void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, | 498 void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, |
753 gfx::Transform* transform) { | 499 gfx::Transform* transform) { |
754 DCHECK(effect_node->has_render_surface); | 500 DCHECK(effect_node->has_render_surface); |
755 if (effect_node->surface_contents_scale.x() != 0.0 && | 501 if (effect_node->surface_contents_scale.x() != 0.0 && |
756 effect_node->surface_contents_scale.y() != 0.0) | 502 effect_node->surface_contents_scale.y() != 0.0) |
757 transform->Scale(1.0 / effect_node->surface_contents_scale.x(), | 503 transform->Scale(1.0 / effect_node->surface_contents_scale.x(), |
758 1.0 / effect_node->surface_contents_scale.y()); | 504 1.0 / effect_node->surface_contents_scale.y()); |
759 } | 505 } |
760 | 506 |
761 void ComputeClips(PropertyTrees* property_trees, | |
762 bool non_root_surfaces_enabled) { | |
763 ClipTree* clip_tree = &property_trees->clip_tree; | |
764 if (!clip_tree->needs_update()) | |
765 return; | |
766 for (int i = ClipTree::kViewportNodeId; | |
767 i < static_cast<int>(clip_tree->size()); ++i) { | |
768 ClipNode* clip_node = clip_tree->Node(i); | |
769 | |
770 if (clip_node->id == ClipTree::kViewportNodeId) { | |
771 ResetIfHasNanCoordinate(&clip_node->clip); | |
772 clip_node->clip_in_target_space = clip_node->clip; | |
773 clip_node->combined_clip_in_target_space = clip_node->clip; | |
774 continue; | |
775 } | |
776 const TransformTree& transform_tree = property_trees->transform_tree; | |
777 const EffectTree& effect_tree = property_trees->effect_tree; | |
778 const TransformNode* transform_node = | |
779 transform_tree.Node(clip_node->transform_id); | |
780 ClipNode* parent_clip_node = clip_tree->parent(clip_node); | |
781 | |
782 bool target_is_clipped = | |
783 effect_tree.Node(clip_node->target_effect_id)->surface_is_clipped; | |
784 | |
785 gfx::Transform parent_to_current; | |
786 const TransformNode* parent_target_transform_node = | |
787 transform_tree.Node(parent_clip_node->target_transform_id); | |
788 bool success = true; | |
789 | |
790 // Clips must be combined in target space. We cannot, for example, combine | |
791 // clips in the space of the child clip. The reason is non-affine | |
792 // transforms. Say we have the following tree T->A->B->C, and B clips C, but | |
793 // draw into target T. It may be the case that A applies a perspective | |
794 // transform, and B and C are at different z positions. When projected into | |
795 // target space, the relative sizes and positions of B and C can shift. | |
796 // Since it's the relationship in target space that matters, that's where we | |
797 // must combine clips. For each clip node, we save the clip rects in its | |
798 // target space. So, we need to get the ancestor clip rect in the current | |
799 // clip node's target space. | |
800 gfx::RectF parent_combined_clip_in_target_space = | |
801 parent_clip_node->combined_clip_in_target_space; | |
802 gfx::RectF parent_clip_in_target_space = | |
803 parent_clip_node->clip_in_target_space; | |
804 if (parent_target_transform_node && | |
805 parent_target_transform_node->id != clip_node->target_transform_id && | |
806 non_root_surfaces_enabled) { | |
807 success &= ConvertRectBetweenSurfaceSpaces( | |
808 property_trees, parent_clip_node->target_effect_id, | |
809 clip_node->target_effect_id, | |
810 parent_clip_node->combined_clip_in_target_space, | |
811 &parent_combined_clip_in_target_space); | |
812 // If we can't compute a transform, it's because we had to use the inverse | |
813 // of a singular transform. We won't draw in this case, so there's no need | |
814 // to compute clips. | |
815 if (!success) | |
816 continue; | |
817 if (clip_node->clip_type == ClipNode::ClipType::EXPANDS_CLIP) { | |
818 parent_combined_clip_in_target_space = | |
819 gfx::RectF(clip_node->clip_expander->MapRectReverse( | |
820 gfx::ToEnclosingRect(parent_combined_clip_in_target_space), | |
821 property_trees)); | |
822 } | |
823 ConvertRectBetweenSurfaceSpaces( | |
824 property_trees, parent_clip_node->target_effect_id, | |
825 clip_node->target_effect_id, parent_clip_node->clip_in_target_space, | |
826 &parent_clip_in_target_space); | |
827 } | |
828 // Only nodes affected by ancestor clips will have their clip adjusted due | |
829 // to intersecting with an ancestor clip. But, we still need to propagate | |
830 // the combined clip to our children because if they are clipped, they may | |
831 // need to clip using our parent clip and if we don't propagate it here, | |
832 // it will be lost. | |
833 if (clip_node->resets_clip && non_root_surfaces_enabled) { | |
834 if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) { | |
835 gfx::Transform to_target; | |
836 property_trees->GetToTarget(clip_node->transform_id, | |
837 clip_node->target_effect_id, &to_target); | |
838 clip_node->clip_in_target_space = | |
839 MathUtil::MapClippedRect(to_target, clip_node->clip); | |
840 ResetIfHasNanCoordinate(&clip_node->clip_in_target_space); | |
841 clip_node->combined_clip_in_target_space = | |
842 gfx::IntersectRects(clip_node->clip_in_target_space, | |
843 parent_combined_clip_in_target_space); | |
844 } else { | |
845 DCHECK(!target_is_clipped); | |
846 DCHECK(!clip_node->layers_are_clipped); | |
847 clip_node->combined_clip_in_target_space = | |
848 parent_combined_clip_in_target_space; | |
849 } | |
850 ResetIfHasNanCoordinate(&clip_node->combined_clip_in_target_space); | |
851 continue; | |
852 } | |
853 bool use_only_parent_clip = | |
854 clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP; | |
855 if (use_only_parent_clip) { | |
856 clip_node->combined_clip_in_target_space = | |
857 parent_combined_clip_in_target_space; | |
858 if (!non_root_surfaces_enabled) { | |
859 clip_node->clip_in_target_space = | |
860 parent_clip_node->clip_in_target_space; | |
861 } else if (!target_is_clipped) { | |
862 clip_node->clip_in_target_space = parent_clip_in_target_space; | |
863 } else { | |
864 // Render Surface applies clip and the owning layer itself applies | |
865 // no clip. So, clip_in_target_space is not used and hence we can set | |
866 // it to an empty rect. | |
867 clip_node->clip_in_target_space = gfx::RectF(); | |
868 } | |
869 } else { | |
870 gfx::Transform source_to_target; | |
871 | |
872 if (!non_root_surfaces_enabled) { | |
873 source_to_target = transform_tree.ToScreen(clip_node->transform_id); | |
874 } else if (transform_tree.ContentTargetId(transform_node->id) == | |
875 clip_node->target_transform_id) { | |
876 property_trees->GetToTarget(clip_node->transform_id, | |
877 clip_node->target_effect_id, | |
878 &source_to_target); | |
879 } else { | |
880 success = property_trees->GetToTarget( | |
881 transform_node->id, clip_node->target_effect_id, &source_to_target); | |
882 // source_to_target computation should be successful as target is an | |
883 // ancestor of the transform node. | |
884 DCHECK(success); | |
885 } | |
886 | |
887 gfx::RectF source_clip_in_target_space = | |
888 MathUtil::MapClippedRect(source_to_target, clip_node->clip); | |
889 | |
890 // With surfaces disabled, the only case where we use only the local clip | |
891 // for layer clipping is the case where no non-viewport ancestor node | |
892 // applies a local clip. | |
893 bool layer_clipping_uses_only_local_clip = | |
894 non_root_surfaces_enabled | |
895 ? clip_node->layer_clipping_uses_only_local_clip | |
896 : !parent_clip_node->layers_are_clipped_when_surfaces_disabled; | |
897 if (!layer_clipping_uses_only_local_clip) { | |
898 clip_node->clip_in_target_space = gfx::IntersectRects( | |
899 parent_clip_in_target_space, source_clip_in_target_space); | |
900 } else { | |
901 clip_node->clip_in_target_space = source_clip_in_target_space; | |
902 } | |
903 | |
904 clip_node->combined_clip_in_target_space = gfx::IntersectRects( | |
905 parent_combined_clip_in_target_space, source_clip_in_target_space); | |
906 } | |
907 ResetIfHasNanCoordinate(&clip_node->clip_in_target_space); | |
908 ResetIfHasNanCoordinate(&clip_node->combined_clip_in_target_space); | |
909 } | |
910 clip_tree->set_needs_update(false); | |
911 } | |
912 | |
913 void UpdateScrollTree(ScrollTree* scroll_tree, | 507 void UpdateScrollTree(ScrollTree* scroll_tree, |
914 const LayerTreeHost* layer_tree_host) { | 508 const LayerTreeHost* layer_tree_host) { |
915 if (!scroll_tree->needs_update()) | 509 if (!scroll_tree->needs_update()) |
916 return; | 510 return; |
917 | 511 |
918 for (int i = ScrollTree::kRootNodeId; | 512 for (int i = ScrollTree::kRootNodeId; |
919 i < static_cast<int>(scroll_tree->size()); ++i) { | 513 i < static_cast<int>(scroll_tree->size()); ++i) { |
920 ScrollNode* scroll_node = scroll_tree->Node(i); | 514 ScrollNode* scroll_node = scroll_tree->Node(i); |
921 if (Layer* scroll_layer = | 515 if (Layer* scroll_layer = |
922 layer_tree_host->LayerById(scroll_node->owning_layer_id)) { | 516 layer_tree_host->LayerById(scroll_node->owning_layer_id)) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 | 550 |
957 void ComputeEffects(EffectTree* effect_tree) { | 551 void ComputeEffects(EffectTree* effect_tree) { |
958 if (!effect_tree->needs_update()) | 552 if (!effect_tree->needs_update()) |
959 return; | 553 return; |
960 for (int i = EffectTree::kContentsRootNodeId; | 554 for (int i = EffectTree::kContentsRootNodeId; |
961 i < static_cast<int>(effect_tree->size()); ++i) | 555 i < static_cast<int>(effect_tree->size()); ++i) |
962 effect_tree->UpdateEffects(i); | 556 effect_tree->UpdateEffects(i); |
963 effect_tree->set_needs_update(false); | 557 effect_tree->set_needs_update(false); |
964 } | 558 } |
965 | 559 |
966 static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) { | 560 void ComputeClips(PropertyTrees* property_trees) { |
967 EffectTree* effect_tree = &property_trees->effect_tree; | 561 DCHECK(!property_trees->transform_tree.needs_update()); |
968 const ClipTree* clip_tree = &property_trees->clip_tree; | 562 ClipTree* clip_tree = &property_trees->clip_tree; |
969 EffectNode* root_effect_node = | 563 if (!clip_tree->needs_update()) |
970 effect_tree->Node(EffectTree::kContentsRootNodeId); | 564 return; |
971 const RenderSurfaceImpl* root_render_surface = | 565 const int target_effect_id = EffectTree::kContentsRootNodeId; |
972 effect_tree->GetRenderSurface(EffectTree::kContentsRootNodeId); | 566 const int target_transform_id = TransformTree::kRootNodeId; |
973 gfx::Rect root_clip = | 567 const bool include_expanding_clips = true; |
974 gfx::ToEnclosingRect(clip_tree->Node(root_effect_node->clip_id)->clip); | 568 for (int i = ClipTree::kViewportNodeId; |
975 if (root_render_surface->is_clipped()) | 569 i < static_cast<int>(clip_tree->size()); ++i) { |
976 DCHECK(root_clip == root_render_surface->clip_rect()) | 570 ClipNode* clip_node = clip_tree->Node(i); |
977 << "clip on root render surface: " | 571 // Clear the clip rect cache |
978 << root_render_surface->clip_rect().ToString() | 572 clip_node->cached_clip_rects = std::vector<ClipRectData>(1); |
979 << " v.s. root effect node's clip: " << root_clip.ToString(); | 573 if (clip_node->id == ClipTree::kViewportNodeId) { |
980 for (int i = 2; i < static_cast<int>(effect_tree->size()); ++i) { | 574 clip_node->cached_accumulated_rect_in_screen_space = clip_node->clip; |
981 EffectNode* effect_node = effect_tree->Node(i); | 575 continue; |
982 const EffectNode* target_node = effect_tree->Node(effect_node->target_id); | |
983 bool include_viewport_clip = false; | |
984 bool include_expanding_clips = false; | |
985 ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( | |
986 property_trees, include_viewport_clip, include_expanding_clips, | |
987 effect_node->clip_id, target_node->id); | |
988 gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect; | |
989 const RenderSurfaceImpl* render_surface = effect_tree->GetRenderSurface(i); | |
990 if (render_surface && render_surface->is_clipped()) { | |
991 DCHECK(gfx::ToEnclosingRect(accumulated_clip) == | |
992 render_surface->clip_rect()) | |
993 << " render surface's clip rect: " | |
994 << render_surface->clip_rect().ToString() | |
995 << " v.s. accumulated clip: " | |
996 << gfx::ToEnclosingRect(accumulated_clip).ToString(); | |
997 } | 576 } |
| 577 ClipNode* parent_clip_node = clip_tree->parent(clip_node); |
| 578 DCHECK(parent_clip_node); |
| 579 gfx::RectF accumulated_clip = |
| 580 parent_clip_node->cached_accumulated_rect_in_screen_space; |
| 581 bool success = ApplyClipNodeToAccumulatedClip( |
| 582 property_trees, include_expanding_clips, target_effect_id, |
| 583 target_transform_id, clip_node, &accumulated_clip); |
| 584 DCHECK(success); |
| 585 clip_node->cached_accumulated_rect_in_screen_space = accumulated_clip; |
998 } | 586 } |
| 587 clip_tree->set_needs_update(false); |
999 } | 588 } |
1000 | 589 |
1001 static void ComputeLayerClipRect(const PropertyTrees* property_trees, | 590 static ConditionalClip LayerClipRect(PropertyTrees* property_trees, |
1002 const LayerImpl* layer) { | 591 LayerImpl* layer) { |
1003 const EffectTree* effect_tree = &property_trees->effect_tree; | 592 const EffectTree* effect_tree = &property_trees->effect_tree; |
1004 const ClipTree* clip_tree = &property_trees->clip_tree; | |
1005 const ClipNode* clip_node = clip_tree->Node(layer->clip_tree_index()); | |
1006 const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); | 593 const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); |
1007 const EffectNode* target_node = | 594 const EffectNode* target_node = |
1008 effect_node->has_render_surface | 595 effect_node->has_render_surface |
1009 ? effect_node | 596 ? effect_node |
1010 : effect_tree->Node(effect_node->target_id); | 597 : effect_tree->Node(effect_node->target_id); |
1011 // TODO(weiliangc): When effect node has up to date render surface info on | 598 // TODO(weiliangc): When effect node has up to date render surface info on |
1012 // compositor thread, no need to check for resourceless draw mode | 599 // compositor thread, no need to check for resourceless draw mode |
1013 if (!property_trees->non_root_surfaces_enabled) { | 600 if (!property_trees->non_root_surfaces_enabled) { |
1014 target_node = effect_tree->Node(1); | 601 target_node = effect_tree->Node(1); |
1015 } | 602 } |
1016 | 603 |
1017 bool include_viewport_clip = false; | |
1018 bool include_expanding_clips = false; | 604 bool include_expanding_clips = false; |
1019 ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( | 605 return ComputeAccumulatedClip(property_trees, include_expanding_clips, |
1020 property_trees, include_viewport_clip, include_expanding_clips, | 606 layer->clip_tree_index(), target_node->id); |
1021 layer->clip_tree_index(), target_node->id); | |
1022 | |
1023 bool is_clipped_from_clip_tree = | |
1024 property_trees->non_root_surfaces_enabled | |
1025 ? clip_node->layers_are_clipped | |
1026 : clip_node->layers_are_clipped_when_surfaces_disabled; | |
1027 DCHECK_EQ(is_clipped_from_clip_tree, accumulated_clip_rect.is_clipped); | |
1028 | |
1029 gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect; | |
1030 | |
1031 DCHECK(layer->clip_rect() == gfx::ToEnclosingRect(accumulated_clip)) | |
1032 << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index() | |
1033 << " layer clip: " << layer->clip_rect().ToString() << " v.s. " | |
1034 << gfx::ToEnclosingRect(accumulated_clip).ToString() | |
1035 << " and clip node clip: " | |
1036 << gfx::ToEnclosingRect(clip_node->clip_in_target_space).ToString(); | |
1037 } | 607 } |
1038 | 608 |
1039 void ComputeVisibleRects(LayerImpl* root_layer, | 609 static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, |
1040 PropertyTrees* property_trees, | 610 LayerImpl* layer) { |
1041 bool can_render_to_separate_surface, | |
1042 LayerImplList* visible_layer_list) { | |
1043 bool render_surfaces_need_update = false; | |
1044 if (property_trees->non_root_surfaces_enabled != | |
1045 can_render_to_separate_surface) { | |
1046 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | |
1047 property_trees->transform_tree.set_needs_update(true); | |
1048 render_surfaces_need_update = true; | |
1049 } | |
1050 if (property_trees->transform_tree.needs_update()) { | |
1051 property_trees->clip_tree.set_needs_update(true); | |
1052 property_trees->effect_tree.set_needs_update(true); | |
1053 } | |
1054 | |
1055 if (render_surfaces_need_update) { | |
1056 property_trees->effect_tree.UpdateRenderSurfaces( | |
1057 root_layer->layer_tree_impl(), | |
1058 property_trees->non_root_surfaces_enabled); | |
1059 } | |
1060 UpdateRenderTarget(&property_trees->effect_tree, | |
1061 property_trees->non_root_surfaces_enabled); | |
1062 ComputeTransforms(&property_trees->transform_tree); | |
1063 // Computation of clips uses surface contents scale which is updated while | |
1064 // computing effects. So, ComputeEffects should be before ComputeClips. | |
1065 ComputeEffects(&property_trees->effect_tree); | |
1066 ComputeClips(property_trees, can_render_to_separate_surface); | |
1067 | |
1068 FindLayersThatNeedUpdates(root_layer->layer_tree_impl(), property_trees, | |
1069 visible_layer_list); | |
1070 CalculateClipRects(*visible_layer_list, property_trees, | |
1071 can_render_to_separate_surface); | |
1072 CalculateVisibleRects(*visible_layer_list, property_trees, | |
1073 can_render_to_separate_surface); | |
1074 } | |
1075 | |
1076 void UpdatePropertyTrees(LayerTreeHost* layer_tree_host, | |
1077 PropertyTrees* property_trees, | |
1078 bool can_render_to_separate_surface) { | |
1079 DCHECK(layer_tree_host); | |
1080 DCHECK(property_trees); | |
1081 DCHECK_EQ(layer_tree_host->property_trees(), property_trees); | |
1082 if (property_trees->non_root_surfaces_enabled != | |
1083 can_render_to_separate_surface) { | |
1084 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | |
1085 property_trees->transform_tree.set_needs_update(true); | |
1086 } | |
1087 if (property_trees->transform_tree.needs_update()) { | |
1088 property_trees->clip_tree.set_needs_update(true); | |
1089 property_trees->effect_tree.set_needs_update(true); | |
1090 } | |
1091 UpdateScrollTree(&property_trees->scroll_tree, layer_tree_host); | |
1092 ComputeTransforms(&property_trees->transform_tree); | |
1093 // Computation of clips uses surface contents scale which is updated while | |
1094 // computing effects. So, ComputeEffects should be before ComputeClips. | |
1095 ComputeEffects(&property_trees->effect_tree); | |
1096 ComputeClips(property_trees, can_render_to_separate_surface); | |
1097 } | |
1098 | |
1099 void BuildPropertyTreesAndComputeVisibleRects( | |
1100 LayerImpl* root_layer, | |
1101 const LayerImpl* page_scale_layer, | |
1102 const LayerImpl* inner_viewport_scroll_layer, | |
1103 const LayerImpl* outer_viewport_scroll_layer, | |
1104 const LayerImpl* overscroll_elasticity_layer, | |
1105 const gfx::Vector2dF& elastic_overscroll, | |
1106 float page_scale_factor, | |
1107 float device_scale_factor, | |
1108 const gfx::Rect& viewport, | |
1109 const gfx::Transform& device_transform, | |
1110 bool can_render_to_separate_surface, | |
1111 PropertyTrees* property_trees, | |
1112 LayerImplList* visible_layer_list) { | |
1113 PropertyTreeBuilder::BuildPropertyTrees( | |
1114 root_layer, page_scale_layer, inner_viewport_scroll_layer, | |
1115 outer_viewport_scroll_layer, overscroll_elasticity_layer, | |
1116 elastic_overscroll, page_scale_factor, device_scale_factor, viewport, | |
1117 device_transform, property_trees); | |
1118 ComputeVisibleRects(root_layer, property_trees, | |
1119 can_render_to_separate_surface, visible_layer_list); | |
1120 } | |
1121 | |
1122 void VerifyClipTreeCalculations(const LayerImplList& layer_list, | |
1123 PropertyTrees* property_trees) { | |
1124 if (property_trees->non_root_surfaces_enabled) { | |
1125 ComputeClipsWithEffectTree(property_trees); | |
1126 } | |
1127 for (auto* layer : layer_list) | |
1128 ComputeLayerClipRect(property_trees, layer); | |
1129 } | |
1130 | |
1131 gfx::Rect ComputeLayerVisibleRectDynamic(const PropertyTrees* property_trees, | |
1132 const LayerImpl* layer) { | |
1133 int effect_ancestor_with_copy_request = | 611 int effect_ancestor_with_copy_request = |
1134 property_trees->effect_tree.ClosestAncestorWithCopyRequest( | 612 property_trees->effect_tree.ClosestAncestorWithCopyRequest( |
1135 layer->effect_tree_index()); | 613 layer->effect_tree_index()); |
1136 bool non_root_copy_request = | 614 bool non_root_copy_request = |
1137 effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId; | 615 effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId; |
1138 gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); | 616 gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); |
1139 gfx::RectF accumulated_clip_in_root_space; | 617 gfx::RectF accumulated_clip_in_root_space; |
1140 if (non_root_copy_request) { | 618 if (non_root_copy_request) { |
1141 bool include_viewport_clip = false; | |
1142 bool include_expanding_clips = true; | 619 bool include_expanding_clips = true; |
1143 ConditionalClip accumulated_clip = ComputeAccumulatedClip( | 620 ConditionalClip accumulated_clip = ComputeAccumulatedClip( |
1144 property_trees, include_viewport_clip, include_expanding_clips, | 621 property_trees, include_expanding_clips, layer->clip_tree_index(), |
1145 layer->clip_tree_index(), effect_ancestor_with_copy_request); | 622 effect_ancestor_with_copy_request); |
1146 if (!accumulated_clip.is_clipped) | 623 if (!accumulated_clip.is_clipped) |
1147 return layer_content_rect; | 624 return layer_content_rect; |
1148 accumulated_clip_in_root_space = accumulated_clip.clip_rect; | 625 accumulated_clip_in_root_space = accumulated_clip.clip_rect; |
1149 } else { | 626 } else { |
1150 accumulated_clip_in_root_space = | 627 const ClipNode* clip_node = |
1151 ComputeAccumulatedClipInRootSpaceForVisibleRect( | 628 property_trees->clip_tree.Node(layer->clip_tree_index()); |
1152 property_trees, layer->clip_tree_index()); | 629 const EffectNode* effect_node = property_trees->effect_tree.Node( |
| 630 layer->render_target_effect_tree_index()); |
| 631 bool fully_visible = |
| 632 !layer->is_clipped() && !effect_node->surface_is_clipped; |
| 633 if (fully_visible) { |
| 634 accumulated_clip_in_root_space = property_trees->clip_tree.ViewportClip(); |
| 635 } else { |
| 636 accumulated_clip_in_root_space = |
| 637 clip_node->cached_accumulated_rect_in_screen_space; |
| 638 } |
1153 } | 639 } |
1154 | 640 |
1155 const EffectNode* root_effect_node = | 641 const EffectNode* root_effect_node = |
1156 non_root_copy_request | 642 non_root_copy_request |
1157 ? property_trees->effect_tree.Node(effect_ancestor_with_copy_request) | 643 ? property_trees->effect_tree.Node(effect_ancestor_with_copy_request) |
1158 : property_trees->effect_tree.Node(EffectTree::kContentsRootNodeId); | 644 : property_trees->effect_tree.Node(EffectTree::kContentsRootNodeId); |
1159 ConditionalClip accumulated_clip_in_layer_space = | 645 ConditionalClip accumulated_clip_in_layer_space = |
1160 ComputeTargetRectInLocalSpace( | 646 ComputeTargetRectInLocalSpace( |
1161 accumulated_clip_in_root_space, property_trees, | 647 accumulated_clip_in_root_space, property_trees, |
1162 root_effect_node->transform_id, layer->transform_tree_index(), | 648 root_effect_node->transform_id, layer->transform_tree_index(), |
1163 root_effect_node->id); | 649 root_effect_node->id); |
1164 if (!accumulated_clip_in_layer_space.is_clipped) | 650 if (!accumulated_clip_in_layer_space.is_clipped) { |
1165 return layer_content_rect; | 651 return layer_content_rect; |
| 652 } |
1166 gfx::RectF clip_in_layer_space = accumulated_clip_in_layer_space.clip_rect; | 653 gfx::RectF clip_in_layer_space = accumulated_clip_in_layer_space.clip_rect; |
1167 clip_in_layer_space.Offset(-layer->offset_to_transform_parent()); | 654 clip_in_layer_space.Offset(-layer->offset_to_transform_parent()); |
1168 | 655 |
1169 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_in_layer_space); | 656 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_in_layer_space); |
1170 visible_rect.Intersect(layer_content_rect); | 657 visible_rect.Intersect(layer_content_rect); |
1171 return visible_rect; | 658 return visible_rect; |
1172 } | 659 } |
1173 | 660 |
1174 void VerifyVisibleRectsCalculations(const LayerImplList& layer_list, | 661 void UpdatePropertyTrees(LayerTreeHost* layer_tree_host, |
1175 const PropertyTrees* property_trees) { | 662 PropertyTrees* property_trees, |
1176 for (auto* layer : layer_list) { | 663 bool can_render_to_separate_surface) { |
1177 gfx::Rect visible_rect_dynamic = | 664 DCHECK(layer_tree_host); |
1178 ComputeLayerVisibleRectDynamic(property_trees, layer); | 665 DCHECK(property_trees); |
1179 DCHECK(layer->visible_layer_rect() == visible_rect_dynamic) | 666 DCHECK_EQ(layer_tree_host->property_trees(), property_trees); |
1180 << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index() | 667 if (property_trees->non_root_surfaces_enabled != |
1181 << " visible rect cached: " << layer->visible_layer_rect().ToString() | 668 can_render_to_separate_surface) { |
1182 << " v.s. " | 669 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; |
1183 << " visible rect dynamic: " << visible_rect_dynamic.ToString(); | 670 property_trees->transform_tree.set_needs_update(true); |
1184 } | 671 } |
| 672 if (property_trees->transform_tree.needs_update()) { |
| 673 property_trees->clip_tree.set_needs_update(true); |
| 674 property_trees->effect_tree.set_needs_update(true); |
| 675 } |
| 676 UpdateScrollTree(&property_trees->scroll_tree, layer_tree_host); |
| 677 ComputeTransforms(&property_trees->transform_tree); |
| 678 ComputeEffects(&property_trees->effect_tree); |
| 679 // Computation of clips uses ToScreen which is updated while computing |
| 680 // transforms. So, ComputeTransforms should be before ComputeClips. |
| 681 ComputeClips(property_trees); |
| 682 } |
| 683 |
| 684 void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, |
| 685 PropertyTrees* property_trees, |
| 686 bool can_render_to_separate_surface) { |
| 687 bool render_surfaces_need_update = false; |
| 688 if (property_trees->non_root_surfaces_enabled != |
| 689 can_render_to_separate_surface) { |
| 690 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; |
| 691 property_trees->transform_tree.set_needs_update(true); |
| 692 render_surfaces_need_update = true; |
| 693 } |
| 694 if (property_trees->transform_tree.needs_update()) { |
| 695 property_trees->clip_tree.set_needs_update(true); |
| 696 property_trees->effect_tree.set_needs_update(true); |
| 697 } |
| 698 if (render_surfaces_need_update) { |
| 699 property_trees->effect_tree.UpdateRenderSurfaces( |
| 700 root_layer->layer_tree_impl(), |
| 701 property_trees->non_root_surfaces_enabled); |
| 702 } |
| 703 UpdateRenderTarget(&property_trees->effect_tree, |
| 704 property_trees->non_root_surfaces_enabled); |
| 705 |
| 706 ComputeTransforms(&property_trees->transform_tree); |
| 707 ComputeEffects(&property_trees->effect_tree); |
| 708 // Computation of clips uses ToScreen which is updated while computing |
| 709 // transforms. So, ComputeTransforms should be before ComputeClips. |
| 710 ComputeClips(property_trees); |
1185 } | 711 } |
1186 | 712 |
1187 bool LayerNeedsUpdate(Layer* layer, | 713 bool LayerNeedsUpdate(Layer* layer, |
1188 bool layer_is_drawn, | 714 bool layer_is_drawn, |
1189 const PropertyTrees* property_trees) { | 715 const PropertyTrees* property_trees) { |
1190 return LayerNeedsUpdateInternal(layer, layer_is_drawn, property_trees); | 716 return LayerNeedsUpdateInternal(layer, layer_is_drawn, property_trees); |
1191 } | 717 } |
1192 | 718 |
1193 bool LayerNeedsUpdate(LayerImpl* layer, | 719 bool LayerNeedsUpdate(LayerImpl* layer, |
1194 bool layer_is_drawn, | 720 bool layer_is_drawn, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1234 const EffectNode* target_effect_node = | 760 const EffectNode* target_effect_node = |
1235 effect_tree.Node(effect_node->target_id); | 761 effect_tree.Node(effect_node->target_id); |
1236 property_trees->GetToTarget(transform_node->id, target_effect_node->id, | 762 property_trees->GetToTarget(transform_node->id, target_effect_node->id, |
1237 &render_surface_transform); | 763 &render_surface_transform); |
1238 | 764 |
1239 ConcatInverseSurfaceContentsScale(effect_node, &render_surface_transform); | 765 ConcatInverseSurfaceContentsScale(effect_node, &render_surface_transform); |
1240 render_surface->SetDrawTransform(render_surface_transform); | 766 render_surface->SetDrawTransform(render_surface_transform); |
1241 } | 767 } |
1242 | 768 |
1243 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, | 769 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, |
1244 const PropertyTrees* property_trees, | 770 PropertyTrees* property_trees, |
1245 RenderSurfaceImpl* render_surface) { | 771 RenderSurfaceImpl* render_surface) { |
1246 if (!render_surface->is_clipped()) { | 772 if (!render_surface->is_clipped()) { |
1247 render_surface->SetClipRect(gfx::Rect()); | 773 render_surface->SetClipRect(gfx::Rect()); |
1248 return; | 774 return; |
1249 } | 775 } |
1250 | 776 |
1251 const EffectTree& effect_tree = property_trees->effect_tree; | 777 const EffectTree& effect_tree = property_trees->effect_tree; |
1252 const TransformTree& transform_tree = property_trees->transform_tree; | 778 const ClipTree& clip_tree = property_trees->clip_tree; |
1253 const TransformNode* transform_node = | |
1254 transform_tree.Node(render_surface->TransformTreeIndex()); | |
1255 if (transform_tree.TargetId(transform_node->id) == | |
1256 parent_clip_node->target_transform_id) { | |
1257 render_surface->SetClipRect( | |
1258 gfx::ToEnclosingRect(parent_clip_node->clip_in_target_space)); | |
1259 return; | |
1260 } | |
1261 | |
1262 // In this case, the clip child has reset the clip node for subtree and hence | |
1263 // the parent clip node's clip rect is in clip parent's target space and not | |
1264 // our target space. We need to transform it to our target space. | |
1265 const EffectNode* effect_node = | 779 const EffectNode* effect_node = |
1266 effect_tree.Node(render_surface->EffectTreeIndex()); | 780 effect_tree.Node(render_surface->EffectTreeIndex()); |
1267 int target_effect_id = effect_node->target_id; | 781 const EffectNode* target_node = effect_tree.Node(effect_node->target_id); |
1268 gfx::RectF clip_rect; | 782 bool include_expanding_clips = false; |
1269 const bool success = ConvertRectBetweenSurfaceSpaces( | 783 if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { |
1270 property_trees, parent_clip_node->target_effect_id, target_effect_id, | 784 render_surface->SetClipRect( |
1271 parent_clip_node->clip_in_target_space, &clip_rect); | 785 gfx::ToEnclosingRect(clip_tree.Node(effect_node->clip_id)->clip)); |
1272 | 786 } else { |
1273 if (!success) { | 787 ConditionalClip accumulated_clip_rect = |
1274 render_surface->SetClipRect(gfx::Rect()); | 788 ComputeAccumulatedClip(property_trees, include_expanding_clips, |
1275 return; | 789 effect_node->clip_id, target_node->id); |
| 790 render_surface->SetClipRect( |
| 791 gfx::ToEnclosingRect(accumulated_clip_rect.clip_rect)); |
1276 } | 792 } |
1277 render_surface->SetClipRect(gfx::ToEnclosingRect(clip_rect)); | |
1278 } | 793 } |
1279 | 794 |
1280 template <typename LayerType> | 795 template <typename LayerType> |
1281 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, | 796 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, |
1282 const TransformTree& tree) { | 797 const TransformTree& tree) { |
1283 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), | 798 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), |
1284 layer->offset_to_transform_parent().y()); | 799 layer->offset_to_transform_parent().y()); |
1285 gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); | 800 gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); |
1286 xform.ConcatTransform(ssxform); | 801 xform.ConcatTransform(ssxform); |
1287 if (layer->should_flatten_transform_from_property_tree()) | 802 if (layer->should_flatten_transform_from_property_tree()) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1333 static gfx::Rect LayerDrawableContentRect( | 848 static gfx::Rect LayerDrawableContentRect( |
1334 const LayerImpl* layer, | 849 const LayerImpl* layer, |
1335 const gfx::Rect& layer_bounds_in_target_space, | 850 const gfx::Rect& layer_bounds_in_target_space, |
1336 const gfx::Rect& clip_rect) { | 851 const gfx::Rect& clip_rect) { |
1337 if (layer->is_clipped()) | 852 if (layer->is_clipped()) |
1338 return IntersectRects(layer_bounds_in_target_space, clip_rect); | 853 return IntersectRects(layer_bounds_in_target_space, clip_rect); |
1339 | 854 |
1340 return layer_bounds_in_target_space; | 855 return layer_bounds_in_target_space; |
1341 } | 856 } |
1342 | 857 |
1343 void ComputeLayerDrawProperties(LayerImpl* layer, | 858 void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, |
1344 const PropertyTrees* property_trees) { | 859 PropertyTrees* property_trees) { |
1345 const TransformNode* transform_node = | 860 // Compute transforms |
1346 property_trees->transform_tree.Node(layer->transform_tree_index()); | 861 for (LayerImpl* layer : *layer_list) { |
1347 const ClipNode* clip_node = | 862 const TransformNode* transform_node = |
1348 property_trees->clip_tree.Node(layer->clip_tree_index()); | 863 property_trees->transform_tree.Node(layer->transform_tree_index()); |
1349 | 864 |
1350 layer->draw_properties().screen_space_transform = | 865 layer->draw_properties().screen_space_transform = |
1351 ScreenSpaceTransformInternal(layer, property_trees->transform_tree); | 866 ScreenSpaceTransformInternal(layer, property_trees->transform_tree); |
1352 layer->draw_properties().target_space_transform = DrawTransform( | 867 layer->draw_properties().target_space_transform = DrawTransform( |
1353 layer, property_trees->transform_tree, property_trees->effect_tree); | 868 layer, property_trees->transform_tree, property_trees->effect_tree); |
1354 layer->draw_properties().screen_space_transform_is_animating = | 869 layer->draw_properties().screen_space_transform_is_animating = |
1355 transform_node->to_screen_is_potentially_animated; | 870 transform_node->to_screen_is_potentially_animated; |
1356 | |
1357 layer->draw_properties().opacity = | |
1358 LayerDrawOpacity(layer, property_trees->effect_tree); | |
1359 if (property_trees->non_root_surfaces_enabled) { | |
1360 layer->draw_properties().is_clipped = clip_node->layers_are_clipped; | |
1361 } else { | |
1362 layer->draw_properties().is_clipped = | |
1363 clip_node->layers_are_clipped_when_surfaces_disabled; | |
1364 } | 871 } |
1365 | 872 |
1366 gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( | 873 // Compute draw opacities |
1367 layer->draw_properties().target_space_transform, | 874 for (LayerImpl* layer : *layer_list) { |
1368 gfx::Rect(layer->bounds())); | 875 layer->draw_properties().opacity = |
1369 layer->draw_properties().drawable_content_rect = LayerDrawableContentRect( | 876 LayerDrawOpacity(layer, property_trees->effect_tree); |
1370 layer, bounds_in_target_space, layer->draw_properties().clip_rect); | 877 } |
| 878 |
| 879 // Compute clips and viisble rects |
| 880 for (LayerImpl* layer : *layer_list) { |
| 881 ConditionalClip clip = LayerClipRect(property_trees, layer); |
| 882 // is_clipped should be set before visible rect computation as it is used |
| 883 // there. |
| 884 layer->draw_properties().is_clipped = clip.is_clipped; |
| 885 layer->draw_properties().clip_rect = gfx::ToEnclosingRect(clip.clip_rect); |
| 886 layer->draw_properties().visible_layer_rect = |
| 887 LayerVisibleRect(property_trees, layer); |
| 888 } |
| 889 |
| 890 // Compute drawable content rects |
| 891 for (LayerImpl* layer : *layer_list) { |
| 892 gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( |
| 893 layer->draw_properties().target_space_transform, |
| 894 gfx::Rect(layer->bounds())); |
| 895 layer->draw_properties().drawable_content_rect = LayerDrawableContentRect( |
| 896 layer, bounds_in_target_space, layer->draw_properties().clip_rect); |
| 897 } |
1371 } | 898 } |
1372 | 899 |
1373 void ComputeMaskDrawProperties(LayerImpl* mask_layer, | 900 void ComputeMaskDrawProperties(LayerImpl* mask_layer, |
1374 const PropertyTrees* property_trees) { | 901 const PropertyTrees* property_trees) { |
1375 // Mask draw properties are used only for rastering, so most of the draw | 902 // Mask draw properties are used only for rastering, so most of the draw |
1376 // properties computed for other layers are not needed. | 903 // properties computed for other layers are not needed. |
1377 mask_layer->draw_properties().screen_space_transform = | 904 mask_layer->draw_properties().screen_space_transform = |
1378 ScreenSpaceTransformInternal(mask_layer, | 905 ScreenSpaceTransformInternal(mask_layer, |
1379 property_trees->transform_tree); | 906 property_trees->transform_tree); |
1380 mask_layer->draw_properties().visible_layer_rect = | 907 mask_layer->draw_properties().visible_layer_rect = |
1381 gfx::Rect(mask_layer->bounds()); | 908 gfx::Rect(mask_layer->bounds()); |
1382 } | 909 } |
1383 | 910 |
1384 void ComputeSurfaceDrawProperties(const PropertyTrees* property_trees, | 911 void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, |
1385 RenderSurfaceImpl* render_surface) { | 912 RenderSurfaceImpl* render_surface, |
| 913 const bool use_layer_lists) { |
1386 const EffectNode* effect_node = | 914 const EffectNode* effect_node = |
1387 property_trees->effect_tree.Node(render_surface->EffectTreeIndex()); | 915 property_trees->effect_tree.Node(render_surface->EffectTreeIndex()); |
1388 render_surface->SetIsClipped(effect_node->surface_is_clipped); | 916 if (use_layer_lists) { |
| 917 // TODO(crbug.com/702010) : Calculate surface's is_clipped value outside |
| 918 // cc property tree building. This is a temporary hack to make SPv2 layout |
| 919 // tests pass. |
| 920 bool is_clipped = effect_node->id == EffectTree::kContentsRootNodeId || |
| 921 (render_surface->render_target()->ClipTreeIndex() != |
| 922 render_surface->ClipTreeIndex()); |
| 923 render_surface->SetIsClipped(is_clipped); |
| 924 } else { |
| 925 render_surface->SetIsClipped(effect_node->surface_is_clipped); |
| 926 } |
1389 SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); | 927 SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); |
1390 SetSurfaceDrawTransform(property_trees, render_surface); | 928 SetSurfaceDrawTransform(property_trees, render_surface); |
1391 render_surface->SetScreenSpaceTransform( | 929 render_surface->SetScreenSpaceTransform( |
1392 property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( | 930 property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( |
1393 render_surface->TransformTreeIndex(), | 931 render_surface->TransformTreeIndex(), |
1394 render_surface->EffectTreeIndex())); | 932 render_surface->EffectTreeIndex())); |
1395 | 933 |
1396 const ClipNode* clip_node = | 934 const ClipNode* clip_node = |
1397 property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); | 935 property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); |
1398 SetSurfaceClipRect(clip_node, property_trees, render_surface); | 936 SetSurfaceClipRect(clip_node, property_trees, render_surface); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1494 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1032 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
1495 const Layer* overscroll_elasticity_layer, | 1033 const Layer* overscroll_elasticity_layer, |
1496 const gfx::Vector2dF& elastic_overscroll) { | 1034 const gfx::Vector2dF& elastic_overscroll) { |
1497 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1035 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
1498 elastic_overscroll); | 1036 elastic_overscroll); |
1499 } | 1037 } |
1500 | 1038 |
1501 } // namespace draw_property_utils | 1039 } // namespace draw_property_utils |
1502 | 1040 |
1503 } // namespace cc | 1041 } // namespace cc |
OLD | NEW |