Chromium Code Reviews| 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 if (clip_node->data.target_id < target_node->id) { | 126 if (clip_node->data.target_id < target_node->id) { |
| 127 combined_clip_rect_in_target_space = | 127 combined_clip_rect_in_target_space = |
| 128 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | 128 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( |
| 129 clip_to_target, clip_node->data.clip_in_target_space)); | 129 clip_to_target, clip_node->data.clip_in_target_space)); |
| 130 } else { | 130 } else { |
| 131 combined_clip_rect_in_target_space = | 131 combined_clip_rect_in_target_space = |
| 132 gfx::ToEnclosingRect(MathUtil::MapClippedRect( | 132 gfx::ToEnclosingRect(MathUtil::MapClippedRect( |
| 133 clip_to_target, clip_node->data.clip_in_target_space)); | 133 clip_to_target, clip_node->data.clip_in_target_space)); |
| 134 } | 134 } |
| 135 clip_rect_in_target_space = combined_clip_rect_in_target_space; | 135 clip_rect_in_target_space = combined_clip_rect_in_target_space; |
| 136 | |
| 137 } else { | 136 } else { |
| 138 clip_rect_in_target_space = | 137 clip_rect_in_target_space = |
| 139 gfx::ToEnclosingRect(clip_node->data.clip_in_target_space); | 138 gfx::ToEnclosingRect(clip_node->data.clip_in_target_space); |
| 140 if (clip_node->data.target_is_clipped || !non_root_surfaces_enabled) | 139 if (clip_node->data.target_is_clipped || !non_root_surfaces_enabled) |
| 141 combined_clip_rect_in_target_space = gfx::ToEnclosingRect( | 140 combined_clip_rect_in_target_space = gfx::ToEnclosingRect( |
| 142 clip_node->data.combined_clip_in_target_space); | 141 clip_node->data.combined_clip_in_target_space); |
| 143 else | 142 else |
| 144 combined_clip_rect_in_target_space = clip_rect_in_target_space; | 143 combined_clip_rect_in_target_space = clip_rect_in_target_space; |
| 145 } | 144 } |
| 146 | 145 |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 } | 446 } |
| 448 | 447 |
| 449 for (size_t i = 0; i < layer->children().size(); ++i) { | 448 for (size_t i = 0; i < layer->children().size(); ++i) { |
| 450 FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree, | 449 FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree, |
| 451 update_layer_list, visible_layer_list); | 450 update_layer_list, visible_layer_list); |
| 452 } | 451 } |
| 453 } | 452 } |
| 454 | 453 |
| 455 template <typename LayerType> | 454 template <typename LayerType> |
| 456 void UpdateRenderSurfacesWithEffectTreeInternal(EffectTree* effect_tree, | 455 void UpdateRenderSurfacesWithEffectTreeInternal(EffectTree* effect_tree, |
| 457 LayerType* layer) { | 456 LayerType* layer, |
| 457 int target_id) { | |
| 458 EffectNode* node = effect_tree->Node(layer->effect_tree_index()); | 458 EffectNode* node = effect_tree->Node(layer->effect_tree_index()); |
| 459 if (node->owner_id == layer->id()) | |
| 460 node->data.target_id = target_id; | |
| 459 | 461 |
| 460 if (node->owner_id == layer->id() && node->data.has_render_surface) | 462 if (node->owner_id == layer->id() && node->data.has_render_surface) { |
| 461 layer->SetHasRenderSurface(true); | 463 layer->SetHasRenderSurface(true); |
| 462 else | 464 target_id = node->id; |
| 465 } else { | |
| 463 layer->SetHasRenderSurface(false); | 466 layer->SetHasRenderSurface(false); |
| 467 } | |
| 464 | 468 |
| 465 for (size_t i = 0; i < layer->children().size(); ++i) { | 469 for (size_t i = 0; i < layer->children().size(); ++i) { |
| 466 UpdateRenderSurfacesWithEffectTreeInternal<LayerType>(effect_tree, | 470 UpdateRenderSurfacesWithEffectTreeInternal<LayerType>( |
| 467 layer->child_at(i)); | 471 effect_tree, layer->child_at(i), target_id); |
| 468 } | 472 } |
| 469 } | 473 } |
| 470 | 474 |
| 471 void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, Layer* layer) { | 475 void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, Layer* layer) { |
| 472 UpdateRenderSurfacesWithEffectTreeInternal<Layer>(effect_tree, layer); | 476 UpdateRenderSurfacesWithEffectTreeInternal<Layer>(effect_tree, layer, 0); |
| 473 } | 477 } |
| 474 | 478 |
| 475 void UpdateRenderSurfacesNonRootSurfacesDisabled(LayerImpl* layer) { | 479 void UpdateRenderSurfacesNonRootSurfacesDisabled(LayerImpl* layer) { |
| 476 // Only root layer has render surface, all other layers don't. | 480 // Only root layer has render surface, all other layers don't. |
| 477 layer->SetHasRenderSurface(!layer->parent()); | 481 layer->SetHasRenderSurface(!layer->parent()); |
| 478 | 482 |
| 479 for (size_t i = 0; i < layer->children().size(); ++i) | 483 for (size_t i = 0; i < layer->children().size(); ++i) |
| 480 UpdateRenderSurfacesNonRootSurfacesDisabled(layer->child_at(i)); | 484 UpdateRenderSurfacesNonRootSurfacesDisabled(layer->child_at(i)); |
| 481 } | 485 } |
| 482 | 486 |
| 483 void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, | 487 void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, |
| 484 bool non_root_surfaces_enabled, | 488 bool non_root_surfaces_enabled, |
| 485 LayerImpl* layer) { | 489 LayerImpl* layer) { |
| 486 if (!non_root_surfaces_enabled) | 490 if (!non_root_surfaces_enabled) |
| 487 UpdateRenderSurfacesNonRootSurfacesDisabled(layer); | 491 UpdateRenderSurfacesNonRootSurfacesDisabled(layer); |
| 488 else | 492 else |
| 489 UpdateRenderSurfacesWithEffectTreeInternal<LayerImpl>(effect_tree, layer); | 493 UpdateRenderSurfacesWithEffectTreeInternal<LayerImpl>(effect_tree, layer, |
| 494 0); | |
| 490 } | 495 } |
| 491 | 496 |
| 492 } // namespace | 497 } // namespace |
| 493 | 498 |
| 494 static void ResetIfHasNanCoordinate(gfx::RectF* rect) { | 499 static void ResetIfHasNanCoordinate(gfx::RectF* rect) { |
| 495 if (std::isnan(rect->x()) || std::isnan(rect->y()) || | 500 if (std::isnan(rect->x()) || std::isnan(rect->y()) || |
| 496 std::isnan(rect->right()) || std::isnan(rect->bottom())) | 501 std::isnan(rect->right()) || std::isnan(rect->bottom())) |
| 497 *rect = gfx::RectF(); | 502 *rect = gfx::RectF(); |
| 498 } | 503 } |
| 499 | 504 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 } | 649 } |
| 645 | 650 |
| 646 void ComputeEffects(EffectTree* effect_tree) { | 651 void ComputeEffects(EffectTree* effect_tree) { |
| 647 if (!effect_tree->needs_update()) | 652 if (!effect_tree->needs_update()) |
| 648 return; | 653 return; |
| 649 for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) | 654 for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) |
| 650 effect_tree->UpdateEffects(i); | 655 effect_tree->UpdateEffects(i); |
| 651 effect_tree->set_needs_update(false); | 656 effect_tree->set_needs_update(false); |
| 652 } | 657 } |
| 653 | 658 |
| 659 static gfx::RectF ComputeCurrentClip(const ClipNode* clip_node, | |
| 660 const TransformTree& transform_tree, | |
| 661 int target_transform_id) { | |
| 662 if (clip_node->data.transform_id != target_transform_id) { | |
| 663 gfx::Transform current_to_target; | |
| 664 if (!transform_tree.ComputeTransformWithDestinationSublayerScale( | |
| 665 clip_node->data.transform_id, target_transform_id, | |
| 666 ¤t_to_target)) | |
| 667 return gfx::RectF(); | |
| 668 if (clip_node->data.transform_id > target_transform_id) | |
| 669 return MathUtil::MapClippedRect(current_to_target, clip_node->data.clip); | |
| 670 else | |
| 671 return MathUtil::ProjectClippedRect(current_to_target, | |
| 672 clip_node->data.clip); | |
| 673 } else { | |
| 674 gfx::RectF current_clip = clip_node->data.clip; | |
| 675 gfx::Vector2dF sublayer_scale = | |
| 676 transform_tree.Node(target_transform_id)->data.sublayer_scale; | |
| 677 if (sublayer_scale.x() > 0 && sublayer_scale.y() > 0) { | |
| 678 current_clip.Scale(sublayer_scale.x(), sublayer_scale.y()); | |
| 679 } | |
| 680 return current_clip; | |
| 681 } | |
| 682 } | |
| 683 | |
| 684 static gfx::RectF ComputeAccumulatedClip(const ClipTree& clip_tree, | |
| 685 int local_clip_id, | |
| 686 const EffectTree& effect_tree, | |
| 687 int target_id, | |
| 688 const TransformTree& transform_tree) { | |
| 689 const ClipNode* clip_node = clip_tree.Node(local_clip_id); | |
| 690 const EffectNode* target_node = effect_tree.Node(target_id); | |
| 691 int target_transform_id = target_node->data.transform_id; | |
| 692 | |
| 693 // Collect all the clips that need to be accumulated. | |
| 694 std::stack<const ClipNode*> parent_chain; | |
| 695 | |
| 696 // If target is not direct ancestor of clip, this will find least common | |
| 697 // ancestor between the target and the clip. | |
| 698 while (target_node->id >= 0 && clip_node->id >= 0) { | |
| 699 while (target_node->data.clip_id > clip_node->id || | |
| 700 target_node->data.has_unclipped_descendants) { | |
| 701 target_node = effect_tree.Node(target_node->data.target_id); | |
| 702 } | |
| 703 if (target_node->data.clip_id == clip_node->id) | |
| 704 break; | |
| 705 while (target_node->data.clip_id < clip_node->id) { | |
| 706 parent_chain.push(clip_node); | |
| 707 clip_node = clip_tree.parent(clip_node); | |
| 708 } | |
| 709 if (target_node->data.clip_id == clip_node->id) { | |
| 710 clip_node = parent_chain.top(); | |
| 711 parent_chain.pop(); | |
| 712 break; | |
| 713 } | |
| 714 } | |
| 715 | |
| 716 // TODO(weiliangc): If we don't create clip for render surface, we don't need | |
| 717 // to check applies_local_clip. | |
| 718 while (!clip_node->data.applies_local_clip && parent_chain.size() > 0) { | |
| 719 clip_node = parent_chain.top(); | |
| 720 parent_chain.pop(); | |
| 721 } | |
| 722 | |
| 723 if (!clip_node->data.applies_local_clip) | |
| 724 return gfx::RectF(); | |
| 725 | |
| 726 gfx::RectF accumulated_clip = | |
| 727 ComputeCurrentClip(clip_node, transform_tree, target_transform_id); | |
| 728 | |
| 729 while (parent_chain.size() > 0) { | |
| 730 clip_node = parent_chain.top(); | |
| 731 parent_chain.pop(); | |
| 732 if (!clip_node->data.applies_local_clip) { | |
| 733 continue; | |
| 734 } | |
| 735 gfx::RectF current_clip = | |
| 736 ComputeCurrentClip(clip_node, transform_tree, target_transform_id); | |
| 737 | |
| 738 if (current_clip.IsEmpty()) | |
| 739 return gfx::RectF(); | |
| 740 | |
| 741 accumulated_clip = gfx::IntersectRects(accumulated_clip, current_clip); | |
| 742 } | |
| 743 | |
| 744 return accumulated_clip.IsEmpty() ? gfx::RectF() : accumulated_clip; | |
| 745 } | |
| 746 | |
| 747 static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) { | |
| 748 EffectTree* effect_tree = &property_trees->effect_tree; | |
| 749 const ClipTree* clip_tree = &property_trees->clip_tree; | |
| 750 const TransformTree* transform_tree = &property_trees->transform_tree; | |
| 751 EffectNode* root_effect_node = effect_tree->Node(1); | |
| 752 root_effect_node->data.clip_rect = gfx::ToEnclosingRect( | |
| 753 clip_tree->Node(root_effect_node->data.clip_id)->data.clip); | |
| 754 for (int i = 2; i < static_cast<int>(effect_tree->size()); ++i) { | |
| 755 EffectNode* effect_node = effect_tree->Node(i); | |
| 756 const EffectNode* target_node = | |
| 757 effect_tree->Node(effect_node->data.target_id); | |
| 758 gfx::RectF accumulated_clip = | |
| 759 ComputeAccumulatedClip(*clip_tree, effect_node->data.clip_id, | |
| 760 *effect_tree, target_node->id, *transform_tree); | |
| 761 | |
| 762 const ClipNode* clip_node = clip_tree->Node(effect_node->data.clip_id); | |
| 763 if (!clip_node->data.applies_local_clip && | |
| 764 !effect_node->data.has_unclipped_descendants) { | |
| 765 DCHECK(accumulated_clip == clip_node->data.clip_in_target_space); | |
|
ajuma
2016/03/19 00:29:41
The original patch also had logic to compare the e
weiliangc
2016/05/11 23:08:08
Added the logic back. Now the verification on rend
| |
| 766 } | |
| 767 effect_node->data.clip_rect = gfx::ToEnclosingRect(accumulated_clip); | |
| 768 } | |
| 769 } | |
| 770 | |
| 771 static void ComputeLayerClipRect(const PropertyTrees* property_trees, | |
| 772 const LayerImpl* layer) { | |
| 773 const EffectTree* effect_tree = &property_trees->effect_tree; | |
| 774 const ClipTree* clip_tree = &property_trees->clip_tree; | |
| 775 const TransformTree* transform_tree = &property_trees->transform_tree; | |
| 776 const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); | |
| 777 const EffectNode* target_node = | |
| 778 effect_node->data.has_render_surface | |
| 779 ? effect_node | |
| 780 : effect_tree->Node(effect_node->data.target_id); | |
| 781 | |
| 782 gfx::RectF accumulated_clip = | |
| 783 ComputeAccumulatedClip(*clip_tree, layer->clip_tree_index(), *effect_tree, | |
| 784 target_node->id, *transform_tree); | |
| 785 if (!property_trees->non_root_surfaces_enabled || | |
|
ajuma
2016/03/19 00:29:41
Since this is currently only called when non_root_
weiliangc
2016/05/11 23:08:08
Added computation and verification for resourceles
| |
| 786 clip_tree->Node(layer->clip_tree_index())->data.layers_are_clipped) { | |
| 787 DCHECK(layer->clip_rect() == gfx::ToEnclosingRect(accumulated_clip)) | |
| 788 << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index() | |
| 789 << " layer clip: " << layer->clip_rect().ToString() << " v.s. " | |
| 790 << gfx::ToEnclosingRect(accumulated_clip).ToString() | |
| 791 << " and clip node clip: " | |
| 792 << gfx::ToEnclosingRect(clip_tree->Node(layer->clip_tree_index()) | |
| 793 ->data.clip_in_target_space) | |
| 794 .ToString(); | |
| 795 } | |
| 796 } | |
| 797 | |
| 654 template <typename LayerType> | 798 template <typename LayerType> |
| 655 static void ComputeVisibleRectsInternal( | 799 static void ComputeVisibleRectsInternal( |
| 656 LayerType* root_layer, | 800 LayerType* root_layer, |
| 657 PropertyTrees* property_trees, | 801 PropertyTrees* property_trees, |
| 658 bool can_render_to_separate_surface, | 802 bool can_render_to_separate_surface, |
| 659 typename LayerType::LayerListType* update_layer_list, | 803 typename LayerType::LayerListType* update_layer_list, |
| 660 std::vector<LayerType*>* visible_layer_list) { | 804 std::vector<LayerType*>* visible_layer_list) { |
| 661 if (property_trees->non_root_surfaces_enabled != | 805 if (property_trees->non_root_surfaces_enabled != |
| 662 can_render_to_separate_surface) { | 806 can_render_to_separate_surface) { |
| 663 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | 807 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 729 void ComputeVisibleRects(Layer* root_layer, | 873 void ComputeVisibleRects(Layer* root_layer, |
| 730 PropertyTrees* property_trees, | 874 PropertyTrees* property_trees, |
| 731 bool can_render_to_separate_surface, | 875 bool can_render_to_separate_surface, |
| 732 LayerList* update_layer_list) { | 876 LayerList* update_layer_list) { |
| 733 std::vector<Layer*> visible_layer_list; | 877 std::vector<Layer*> visible_layer_list; |
| 734 ComputeVisibleRectsInternal(root_layer, property_trees, | 878 ComputeVisibleRectsInternal(root_layer, property_trees, |
| 735 can_render_to_separate_surface, update_layer_list, | 879 can_render_to_separate_surface, update_layer_list, |
| 736 &visible_layer_list); | 880 &visible_layer_list); |
| 737 } | 881 } |
| 738 | 882 |
| 883 void VerifyClipTreeCalculations(const LayerImplList& layer_list, | |
| 884 PropertyTrees* property_trees) { | |
| 885 if (property_trees->non_root_surfaces_enabled) { | |
|
ajuma
2016/03/19 00:29:41
Just to make sure I understand, the reason this do
weiliangc
2016/05/11 23:08:08
Yes. I have added a hack to the computation (aka e
| |
| 886 ComputeClipsWithEffectTree(property_trees); | |
| 887 for (auto layer : layer_list) | |
| 888 ComputeLayerClipRect(property_trees, layer); | |
| 889 } | |
| 890 } | |
| 891 | |
| 739 void ComputeVisibleRects(LayerImpl* root_layer, | 892 void ComputeVisibleRects(LayerImpl* root_layer, |
| 740 PropertyTrees* property_trees, | 893 PropertyTrees* property_trees, |
| 741 bool can_render_to_separate_surface, | 894 bool can_render_to_separate_surface, |
| 742 LayerImplList* visible_layer_list) { | 895 LayerImplList* visible_layer_list) { |
| 743 UpdateRenderSurfacesWithEffectTree( | 896 UpdateRenderSurfacesWithEffectTree( |
| 744 &property_trees->effect_tree, can_render_to_separate_surface, root_layer); | 897 &property_trees->effect_tree, can_render_to_separate_surface, root_layer); |
| 745 if (can_render_to_separate_surface) | 898 if (can_render_to_separate_surface) |
| 746 ValidateRenderSurfaces(root_layer); | 899 ValidateRenderSurfaces(root_layer); |
| 747 LayerImplList update_layer_list; | 900 LayerImplList update_layer_list; |
| 748 ComputeVisibleRectsInternal(root_layer, property_trees, | 901 ComputeVisibleRectsInternal(root_layer, property_trees, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 795 &render_surface_transform); | 948 &render_surface_transform); |
| 796 if (node->data.sublayer_scale.x() != 0.0 && | 949 if (node->data.sublayer_scale.x() != 0.0 && |
| 797 node->data.sublayer_scale.y() != 0.0) | 950 node->data.sublayer_scale.y() != 0.0) |
| 798 render_surface_transform.Scale(1.0 / node->data.sublayer_scale.x(), | 951 render_surface_transform.Scale(1.0 / node->data.sublayer_scale.x(), |
| 799 1.0 / node->data.sublayer_scale.y()); | 952 1.0 / node->data.sublayer_scale.y()); |
| 800 render_surface->SetDrawTransform(render_surface_transform); | 953 render_surface->SetDrawTransform(render_surface_transform); |
| 801 } | 954 } |
| 802 | 955 |
| 803 static void SetSurfaceIsClipped(const ClipNode* clip_node, | 956 static void SetSurfaceIsClipped(const ClipNode* clip_node, |
| 804 RenderSurfaceImpl* render_surface) { | 957 RenderSurfaceImpl* render_surface) { |
| 958 DCHECK(render_surface->OwningLayerId() == clip_node->owner_id) | |
|
ajuma
2016/03/19 00:29:41
Since we now have this DCHECK, the 'if' below can
weiliangc
2016/05/11 23:08:08
Done.
| |
| 959 << "we now create clip node for every render surface"; | |
| 805 // If the render surface's owning layer doesn't form a clip node, it is not | 960 // If the render surface's owning layer doesn't form a clip node, it is not |
| 806 // clipped. | 961 // clipped. |
| 807 if (render_surface->OwningLayerId() != clip_node->owner_id) | 962 if (render_surface->OwningLayerId() != clip_node->owner_id) |
| 808 render_surface->SetIsClipped(false); | 963 render_surface->SetIsClipped(false); |
| 809 else | 964 else |
| 810 render_surface->SetIsClipped(clip_node->data.target_is_clipped); | 965 render_surface->SetIsClipped(clip_node->data.target_is_clipped); |
| 811 } | 966 } |
| 812 | 967 |
| 813 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, | 968 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, |
| 814 const TransformTree& transform_tree, | 969 const TransformTree& transform_tree, |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1130 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1285 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
| 1131 const Layer* overscroll_elasticity_layer, | 1286 const Layer* overscroll_elasticity_layer, |
| 1132 const gfx::Vector2dF& elastic_overscroll) { | 1287 const gfx::Vector2dF& elastic_overscroll) { |
| 1133 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1288 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
| 1134 elastic_overscroll); | 1289 elastic_overscroll); |
| 1135 } | 1290 } |
| 1136 | 1291 |
| 1137 } // namespace draw_property_utils | 1292 } // namespace draw_property_utils |
| 1138 | 1293 |
| 1139 } // namespace cc | 1294 } // namespace cc |
| OLD | NEW |