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

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: clean up and try 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
« no previous file with comments | « no previous file | cc/trees/property_tree.h » ('j') | cc/trees/property_tree.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 } 444 }
446 445
447 for (size_t i = 0; i < layer->children().size(); ++i) { 446 for (size_t i = 0; i < layer->children().size(); ++i) {
448 FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree, 447 FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree,
449 update_layer_list, visible_layer_list); 448 update_layer_list, visible_layer_list);
450 } 449 }
451 } 450 }
452 451
453 template <typename LayerType> 452 template <typename LayerType>
454 void UpdateRenderSurfacesWithEffectTreeInternal(EffectTree* effect_tree, 453 void UpdateRenderSurfacesWithEffectTreeInternal(EffectTree* effect_tree,
455 LayerType* layer) { 454 LayerType* layer,
455 int target_id) {
456 EffectNode* node = effect_tree->Node(layer->effect_tree_index()); 456 EffectNode* node = effect_tree->Node(layer->effect_tree_index());
457 if (node->owner_id == layer->id())
458 node->data.target_id = target_id;
457 459
458 if (node->owner_id == layer->id() && node->data.has_render_surface) 460 if (node->owner_id == layer->id() && node->data.has_render_surface) {
459 layer->SetHasRenderSurface(true); 461 layer->SetHasRenderSurface(true);
460 else 462 target_id = node->id;
463 } else {
461 layer->SetHasRenderSurface(false); 464 layer->SetHasRenderSurface(false);
465 }
462 466
463 for (size_t i = 0; i < layer->children().size(); ++i) { 467 for (size_t i = 0; i < layer->children().size(); ++i) {
464 UpdateRenderSurfacesWithEffectTreeInternal<LayerType>(effect_tree, 468 UpdateRenderSurfacesWithEffectTreeInternal<LayerType>(
465 layer->child_at(i)); 469 effect_tree, layer->child_at(i), target_id);
466 } 470 }
467 } 471 }
468 472
469 void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, Layer* layer) { 473 void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, Layer* layer) {
470 UpdateRenderSurfacesWithEffectTreeInternal<Layer>(effect_tree, layer); 474 UpdateRenderSurfacesWithEffectTreeInternal<Layer>(effect_tree, layer, 0);
471 } 475 }
472 476
473 void UpdateRenderSurfacesNonRootSurfacesDisabled(LayerImpl* layer) { 477 void UpdateRenderSurfacesNonRootSurfacesDisabled(LayerImpl* layer) {
474 // Only root layer has render surface, all other layers don't. 478 // Only root layer has render surface, all other layers don't.
475 layer->SetHasRenderSurface(!layer->parent()); 479 layer->SetHasRenderSurface(!layer->parent());
476 480
477 for (size_t i = 0; i < layer->children().size(); ++i) 481 for (size_t i = 0; i < layer->children().size(); ++i)
478 UpdateRenderSurfacesNonRootSurfacesDisabled(layer->child_at(i)); 482 UpdateRenderSurfacesNonRootSurfacesDisabled(layer->child_at(i));
479 } 483 }
480 484
481 void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree, 485 void UpdateRenderSurfacesWithEffectTree(EffectTree* effect_tree,
482 bool non_root_surfaces_enabled, 486 bool non_root_surfaces_enabled,
483 LayerImpl* layer) { 487 LayerImpl* layer) {
484 if (!non_root_surfaces_enabled) 488 if (!non_root_surfaces_enabled)
485 UpdateRenderSurfacesNonRootSurfacesDisabled(layer); 489 UpdateRenderSurfacesNonRootSurfacesDisabled(layer);
486 else 490 else
487 UpdateRenderSurfacesWithEffectTreeInternal<LayerImpl>(effect_tree, layer); 491 UpdateRenderSurfacesWithEffectTreeInternal<LayerImpl>(effect_tree, layer,
492 0);
488 } 493 }
489 494
490 } // namespace 495 } // namespace
491 496
492 static void ResetIfHasNanCoordinate(gfx::RectF* rect) { 497 static void ResetIfHasNanCoordinate(gfx::RectF* rect) {
493 if (std::isnan(rect->x()) || std::isnan(rect->y()) || 498 if (std::isnan(rect->x()) || std::isnan(rect->y()) ||
494 std::isnan(rect->right()) || std::isnan(rect->bottom())) 499 std::isnan(rect->right()) || std::isnan(rect->bottom()))
495 *rect = gfx::RectF(); 500 *rect = gfx::RectF();
496 } 501 }
497 502
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 } 647 }
643 648
644 void ComputeEffects(EffectTree* effect_tree) { 649 void ComputeEffects(EffectTree* effect_tree) {
645 if (!effect_tree->needs_update()) 650 if (!effect_tree->needs_update())
646 return; 651 return;
647 for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) 652 for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i)
648 effect_tree->UpdateEffects(i); 653 effect_tree->UpdateEffects(i);
649 effect_tree->set_needs_update(false); 654 effect_tree->set_needs_update(false);
650 } 655 }
651 656
657 static gfx::RectF ComputeCurrentClip(const ClipNode* clip_node,
658 const TransformTree& transform_tree,
659 int target_transform_id) {
660 if (clip_node->data.transform_id != target_transform_id) {
661 gfx::Transform current_to_target;
662 if (!transform_tree.ComputeTransformWithDestinationSublayerScale(
663 clip_node->data.transform_id, target_transform_id,
664 &current_to_target))
665 return gfx::RectF();
666 if (clip_node->data.transform_id > target_transform_id)
667 return MathUtil::MapClippedRect(current_to_target, clip_node->data.clip);
668 else
669 return MathUtil::ProjectClippedRect(current_to_target,
670 clip_node->data.clip);
671 } else {
672 gfx::RectF current_clip = clip_node->data.clip;
673 gfx::Vector2dF sublayer_scale =
674 transform_tree.Node(target_transform_id)->data.sublayer_scale;
675 if (sublayer_scale.x() > 0 && sublayer_scale.y() > 0) {
676 current_clip.Scale(sublayer_scale.x(), sublayer_scale.y());
677 }
678 return current_clip;
679 }
680 NOTREACHED();
681 return gfx::RectF();
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 if (local_clip_id == target_node->data.clip_id)
ajuma 2016/03/15 14:59:56 This confused me for a bit since it seemed like th
weiliangc 2016/03/15 15:29:36 This is a special case I started with, but is no l
693 return ComputeCurrentClip(clip_tree.Node(local_clip_id), transform_tree,
694 target_transform_id);
695
696 // Collect all the clips that need to be accumulated.
697 std::stack<const ClipNode*> parent_chain;
698
699 // If target is not direct ancestor of clip, this will find least common
700 // ancestor between the target and the clip.
701 while (target_node->id >= 0 && clip_node->id >= 0) {
702 while (target_node->data.clip_id > clip_node->id ||
703 target_node->data.has_unclipped_descendants) {
704 target_node = effect_tree.Node(target_node->data.target_id);
705 }
706 if (target_node->data.clip_id == clip_node->id)
707 break;
708 while (target_node->data.clip_id < clip_node->id) {
709 parent_chain.push(clip_node);
710 clip_node = clip_tree.parent(clip_node);
711 }
712 if (target_node->data.clip_id == clip_node->id) {
713 clip_node = parent_chain.top();
714 parent_chain.pop();
715 break;
716 }
717 }
718
719 // TODO(weiliangc): If we don't create clip for render surface, we don't need
720 // to check applies_local_clip.
721 while (clip_node->id != 1 && !clip_node->data.applies_local_clip &&
722 parent_chain.size() > 0) {
723 clip_node = parent_chain.top();
724 parent_chain.pop();
725 }
726
727 if (!clip_node->data.applies_local_clip && clip_node->id != 1)
728 return gfx::RectF();
729
730 gfx::RectF accumulated_clip =
731 ComputeCurrentClip(clip_node, transform_tree, target_transform_id);
732
733 while (parent_chain.size() > 0) {
734 clip_node = parent_chain.top();
735 parent_chain.pop();
736 if (!clip_node->data.applies_local_clip && clip_node->id != 1) {
ajuma 2016/03/15 14:59:56 Do we still need this special handling for the vie
weiliangc 2016/03/15 15:29:36 No, I realized viewport clip always applies local
737 continue;
738 }
739 gfx::RectF current_clip =
740 ComputeCurrentClip(clip_node, transform_tree, target_transform_id);
741 accumulated_clip = gfx::IntersectRects(accumulated_clip, current_clip);
742 }
743
744 return 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 CHECK(accumulated_clip == clip_node->data.clip_in_target_space);
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 ||
786 clip_tree->Node(layer->clip_tree_index())->data.layers_are_clipped) {
787 CHECK(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
652 template <typename LayerType> 798 template <typename LayerType>
653 static void ComputeVisibleRectsInternal( 799 static void ComputeVisibleRectsInternal(
654 LayerType* root_layer, 800 LayerType* root_layer,
655 PropertyTrees* property_trees, 801 PropertyTrees* property_trees,
656 bool can_render_to_separate_surface, 802 bool can_render_to_separate_surface,
657 typename LayerType::LayerListType* update_layer_list, 803 typename LayerType::LayerListType* update_layer_list,
658 std::vector<LayerType*>* visible_layer_list) { 804 std::vector<LayerType*>* visible_layer_list) {
659 if (property_trees->non_root_surfaces_enabled != 805 if (property_trees->non_root_surfaces_enabled !=
660 can_render_to_separate_surface) { 806 can_render_to_separate_surface) {
661 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; 807 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 } 881 }
736 882
737 void ComputeVisibleRects(LayerImpl* root_layer, 883 void ComputeVisibleRects(LayerImpl* root_layer,
738 PropertyTrees* property_trees, 884 PropertyTrees* property_trees,
739 bool can_render_to_separate_surface, 885 bool can_render_to_separate_surface,
740 LayerImplList* visible_layer_list) { 886 LayerImplList* visible_layer_list) {
741 UpdateRenderSurfacesWithEffectTree( 887 UpdateRenderSurfacesWithEffectTree(
742 &property_trees->effect_tree, can_render_to_separate_surface, root_layer); 888 &property_trees->effect_tree, can_render_to_separate_surface, root_layer);
743 if (can_render_to_separate_surface) 889 if (can_render_to_separate_surface)
744 ValidateRenderSurfaces(root_layer); 890 ValidateRenderSurfaces(root_layer);
891 if (can_render_to_separate_surface)
892 ComputeClipsWithEffectTree(property_trees);
745 LayerImplList update_layer_list; 893 LayerImplList update_layer_list;
746 ComputeVisibleRectsInternal(root_layer, property_trees, 894 ComputeVisibleRectsInternal(root_layer, property_trees,
747 can_render_to_separate_surface, 895 can_render_to_separate_surface,
748 &update_layer_list, visible_layer_list); 896 &update_layer_list, visible_layer_list);
897 if (can_render_to_separate_surface)
898 for (auto layer : *visible_layer_list)
899 ComputeLayerClipRect(property_trees, layer);
749 } 900 }
750 901
751 template <typename LayerType> 902 template <typename LayerType>
752 static gfx::Transform DrawTransformInternal(const LayerType* layer, 903 static gfx::Transform DrawTransformInternal(const LayerType* layer,
753 const TransformNode* node) { 904 const TransformNode* node) {
754 gfx::Transform xform; 905 gfx::Transform xform;
755 const bool owns_non_root_surface = 906 const bool owns_non_root_surface =
756 layer->parent() && layer->has_render_surface(); 907 layer->parent() && layer->has_render_surface();
757 if (!owns_non_root_surface) { 908 if (!owns_non_root_surface) {
758 // If you're not the root, or you don't own a surface, you need to apply 909 // If you're not the root, or you don't own a surface, you need to apply
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 &render_surface_transform); 944 &render_surface_transform);
794 if (node->data.sublayer_scale.x() != 0.0 && 945 if (node->data.sublayer_scale.x() != 0.0 &&
795 node->data.sublayer_scale.y() != 0.0) 946 node->data.sublayer_scale.y() != 0.0)
796 render_surface_transform.Scale(1.0 / node->data.sublayer_scale.x(), 947 render_surface_transform.Scale(1.0 / node->data.sublayer_scale.x(),
797 1.0 / node->data.sublayer_scale.y()); 948 1.0 / node->data.sublayer_scale.y());
798 render_surface->SetDrawTransform(render_surface_transform); 949 render_surface->SetDrawTransform(render_surface_transform);
799 } 950 }
800 951
801 static void SetSurfaceIsClipped(const ClipNode* clip_node, 952 static void SetSurfaceIsClipped(const ClipNode* clip_node,
802 RenderSurfaceImpl* render_surface) { 953 RenderSurfaceImpl* render_surface) {
954 DCHECK(render_surface->OwningLayerId() == clip_node->owner_id)
955 << "we now create clip node for every render surface";
803 // If the render surface's owning layer doesn't form a clip node, it is not 956 // If the render surface's owning layer doesn't form a clip node, it is not
804 // clipped. 957 // clipped.
805 if (render_surface->OwningLayerId() != clip_node->owner_id) 958 if (render_surface->OwningLayerId() != clip_node->owner_id)
806 render_surface->SetIsClipped(false); 959 render_surface->SetIsClipped(false);
807 else 960 else
808 render_surface->SetIsClipped(clip_node->data.target_is_clipped); 961 render_surface->SetIsClipped(clip_node->data.target_is_clipped);
809 } 962 }
810 963
811 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, 964 static void SetSurfaceClipRect(const ClipNode* parent_clip_node,
812 const TransformTree& transform_tree, 965 const TransformTree& transform_tree,
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 replica_to_surface); 1186 replica_to_surface);
1034 render_surface->SetReplicaScreenSpaceTransform( 1187 render_surface->SetReplicaScreenSpaceTransform(
1035 render_surface->screen_space_transform() * replica_to_surface); 1188 render_surface->screen_space_transform() * replica_to_surface);
1036 } else { 1189 } else {
1037 render_surface->SetReplicaDrawTransform(gfx::Transform()); 1190 render_surface->SetReplicaDrawTransform(gfx::Transform());
1038 render_surface->SetReplicaScreenSpaceTransform(gfx::Transform()); 1191 render_surface->SetReplicaScreenSpaceTransform(gfx::Transform());
1039 } 1192 }
1040 1193
1041 SetSurfaceClipRect(property_trees->clip_tree.parent(clip_node), 1194 SetSurfaceClipRect(property_trees->clip_tree.parent(clip_node),
1042 property_trees->transform_tree, render_surface); 1195 property_trees->transform_tree, render_surface);
1196
1197 if (!property_trees->non_root_surfaces_enabled)
1198 return;
1199
1200 if (render_surface->is_clipped()) {
1201 const EffectNode* effect_node =
1202 property_trees->effect_tree.Node(render_surface->EffectTreeIndex());
1203 DCHECK(effect_node->data.has_render_surface);
1204 CHECK(effect_node->data.clip_rect == render_surface->clip_rect())
1205 << "effect tree's: " << effect_node->data.clip_rect.ToString()
1206 << " clip: " << render_surface->clip_rect().ToString();
1207 }
1043 } 1208 }
1044 1209
1045 template <typename LayerType> 1210 template <typename LayerType>
1046 static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees, 1211 static void UpdatePageScaleFactorInternal(PropertyTrees* property_trees,
1047 const LayerType* page_scale_layer, 1212 const LayerType* page_scale_layer,
1048 float page_scale_factor, 1213 float page_scale_factor,
1049 float device_scale_factor, 1214 float device_scale_factor,
1050 gfx::Transform device_transform) { 1215 gfx::Transform device_transform) {
1051 if (property_trees->transform_tree.page_scale_factor() == page_scale_factor) 1216 if (property_trees->transform_tree.page_scale_factor() == page_scale_factor)
1052 return; 1217 return;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 void UpdateElasticOverscroll(PropertyTrees* property_trees, 1293 void UpdateElasticOverscroll(PropertyTrees* property_trees,
1129 const Layer* overscroll_elasticity_layer, 1294 const Layer* overscroll_elasticity_layer,
1130 const gfx::Vector2dF& elastic_overscroll) { 1295 const gfx::Vector2dF& elastic_overscroll) {
1131 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, 1296 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer,
1132 elastic_overscroll); 1297 elastic_overscroll);
1133 } 1298 }
1134 1299
1135 } // namespace draw_property_utils 1300 } // namespace draw_property_utils
1136 1301
1137 } // namespace cc 1302 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | cc/trees/property_tree.h » ('j') | cc/trees/property_tree.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698