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

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: fix perftests compile by not verify clip tree calc there Created 4 years, 7 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 | « cc/trees/draw_property_utils.h ('k') | cc/trees/layer_tree_host_common.h » ('j') | no next file with comments »
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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 if (clip_node->data.target_id < target_node->id) { 155 if (clip_node->data.target_id < target_node->id) {
156 combined_clip_rect_in_target_space = 156 combined_clip_rect_in_target_space =
157 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( 157 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
158 clip_to_target, clip_node->data.clip_in_target_space)); 158 clip_to_target, clip_node->data.clip_in_target_space));
159 } else { 159 } else {
160 combined_clip_rect_in_target_space = 160 combined_clip_rect_in_target_space =
161 gfx::ToEnclosingRect(MathUtil::MapClippedRect( 161 gfx::ToEnclosingRect(MathUtil::MapClippedRect(
162 clip_to_target, clip_node->data.clip_in_target_space)); 162 clip_to_target, clip_node->data.clip_in_target_space));
163 } 163 }
164 clip_rect_in_target_space = combined_clip_rect_in_target_space; 164 clip_rect_in_target_space = combined_clip_rect_in_target_space;
165
166 } else { 165 } else {
167 clip_rect_in_target_space = 166 clip_rect_in_target_space =
168 gfx::ToEnclosingRect(clip_node->data.clip_in_target_space); 167 gfx::ToEnclosingRect(clip_node->data.clip_in_target_space);
169 if (clip_node->data.target_is_clipped || !non_root_surfaces_enabled) 168 if (clip_node->data.target_is_clipped || !non_root_surfaces_enabled)
170 combined_clip_rect_in_target_space = gfx::ToEnclosingRect( 169 combined_clip_rect_in_target_space = gfx::ToEnclosingRect(
171 clip_node->data.combined_clip_in_target_space); 170 clip_node->data.combined_clip_in_target_space);
172 else 171 else
173 combined_clip_rect_in_target_space = clip_rect_in_target_space; 172 combined_clip_rect_in_target_space = clip_rect_in_target_space;
174 } 173 }
175 174
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 return; 359 return;
361 } 360 }
362 361
363 EffectNode* node = effect_tree->Node(layer->effect_tree_index()); 362 EffectNode* node = effect_tree->Node(layer->effect_tree_index());
364 363
365 if (node->owner_id == layer->id() && node->data.has_render_surface) 364 if (node->owner_id == layer->id() && node->data.has_render_surface)
366 layer->SetHasRenderSurface(true); 365 layer->SetHasRenderSurface(true);
367 else 366 else
368 layer->SetHasRenderSurface(false); 367 layer->SetHasRenderSurface(false);
369 } 368 }
370
371 } // namespace 369 } // namespace
372 370
373 template <typename LayerType> 371 template <typename LayerType>
374 static inline bool LayerShouldBeSkippedInternal( 372 static inline bool LayerShouldBeSkippedInternal(
375 LayerType* layer, 373 LayerType* layer,
376 bool layer_is_drawn, 374 bool layer_is_drawn,
377 const TransformTree& transform_tree, 375 const TransformTree& transform_tree,
378 const EffectTree& effect_tree) { 376 const EffectTree& effect_tree) {
379 const TransformNode* transform_node = 377 const TransformNode* transform_node =
380 transform_tree.Node(layer->transform_tree_index()); 378 transform_tree.Node(layer->transform_tree_index());
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 } 606 }
609 607
610 void ComputeEffects(EffectTree* effect_tree) { 608 void ComputeEffects(EffectTree* effect_tree) {
611 if (!effect_tree->needs_update()) 609 if (!effect_tree->needs_update())
612 return; 610 return;
613 for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) 611 for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i)
614 effect_tree->UpdateEffects(i); 612 effect_tree->UpdateEffects(i);
615 effect_tree->set_needs_update(false); 613 effect_tree->set_needs_update(false);
616 } 614 }
617 615
616 static gfx::RectF ComputeCurrentClip(const ClipNode* clip_node,
617 const TransformTree& transform_tree,
618 int target_transform_id) {
619 if (clip_node->data.transform_id != target_transform_id) {
620 gfx::Transform current_to_target;
621 if (!transform_tree.ComputeTransformWithDestinationSublayerScale(
622 clip_node->data.transform_id, target_transform_id,
623 &current_to_target))
624 return gfx::RectF();
625 if (clip_node->data.transform_id > target_transform_id)
626 return MathUtil::MapClippedRect(current_to_target, clip_node->data.clip);
627 else
628 return MathUtil::ProjectClippedRect(current_to_target,
629 clip_node->data.clip);
630 } else {
631 gfx::RectF current_clip = clip_node->data.clip;
632 gfx::Vector2dF sublayer_scale =
633 transform_tree.Node(target_transform_id)->data.sublayer_scale;
634 if (sublayer_scale.x() > 0 && sublayer_scale.y() > 0) {
635 current_clip.Scale(sublayer_scale.x(), sublayer_scale.y());
636 }
637 return current_clip;
638 }
639 }
640
641 static gfx::RectF ComputeAccumulatedClip(const ClipTree& clip_tree,
642 int local_clip_id,
643 const EffectTree& effect_tree,
644 int target_id,
645 const TransformTree& transform_tree) {
646 const ClipNode* clip_node = clip_tree.Node(local_clip_id);
647 const EffectNode* target_node = effect_tree.Node(target_id);
648 int target_transform_id = target_node->data.transform_id;
649
650 // Collect all the clips that need to be accumulated.
651 std::stack<const ClipNode*> parent_chain;
652
653 // If target is not direct ancestor of clip, this will find least common
654 // ancestor between the target and the clip.
655 while (target_node->id >= 0 && clip_node->id >= 0) {
656 while (target_node->data.clip_id > clip_node->id ||
657 target_node->data.has_unclipped_descendants) {
658 target_node = effect_tree.Node(target_node->data.target_id);
659 }
660 if (target_node->data.clip_id == clip_node->id)
661 break;
662 while (target_node->data.clip_id < clip_node->id) {
663 parent_chain.push(clip_node);
664 clip_node = clip_tree.parent(clip_node);
665 }
666 if (target_node->data.clip_id == clip_node->id) {
667 clip_node = parent_chain.top();
668 parent_chain.pop();
669 break;
670 }
671 }
672
673 // TODO(weiliangc): If we don't create clip for render surface, we don't need
674 // to check applies_local_clip.
675 while (!clip_node->data.applies_local_clip && parent_chain.size() > 0) {
676 clip_node = parent_chain.top();
677 parent_chain.pop();
678 }
679
680 if (!clip_node->data.applies_local_clip)
681 return gfx::RectF();
682
683 gfx::RectF accumulated_clip =
684 ComputeCurrentClip(clip_node, transform_tree, target_transform_id);
685
686 while (parent_chain.size() > 0) {
687 clip_node = parent_chain.top();
688 parent_chain.pop();
689 if (!clip_node->data.applies_local_clip) {
690 continue;
691 }
692 gfx::RectF current_clip =
693 ComputeCurrentClip(clip_node, transform_tree, target_transform_id);
694
695 if (current_clip.IsEmpty())
696 return gfx::RectF();
697
698 accumulated_clip = gfx::IntersectRects(accumulated_clip, current_clip);
699 }
700
701 return accumulated_clip.IsEmpty() ? gfx::RectF() : accumulated_clip;
702 }
703
704 static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) {
705 EffectTree* effect_tree = &property_trees->effect_tree;
706 const ClipTree* clip_tree = &property_trees->clip_tree;
707 const TransformTree* transform_tree = &property_trees->transform_tree;
708 EffectNode* root_effect_node = effect_tree->Node(1);
709 const RenderSurfaceImpl* root_render_surface =
710 root_effect_node->data.render_surface;
711 gfx::Rect root_clip = gfx::ToEnclosingRect(
712 clip_tree->Node(root_effect_node->data.clip_id)->data.clip);
713 if (root_render_surface->is_clipped())
714 DCHECK(root_clip == root_render_surface->clip_rect())
715 << "clip on root render surface: "
716 << root_render_surface->clip_rect().ToString()
717 << " v.s. root effect node's clip: " << root_clip.ToString();
718 for (int i = 2; i < static_cast<int>(effect_tree->size()); ++i) {
719 EffectNode* effect_node = effect_tree->Node(i);
720 const EffectNode* target_node =
721 effect_tree->Node(effect_node->data.target_id);
722 gfx::RectF accumulated_clip =
723 ComputeAccumulatedClip(*clip_tree, effect_node->data.clip_id,
724 *effect_tree, target_node->id, *transform_tree);
725 const RenderSurfaceImpl* render_surface = effect_node->data.render_surface;
726 if (render_surface && render_surface->is_clipped()) {
727 DCHECK(gfx::ToEnclosingRect(accumulated_clip) ==
728 render_surface->clip_rect())
729 << " render surface's clip rect: "
730 << render_surface->clip_rect().ToString()
731 << " v.s. accumulated clip: "
732 << gfx::ToEnclosingRect(accumulated_clip).ToString();
733 }
734 }
735 }
736
737 static void ComputeLayerClipRect(const PropertyTrees* property_trees,
738 const LayerImpl* layer) {
739 const EffectTree* effect_tree = &property_trees->effect_tree;
740 const ClipTree* clip_tree = &property_trees->clip_tree;
741 const TransformTree* transform_tree = &property_trees->transform_tree;
742 const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index());
743 const EffectNode* target_node =
744 effect_node->data.has_render_surface
745 ? effect_node
746 : effect_tree->Node(effect_node->data.target_id);
747 // TODO(weiliangc): When effect node has up to date render surface info on
748 // compositor thread, no need to check for resourceless draw mode
749 if (!property_trees->non_root_surfaces_enabled) {
750 target_node = effect_tree->Node(1);
751 }
752
753 gfx::RectF accumulated_clip =
754 ComputeAccumulatedClip(*clip_tree, layer->clip_tree_index(), *effect_tree,
755 target_node->id, *transform_tree);
756
757 if ((!property_trees->non_root_surfaces_enabled &&
758 clip_tree->Node(layer->clip_tree_index())
759 ->data.layers_are_clipped_when_surfaces_disabled) ||
760 clip_tree->Node(layer->clip_tree_index())->data.layers_are_clipped) {
761 DCHECK(layer->clip_rect() == gfx::ToEnclosingRect(accumulated_clip))
762 << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index()
763 << " layer clip: " << layer->clip_rect().ToString() << " v.s. "
764 << gfx::ToEnclosingRect(accumulated_clip).ToString()
765 << " and clip node clip: "
766 << gfx::ToEnclosingRect(clip_tree->Node(layer->clip_tree_index())
767 ->data.clip_in_target_space)
768 .ToString();
769 }
770 }
771
618 static void ComputeVisibleRectsInternal( 772 static void ComputeVisibleRectsInternal(
619 LayerImpl* root_layer, 773 LayerImpl* root_layer,
620 PropertyTrees* property_trees, 774 PropertyTrees* property_trees,
621 bool can_render_to_separate_surface, 775 bool can_render_to_separate_surface,
622 LayerImplList* update_layer_list, 776 LayerImplList* update_layer_list,
623 std::vector<LayerImpl*>* visible_layer_list) { 777 std::vector<LayerImpl*>* visible_layer_list) {
624 if (property_trees->non_root_surfaces_enabled != 778 if (property_trees->non_root_surfaces_enabled !=
625 can_render_to_separate_surface) { 779 can_render_to_separate_surface) {
626 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; 780 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface;
627 property_trees->transform_tree.set_needs_update(true); 781 property_trees->transform_tree.set_needs_update(true);
(...skipping 10 matching lines...) Expand all
638 FindLayersThatNeedUpdates( 792 FindLayersThatNeedUpdates(
639 root_layer->layer_tree_impl(), property_trees->transform_tree, 793 root_layer->layer_tree_impl(), property_trees->transform_tree,
640 property_trees->effect_tree, update_layer_list, visible_layer_list); 794 property_trees->effect_tree, update_layer_list, visible_layer_list);
641 CalculateVisibleRects<LayerImpl>( 795 CalculateVisibleRects<LayerImpl>(
642 *visible_layer_list, property_trees->clip_tree, 796 *visible_layer_list, property_trees->clip_tree,
643 property_trees->transform_tree, can_render_to_separate_surface); 797 property_trees->transform_tree, can_render_to_separate_surface);
644 } 798 }
645 799
646 void UpdateRenderSurfaces(Layer* root_layer, PropertyTrees* property_trees) { 800 void UpdateRenderSurfaces(Layer* root_layer, PropertyTrees* property_trees) {
647 for (auto* layer : *root_layer->layer_tree_host()) { 801 for (auto* layer : *root_layer->layer_tree_host()) {
648 UpdateRenderSurfaceForLayer(&property_trees->effect_tree, true, layer); 802 UpdateRenderSurfaceForLayer(&property_trees->effect_tree,
803 property_trees->non_root_surfaces_enabled,
804 layer);
649 #if DCHECK_IS_ON() 805 #if DCHECK_IS_ON()
650 ValidateRenderSurfaceForLayer(layer); 806 ValidateRenderSurfaceForLayer(layer);
651 #endif 807 #endif
652 } 808 }
653 } 809 }
654 810
655 void UpdatePropertyTrees(PropertyTrees* property_trees, 811 void UpdatePropertyTrees(PropertyTrees* property_trees,
656 bool can_render_to_separate_surface) { 812 bool can_render_to_separate_surface) {
657 if (property_trees->non_root_surfaces_enabled != 813 if (property_trees->non_root_surfaces_enabled !=
658 can_render_to_separate_surface) { 814 can_render_to_separate_surface) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 LayerImplList* visible_layer_list) { 847 LayerImplList* visible_layer_list) {
692 PropertyTreeBuilder::BuildPropertyTrees( 848 PropertyTreeBuilder::BuildPropertyTrees(
693 root_layer, page_scale_layer, inner_viewport_scroll_layer, 849 root_layer, page_scale_layer, inner_viewport_scroll_layer,
694 outer_viewport_scroll_layer, overscroll_elasticity_layer, 850 outer_viewport_scroll_layer, overscroll_elasticity_layer,
695 elastic_overscroll, page_scale_factor, device_scale_factor, viewport, 851 elastic_overscroll, page_scale_factor, device_scale_factor, viewport,
696 device_transform, property_trees); 852 device_transform, property_trees);
697 ComputeVisibleRects(root_layer, property_trees, 853 ComputeVisibleRects(root_layer, property_trees,
698 can_render_to_separate_surface, visible_layer_list); 854 can_render_to_separate_surface, visible_layer_list);
699 } 855 }
700 856
857 void VerifyClipTreeCalculations(const LayerImplList& layer_list,
858 PropertyTrees* property_trees) {
859 if (property_trees->non_root_surfaces_enabled) {
860 ComputeClipsWithEffectTree(property_trees);
861 }
862 for (auto layer : layer_list)
863 ComputeLayerClipRect(property_trees, layer);
864 }
865
701 void ComputeVisibleRects(LayerImpl* root_layer, 866 void ComputeVisibleRects(LayerImpl* root_layer,
702 PropertyTrees* property_trees, 867 PropertyTrees* property_trees,
703 bool can_render_to_separate_surface, 868 bool can_render_to_separate_surface,
704 LayerImplList* visible_layer_list) { 869 LayerImplList* visible_layer_list) {
705 for (auto* layer : *root_layer->layer_tree_impl()) { 870 for (auto* layer : *root_layer->layer_tree_impl()) {
706 UpdateRenderSurfaceForLayer(&property_trees->effect_tree, 871 UpdateRenderSurfaceForLayer(&property_trees->effect_tree,
707 can_render_to_separate_surface, layer); 872 can_render_to_separate_surface, layer);
708 EffectNode* node = 873 EffectNode* node =
709 property_trees->effect_tree.Node(layer->effect_tree_index()); 874 property_trees->effect_tree.Node(layer->effect_tree_index());
710 if (node->owner_id == layer->id()) 875 if (node->owner_id == layer->id())
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 &render_surface_transform); 933 &render_surface_transform);
769 if (node->data.sublayer_scale.x() != 0.0 && 934 if (node->data.sublayer_scale.x() != 0.0 &&
770 node->data.sublayer_scale.y() != 0.0) 935 node->data.sublayer_scale.y() != 0.0)
771 render_surface_transform.Scale(1.0 / node->data.sublayer_scale.x(), 936 render_surface_transform.Scale(1.0 / node->data.sublayer_scale.x(),
772 1.0 / node->data.sublayer_scale.y()); 937 1.0 / node->data.sublayer_scale.y());
773 render_surface->SetDrawTransform(render_surface_transform); 938 render_surface->SetDrawTransform(render_surface_transform);
774 } 939 }
775 940
776 static void SetSurfaceIsClipped(const ClipNode* clip_node, 941 static void SetSurfaceIsClipped(const ClipNode* clip_node,
777 RenderSurfaceImpl* render_surface) { 942 RenderSurfaceImpl* render_surface) {
778 // If the render surface's owning layer doesn't form a clip node, it is not 943 DCHECK(render_surface->OwningLayerId() == clip_node->owner_id)
779 // clipped. 944 << "we now create clip node for every render surface";
780 if (render_surface->OwningLayerId() != clip_node->owner_id) 945
781 render_surface->SetIsClipped(false); 946 render_surface->SetIsClipped(clip_node->data.target_is_clipped);
782 else
783 render_surface->SetIsClipped(clip_node->data.target_is_clipped);
784 } 947 }
785 948
786 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, 949 static void SetSurfaceClipRect(const ClipNode* parent_clip_node,
787 const TransformTree& transform_tree, 950 const TransformTree& transform_tree,
788 RenderSurfaceImpl* render_surface) { 951 RenderSurfaceImpl* render_surface) {
789 if (!render_surface->is_clipped()) { 952 if (!render_surface->is_clipped()) {
790 render_surface->SetClipRect(gfx::Rect()); 953 render_surface->SetClipRect(gfx::Rect());
791 return; 954 return;
792 } 955 }
793 956
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 void UpdateElasticOverscroll(PropertyTrees* property_trees, 1276 void UpdateElasticOverscroll(PropertyTrees* property_trees,
1114 const Layer* overscroll_elasticity_layer, 1277 const Layer* overscroll_elasticity_layer,
1115 const gfx::Vector2dF& elastic_overscroll) { 1278 const gfx::Vector2dF& elastic_overscroll) {
1116 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, 1279 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer,
1117 elastic_overscroll); 1280 elastic_overscroll);
1118 } 1281 }
1119 1282
1120 } // namespace draw_property_utils 1283 } // namespace draw_property_utils
1121 1284
1122 } // namespace cc 1285 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/draw_property_utils.h ('k') | cc/trees/layer_tree_host_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698