| 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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 | 343 |
| 344 if (!clip_rect_in_target_space.IsEmpty()) { | 344 if (!clip_rect_in_target_space.IsEmpty()) { |
| 345 layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space)); | 345 layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space)); |
| 346 } else { | 346 } else { |
| 347 layer->set_clip_rect(gfx::Rect()); | 347 layer->set_clip_rect(gfx::Rect()); |
| 348 } | 348 } |
| 349 } | 349 } |
| 350 } | 350 } |
| 351 } | 351 } |
| 352 | 352 |
| 353 bool GetLayerClipRect(const LayerImpl* layer, | |
| 354 const ClipNode* clip_node, | |
| 355 const PropertyTrees* property_trees, | |
| 356 int target_node_id, | |
| 357 gfx::RectF* clip_rect_in_target_space) { | |
| 358 // This is equivalent of calling ComputeClipRectInTargetSpace. | |
| 359 *clip_rect_in_target_space = gfx::RectF(layer->clip_rect()); | |
| 360 return property_trees->transform_tree.Node(target_node_id) | |
| 361 ->ancestors_are_invertible; | |
| 362 } | |
| 363 | |
| 364 void CalculateVisibleRects(const LayerImplList& visible_layer_list, | 353 void CalculateVisibleRects(const LayerImplList& visible_layer_list, |
| 365 const PropertyTrees* property_trees, | 354 const PropertyTrees* property_trees, |
| 366 bool non_root_surfaces_enabled) { | 355 bool non_root_surfaces_enabled) { |
| 367 const EffectTree& effect_tree = property_trees->effect_tree; | 356 const EffectTree& effect_tree = property_trees->effect_tree; |
| 368 const TransformTree& transform_tree = property_trees->transform_tree; | |
| 369 const ClipTree& clip_tree = property_trees->clip_tree; | |
| 370 for (auto& layer : visible_layer_list) { | 357 for (auto& layer : visible_layer_list) { |
| 371 gfx::Size layer_bounds = layer->bounds(); | 358 gfx::Size layer_bounds = layer->bounds(); |
| 372 | 359 |
| 360 int root_effect_space = EffectTree::kContentsRootNodeId; |
| 361 |
| 373 int effect_ancestor_with_copy_request = | 362 int effect_ancestor_with_copy_request = |
| 374 effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index()); | 363 effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index()); |
| 375 if (effect_ancestor_with_copy_request > 1) { | 364 // If there is copy request, regard copy request as the "root space". |
| 376 // Non root copy request. | 365 if (effect_ancestor_with_copy_request > 0) |
| 377 ConditionalClip accumulated_clip_rect = | 366 root_effect_space = effect_ancestor_with_copy_request; |
| 378 ComputeAccumulatedClip(property_trees, layer->clip_tree_index(), | |
| 379 effect_ancestor_with_copy_request); | |
| 380 if (!accumulated_clip_rect.is_clipped) { | |
| 381 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
| 382 continue; | |
| 383 } | |
| 384 | 367 |
| 385 gfx::RectF accumulated_clip_in_copy_request_space = | 368 // Accumulates all clips appied to layer in "root space". |
| 386 accumulated_clip_rect.clip_rect; | 369 ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( |
| 387 | 370 property_trees, layer->clip_tree_index(), root_effect_space); |
| 388 const EffectNode* copy_request_effect_node = | 371 if (!accumulated_clip_rect.is_clipped) { |
| 389 effect_tree.Node(effect_ancestor_with_copy_request); | |
| 390 ConditionalClip clip_in_layer_space = ComputeTargetRectInLocalSpace( | |
| 391 accumulated_clip_in_copy_request_space, property_trees, | |
| 392 copy_request_effect_node->transform_id, layer->transform_tree_index(), | |
| 393 copy_request_effect_node->id); | |
| 394 | |
| 395 if (clip_in_layer_space.is_clipped) { | |
| 396 gfx::RectF clip_rect = clip_in_layer_space.clip_rect; | |
| 397 clip_rect.Offset(-layer->offset_to_transform_parent()); | |
| 398 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect); | |
| 399 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
| 400 layer->set_visible_layer_rect(visible_rect); | |
| 401 } else { | |
| 402 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
| 403 } | |
| 404 continue; | |
| 405 } | |
| 406 | |
| 407 const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index()); | |
| 408 const TransformNode* transform_node = | |
| 409 transform_tree.Node(layer->transform_tree_index()); | |
| 410 if (!non_root_surfaces_enabled) { | |
| 411 // When we only have a root surface, the clip node and the layer must | |
| 412 // necessarily have the same target (the root). | |
| 413 if (transform_node->ancestors_are_invertible) { | |
| 414 gfx::RectF combined_clip_rect_in_target_space = | |
| 415 clip_node->combined_clip_in_target_space; | |
| 416 gfx::Transform target_to_content; | |
| 417 target_to_content.Translate(-layer->offset_to_transform_parent().x(), | |
| 418 -layer->offset_to_transform_parent().y()); | |
| 419 target_to_content.PreconcatTransform( | |
| 420 transform_tree.FromScreen(transform_node->id)); | |
| 421 | |
| 422 gfx::Rect visible_rect = | |
| 423 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | |
| 424 target_to_content, combined_clip_rect_in_target_space)); | |
| 425 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
| 426 layer->set_visible_layer_rect(visible_rect); | |
| 427 } else { | |
| 428 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
| 429 } | |
| 430 continue; | |
| 431 } | |
| 432 | |
| 433 // When both the layer and the target are unclipped, the entire layer | |
| 434 // content rect is visible. | |
| 435 const bool fully_visible = | |
| 436 !clip_node->layers_are_clipped && !clip_node->target_is_clipped; | |
| 437 | |
| 438 if (fully_visible) { | |
| 439 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | 372 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); |
| 440 continue; | 373 continue; |
| 441 } | 374 } |
| 442 | 375 |
| 443 int target_node_id = transform_tree.ContentTargetId(transform_node->id); | 376 gfx::RectF accumulated_clip_in_root_space = accumulated_clip_rect.clip_rect; |
| 444 | 377 |
| 445 // The clip node stores clip rect in its target space. If required, | 378 // Convert accumulated clip into layer space. |
| 446 // this clip rect should be mapped to the current layer's target space. | 379 const EffectNode* root_effect_node = effect_tree.Node(root_effect_space); |
| 447 gfx::RectF combined_clip_rect_in_target_space; | 380 ConditionalClip clip_in_layer_space = ComputeTargetRectInLocalSpace( |
| 381 accumulated_clip_in_root_space, property_trees, |
| 382 root_effect_node->transform_id, layer->transform_tree_index(), |
| 383 root_effect_node->id); |
| 448 | 384 |
| 449 if (clip_node->target_transform_id != target_node_id) { | 385 if (clip_in_layer_space.is_clipped) { |
| 450 // In this case, layer has a clip parent or scroll parent (or shares the | 386 gfx::RectF clip_rect = clip_in_layer_space.clip_rect; |
| 451 // target with an ancestor layer that has clip parent) and the clip | 387 clip_rect.Offset(-layer->offset_to_transform_parent()); |
| 452 // parent's target is different from the layer's target. As the layer's | 388 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect); |
| 453 // target has unclippped descendants, it is unclippped. | 389 visible_rect.Intersect(gfx::Rect(layer_bounds)); |
| 454 if (!clip_node->layers_are_clipped) { | 390 layer->set_visible_layer_rect(visible_rect); |
| 455 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
| 456 continue; | |
| 457 } | |
| 458 | |
| 459 // We use the clip node's clip_in_target_space (and not | |
| 460 // combined_clip_in_target_space) here because we want to clip | |
| 461 // with respect to clip parent's local clip and not its combined clip as | |
| 462 // the combined clip has even the clip parent's target's clip baked into | |
| 463 // it and as our target is different, we don't want to use it in our | |
| 464 // visible rect computation. | |
| 465 if (!GetLayerClipRect(layer, clip_node, property_trees, target_node_id, | |
| 466 &combined_clip_rect_in_target_space)) { | |
| 467 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
| 468 continue; | |
| 469 } | |
| 470 } else { | 391 } else { |
| 471 if (clip_node->target_is_clipped) { | 392 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); |
| 472 combined_clip_rect_in_target_space = | |
| 473 clip_node->combined_clip_in_target_space; | |
| 474 } else { | |
| 475 combined_clip_rect_in_target_space = clip_node->clip_in_target_space; | |
| 476 } | |
| 477 } | 393 } |
| 478 | |
| 479 // The clip rect should be intersected with layer rect in target space. | |
| 480 gfx::Transform content_to_target = transform_tree.ToTarget( | |
| 481 transform_node->id, layer->render_target_effect_tree_index()); | |
| 482 content_to_target.Translate(layer->offset_to_transform_parent().x(), | |
| 483 layer->offset_to_transform_parent().y()); | |
| 484 gfx::Rect layer_content_rect = gfx::Rect(layer_bounds); | |
| 485 gfx::RectF layer_content_bounds_in_target_space = MathUtil::MapClippedRect( | |
| 486 content_to_target, gfx::RectF(layer_content_rect)); | |
| 487 // If the layer is fully contained within the clip, treat it as fully | |
| 488 // visible. | |
| 489 if (!layer_content_bounds_in_target_space.IsEmpty() && | |
| 490 combined_clip_rect_in_target_space.Contains( | |
| 491 layer_content_bounds_in_target_space)) { | |
| 492 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
| 493 continue; | |
| 494 } | |
| 495 | |
| 496 combined_clip_rect_in_target_space.Intersect( | |
| 497 layer_content_bounds_in_target_space); | |
| 498 if (combined_clip_rect_in_target_space.IsEmpty()) { | |
| 499 layer->set_visible_layer_rect(gfx::Rect()); | |
| 500 continue; | |
| 501 } | |
| 502 | |
| 503 gfx::Transform target_to_layer; | |
| 504 if (transform_node->ancestors_are_invertible) { | |
| 505 target_to_layer = transform_tree.FromTarget( | |
| 506 transform_node->id, layer->render_target_effect_tree_index()); | |
| 507 } else { | |
| 508 const EffectNode* target_effect_node = | |
| 509 ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree); | |
| 510 bool success = property_trees->ComputeTransformFromTarget( | |
| 511 transform_node->id, target_effect_node->id, &target_to_layer); | |
| 512 if (!success) { | |
| 513 // An animated singular transform may become non-singular during the | |
| 514 // animation, so we still need to compute a visible rect. In this | |
| 515 // situation, we treat the entire layer as visible. | |
| 516 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
| 517 continue; | |
| 518 } | |
| 519 if (target_effect_node->id > EffectTree::kContentsRootNodeId) { | |
| 520 ConcatInverseSurfaceContentsScale(target_effect_node, &target_to_layer); | |
| 521 #if DCHECK_IS_ON() | |
| 522 VerifySurfaceContentsScalesMatch(target_effect_node->id, target_node_id, | |
| 523 effect_tree, transform_tree); | |
| 524 #endif | |
| 525 } | |
| 526 } | |
| 527 gfx::Transform target_to_content; | |
| 528 target_to_content.Translate(-layer->offset_to_transform_parent().x(), | |
| 529 -layer->offset_to_transform_parent().y()); | |
| 530 target_to_content.PreconcatTransform(target_to_layer); | |
| 531 | |
| 532 gfx::Rect visible_rect = gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | |
| 533 target_to_content, combined_clip_rect_in_target_space)); | |
| 534 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
| 535 layer->set_visible_layer_rect(visible_rect); | |
| 536 } | 394 } |
| 537 } | 395 } |
| 538 | 396 |
| 539 static bool HasSingularTransform(int transform_tree_index, | 397 static bool HasSingularTransform(int transform_tree_index, |
| 540 const TransformTree& tree) { | 398 const TransformTree& tree) { |
| 541 const TransformNode* node = tree.Node(transform_tree_index); | 399 const TransformNode* node = tree.Node(transform_tree_index); |
| 542 return !node->is_invertible || !node->ancestors_are_invertible; | 400 return !node->is_invertible || !node->ancestors_are_invertible; |
| 543 } | 401 } |
| 544 | 402 |
| 545 template <typename LayerType> | 403 template <typename LayerType> |
| (...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1453 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
| 1596 const Layer* overscroll_elasticity_layer, | 1454 const Layer* overscroll_elasticity_layer, |
| 1597 const gfx::Vector2dF& elastic_overscroll) { | 1455 const gfx::Vector2dF& elastic_overscroll) { |
| 1598 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1456 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
| 1599 elastic_overscroll); | 1457 elastic_overscroll); |
| 1600 } | 1458 } |
| 1601 | 1459 |
| 1602 } // namespace draw_property_utils | 1460 } // namespace draw_property_utils |
| 1603 | 1461 |
| 1604 } // namespace cc | 1462 } // namespace cc |
| OLD | NEW |