Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: cc/trees/draw_property_utils.cc

Issue 1800923002: cc: Directly use property trees to calculate clip rect (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add setting to only calculate and verify in cc_unittest Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 &current_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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698