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