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