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

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

Issue 687873004: Introduce Property Trees (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@wip-awoloszyn2
Patch Set: . Created 6 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "cc/trees/draw_property_utils.h"
6
7 #include <vector>
8
9 #include "cc/base/math_util.h"
10 #include "cc/layers/layer.h"
11 #include "cc/trees/property_tree.h"
12 #include "cc/trees/property_tree_builder.h"
13 #include "ui/gfx/geometry/rect_conversions.h"
14
15 namespace cc {
16
17 namespace {
18
19 void CalculateVisibleRects(
20 const std::vector<Layer*>& layers_that_need_visible_rects,
21 const ClipTree& clip_tree,
22 const TransformTree& transform_tree) {
23 for (size_t i = 0; i < layers_that_need_visible_rects.size(); ++i) {
24 Layer* layer = layers_that_need_visible_rects[i];
25
26 // TODO(ajuma): Compute content_scale rather than using it. Note that for
enne (OOO) 2014/12/10 23:45:59 I do wonder if we could punt on this until impl-si
enne (OOO) 2014/12/10 23:45:59 I do wonder if we could punt on this until impl-si
Ian Vollick 2014/12/12 03:01:47 sgtm! I've added another comment saying that once
27 // PictureLayer and PictureImageLayers, content_bounds == bounds and
28 // content_scale_x == content_scale_y == 1.0.
29 gfx::Size layer_content_bounds = layer->content_bounds();
30 float contents_scale_x = layer->contents_scale_x();
31 float contents_scale_y = layer->contents_scale_y();
32 const bool has_clip = layer->clip_tree_index() > 0;
33 if (has_clip && layer->has_render_target()) {
34 const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index());
35 const TransformNode* clip_transform_node =
36 transform_tree.Node(clip_node->data.transform_id);
37 const TransformNode* transform_node =
38 transform_tree.Node(layer->transform_tree_index());
39 const TransformNode* target_node =
40 transform_tree.Node(layer->render_target()->transform_tree_index());
41
42 gfx::Transform clip_to_target;
43 gfx::Transform content_to_target;
44 gfx::Transform target_to_content;
45
46 target_to_content.Scale(contents_scale_x, contents_scale_y);
47 target_to_content.Translate(-layer->offset_to_transform_parent().x(),
48 -layer->offset_to_transform_parent().y());
49
50 bool success = ComputeTransform(transform_tree, clip_transform_node->id,
51 target_node->id, &clip_to_target) &&
52 ComputeTransform(transform_tree, transform_node->id,
53 target_node->id, &content_to_target) &&
54 ComputeTransform(transform_tree, target_node->id,
55 transform_node->id, &target_to_content);
56
57 if (!success)
enne (OOO) 2014/12/10 23:45:59 What happens if this doesn't succeed? When does th
Ian Vollick 2014/12/12 03:01:47 If this doesn't succeed it means that an ancestor
enne (OOO) 2014/12/12 19:05:49 Could this just be a DCHECK instead?
Ian Vollick 2014/12/15 21:45:17 Done.
58 continue;
59
60 content_to_target.Translate(layer->offset_to_transform_parent().x(),
61 layer->offset_to_transform_parent().y());
62 content_to_target.Scale(1.0 / contents_scale_x, 1.0 / contents_scale_y);
63
64 gfx::Rect layer_content_rect = gfx::Rect(layer_content_bounds);
65 gfx::RectF layer_content_bounds_in_target_space =
66 MathUtil::MapClippedRect(content_to_target, layer_content_rect);
67 gfx::RectF clip_rect_in_target_space;
68 if (target_node->id > clip_node->id) {
69 clip_rect_in_target_space = MathUtil::ProjectClippedRect(
70 clip_to_target, clip_node->data.combined_clip);
71 } else {
72 clip_rect_in_target_space = MathUtil::MapClippedRect(
73 clip_to_target, clip_node->data.combined_clip);
74 }
75
76 clip_rect_in_target_space.Intersect(layer_content_bounds_in_target_space);
77
78 gfx::Rect visible_rect =
79 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
80 target_to_content, clip_rect_in_target_space));
81
82 visible_rect.Intersect(gfx::Rect(layer_content_bounds));
83
84 layer->set_debug_visible_rect(visible_rect);
85 } else {
86 layer->set_debug_visible_rect(gfx::Rect(layer_content_bounds));
87 }
88 }
89 }
90
91 void FindLayersThatNeedVisibleRects(Layer* layer,
92 std::vector<Layer*>* layers_to_update) {
93 if (layer->NeedsVisibleRectUpdated())
94 layers_to_update->push_back(layer);
95
96 for (size_t i = 0; i < layer->children().size(); ++i) {
97 FindLayersThatNeedVisibleRects(layer->children()[i].get(),
98 layers_to_update);
99 }
100 }
101
102 } // namespace
103
104 void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) {
105 for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) {
106 ClipNode* clip_node = clip_tree->Node(i);
107
108 // Only descendants of a real clipping layer (i.e., not 0) may have their
109 // clip adjusted due to intersecting with an ancestor clip.
110 const bool is_clipped = clip_node->parent_id > 0;
111 if (!is_clipped) {
112 clip_node->data.combined_clip = clip_node->data.clip;
113 continue;
114 }
115
116 ClipNode* parent_clip_node = clip_tree->parent(clip_node);
117 const TransformNode* parent_transform_node =
118 transform_tree.Node(parent_clip_node->data.transform_id);
119 const TransformNode* transform_node =
120 transform_tree.Node(clip_node->data.transform_id);
121
122 // Clips must be combined in target space. We cannot, for example, combine
123 // clips in the space of the child clip. The reason is non-affine
124 // transforms. Say we have the following tree T->A->B->C, and B clips C, but
125 // draw into target T. It may be the case that A applies a perspective
126 // transform, and B and C are at different z positions. When projected into
127 // target space, the relative sizes and positions of B and C can shift.
128 // Since it's the relationship in target space that matters, that's where we
129 // must combine clips.
130 gfx::Transform parent_to_target;
131 gfx::Transform clip_to_target;
132 gfx::Transform target_to_clip;
133
134 bool success =
135 ComputeTransform(transform_tree, parent_transform_node->id,
136 clip_node->data.target_id, &parent_to_target) &&
137 ComputeTransform(transform_tree, transform_node->id,
138 clip_node->data.target_id, &clip_to_target) &&
139 ComputeTransform(transform_tree, clip_node->data.target_id,
140 transform_node->id, &target_to_clip);
141
142 if (!success)
enne (OOO) 2014/12/10 23:45:59 What happens if this doesn't succeed?
Ian Vollick 2014/12/12 03:01:47 Added a comment with an explanation.
143 continue;
144
145 // In order to intersect with as small a rect as possible, we do a
146 // preliminary clip in target space so that when we project back, there's
147 // less likelihood of intersecting the view plane.
148 gfx::RectF inherited_clip_in_target_space = MathUtil::MapClippedRect(
149 parent_to_target, parent_clip_node->data.combined_clip);
150
151 gfx::RectF clip_in_target_space =
152 MathUtil::MapClippedRect(clip_to_target, clip_node->data.clip);
153
154 gfx::RectF intersected_in_target_space = gfx::IntersectRects(
155 inherited_clip_in_target_space, clip_in_target_space);
156
157 clip_node->data.combined_clip = MathUtil::ProjectClippedRect(
158 target_to_clip, intersected_in_target_space);
159
160 clip_node->data.combined_clip.Intersect(clip_node->data.clip);
161 }
162 }
163
164 void ComputeTransforms(TransformTree* transform_tree) {
165 for (int i = 0; i < static_cast<int>(transform_tree->size()); ++i)
166 UpdateScreenSpaceTransform(transform_tree, i);
167 }
168
169 void ComputeVisibleRectsUsingPropertyTrees(
170 Layer* root_layer,
171 const Layer* page_scale_layer,
172 float page_scale_factor,
173 float device_scale_factor,
174 const gfx::Rect& viewport,
175 const gfx::Transform& device_transform,
176 TransformTree* transform_tree,
177 ClipTree* clip_tree) {
178 std::vector<Layer*> layers_to_update;
179 FindLayersThatNeedVisibleRects(root_layer, &layers_to_update);
180
181 if (!layers_to_update.empty()) {
182 PropertyTreeBuilder::BuildPropertyTrees(
183 root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
184 viewport, device_transform, transform_tree, clip_tree);
185
186 ComputeTransforms(transform_tree);
187 ComputeClips(clip_tree, *transform_tree);
188 CalculateVisibleRects(layers_to_update, *clip_tree, *transform_tree);
189 }
190 }
191
192 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698