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

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

Issue 816543004: Update from https://crrev.com/308996 (Closed) Base URL: git@github.com:domokit/mojo.git@master
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
« no previous file with comments | « cc/trees/property_tree_builder.h ('k') | cc/trees/property_tree_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/property_tree_builder.h"
6
7 #include <map>
8 #include <set>
9
10 #include "cc/base/math_util.h"
11 #include "cc/layers/layer.h"
12 #include "cc/trees/layer_tree_host.h"
13 #include "ui/gfx/point_f.h"
14
15 namespace cc {
16
17 class LayerTreeHost;
18
19 namespace {
20
21 struct DataForRecursion {
22 TransformTree* transform_tree;
23 ClipTree* clip_tree;
24 Layer* transform_tree_parent;
25 Layer* transform_fixed_parent;
26 Layer* render_target;
27 int clip_tree_parent;
28 gfx::Vector2dF offset_to_transform_tree_parent;
29 gfx::Vector2dF offset_to_transform_fixed_parent;
30 const Layer* page_scale_layer;
31 float page_scale_factor;
32 float device_scale_factor;
33 };
34
35 static Layer* GetTransformParent(const DataForRecursion& data, Layer* layer) {
36 return layer->position_constraint().is_fixed_position()
37 ? data.transform_fixed_parent
38 : data.transform_tree_parent;
39 }
40
41 static ClipNode* GetClipParent(const DataForRecursion& data, Layer* layer) {
42 const bool inherits_clip = !layer->parent() || !layer->clip_parent();
43 const int id = inherits_clip ? data.clip_tree_parent
44 : layer->clip_parent()->clip_tree_index();
45 return data.clip_tree->Node(id);
46 }
47
48 static bool RequiresClipNode(Layer* layer,
49 bool axis_aligned_with_respect_to_parent) {
50 const bool render_surface_applies_non_axis_aligned_clip =
51 layer->render_surface() && !axis_aligned_with_respect_to_parent &&
52 layer->is_clipped();
53 const bool render_surface_may_grow_due_to_clip_children =
54 layer->render_surface() && layer->num_unclipped_descendants() > 0;
55
56 return !layer->parent() || layer->masks_to_bounds() || layer->mask_layer() ||
57 render_surface_applies_non_axis_aligned_clip ||
58 render_surface_may_grow_due_to_clip_children;
59 }
60
61 void AddClipNodeIfNeeded(const DataForRecursion& data_from_ancestor,
62 Layer* layer,
63 DataForRecursion* data_for_children) {
64 ClipNode* parent = GetClipParent(data_from_ancestor, layer);
65 int parent_id = parent->id;
66 const bool axis_aligned_with_respect_to_parent =
67 data_from_ancestor.transform_tree->Are2DAxisAligned(
68 layer->transform_tree_index(), parent->data.transform_id);
69
70 // TODO(vollick): once Andrew refactors the surface determinations out of
71 // CDP, the the layer->render_surface() check will be invalid.
72 const bool has_unclipped_surface =
73 layer->render_surface() &&
74 !layer->render_surface()->is_clipped() &&
75 layer->num_unclipped_descendants() == 0;
76
77 if (has_unclipped_surface)
78 parent_id = 0;
79
80 if (!RequiresClipNode(layer, axis_aligned_with_respect_to_parent)) {
81 // Unclipped surfaces reset the clip rect.
82 data_for_children->clip_tree_parent = parent_id;
83 } else if (layer->parent()) {
84 // Note the root clip gets handled elsewhere.
85 Layer* transform_parent = GetTransformParent(*data_for_children, layer);
86 ClipNode node;
87 node.data.clip = gfx::RectF(
88 gfx::PointF() + layer->offset_to_transform_parent(), layer->bounds());
89 node.data.transform_id = transform_parent->transform_tree_index();
90 node.data.target_id =
91 data_from_ancestor.render_target->transform_tree_index();
92
93 data_for_children->clip_tree_parent =
94 data_for_children->clip_tree->Insert(node, parent_id);
95 }
96
97 layer->set_clip_tree_index(
98 has_unclipped_surface ? 0 : data_for_children->clip_tree_parent);
99
100 // TODO(awoloszyn): Right now when we hit a node with a replica, we reset the
101 // clip for all children since we may need to draw. We need to figure out a
102 // better way, since we will need both the clipped and unclipped versions.
103 }
104
105 void AddTransformNodeIfNeeded(const DataForRecursion& data_from_ancestor,
106 Layer* layer,
107 DataForRecursion* data_for_children) {
108 const bool is_root = !layer->parent();
109 const bool is_page_scale_application_layer =
110 layer->parent() && layer->parent() == data_from_ancestor.page_scale_layer;
111 const bool is_scrollable = layer->scrollable();
112 const bool is_fixed = layer->position_constraint().is_fixed_position();
113
114 const bool has_significant_transform =
115 !layer->transform().IsIdentityOrTranslation();
116
117 const bool has_animated_transform =
118 layer->layer_animation_controller()->IsAnimatingProperty(
119 Animation::Transform);
120
121 const bool has_transform_origin = layer->transform_origin() != gfx::Point3F();
122
123 const bool has_surface = !!layer->render_surface();
124
125 const bool flattening_change = layer->parent() &&
126 layer->should_flatten_transform() &&
127 !layer->parent()->should_flatten_transform();
128
129 bool requires_node = is_root || is_scrollable || is_fixed ||
130 has_significant_transform || has_animated_transform ||
131 is_page_scale_application_layer || flattening_change ||
132 has_transform_origin || has_surface;
133
134 Layer* transform_parent = GetTransformParent(data_from_ancestor, layer);
135
136 // May be non-zero if layer is fixed or has a scroll parent.
137 gfx::Vector2dF parent_offset;
138 if (transform_parent) {
139 // TODO(vollick): This is to mimic existing bugs (crbug.com/441447).
140 if (!is_fixed)
141 parent_offset = transform_parent->offset_to_transform_parent();
142
143 gfx::Transform to_parent;
144 Layer* source = data_from_ancestor.transform_tree_parent;
145 if (layer->scroll_parent()) {
146 source = layer->parent();
147 parent_offset += layer->parent()->offset_to_transform_parent();
148 }
149 data_from_ancestor.transform_tree->ComputeTransform(
150 source->transform_tree_index(),
151 transform_parent->transform_tree_index(), &to_parent);
152
153 parent_offset += to_parent.To2dTranslation();
154 }
155
156 if (layer->IsContainerForFixedPositionLayers() || is_root)
157 data_for_children->transform_fixed_parent = layer;
158 data_for_children->transform_tree_parent = layer;
159
160 if (!requires_node) {
161 gfx::Vector2dF local_offset = layer->position().OffsetFromOrigin() +
162 layer->transform().To2dTranslation();
163 layer->set_offset_to_transform_parent(parent_offset + local_offset);
164 layer->set_transform_tree_index(transform_parent->transform_tree_index());
165 return;
166 }
167
168 if (!is_root) {
169 data_for_children->transform_tree->Insert(
170 TransformNode(), transform_parent->transform_tree_index());
171 }
172
173 TransformNode* node = data_for_children->transform_tree->back();
174
175 node->data.flattens = layer->should_flatten_transform();
176 node->data.target_id =
177 data_from_ancestor.render_target->transform_tree_index();
178 node->data.is_animated = layer->TransformIsAnimating();
179
180 gfx::Transform transform;
181 float device_and_page_scale_factors = 1.0f;
182 if (is_root)
183 device_and_page_scale_factors = data_from_ancestor.device_scale_factor;
184 if (is_page_scale_application_layer)
185 device_and_page_scale_factors *= data_from_ancestor.page_scale_factor;
186
187 transform.Scale(device_and_page_scale_factors, device_and_page_scale_factors);
188
189 // TODO(vollick): We've accounted for the scroll offset here but we haven't
190 // taken into account snapping to screen space pixels. For the purposes of
191 // computing rects we need to record, this should be fine (the visible rects
192 // we compute may be slightly different than what we'd compute with snapping,
193 // but since we significantly expand the visible rect when determining what to
194 // record, the slight difference should be inconsequential).
195 gfx::Vector2dF position = layer->position().OffsetFromOrigin();
196 if (!layer->scroll_parent()) {
197 position -= gfx::Vector2dF(layer->TotalScrollOffset().x(),
198 layer->TotalScrollOffset().y());
199 }
200
201 position += parent_offset;
202
203 transform.Translate3d(position.x() + layer->transform_origin().x(),
204 position.y() + layer->transform_origin().y(),
205 layer->transform_origin().z());
206 transform.PreconcatTransform(layer->transform());
207 transform.Translate3d(-layer->transform_origin().x(),
208 -layer->transform_origin().y(),
209 -layer->transform_origin().z());
210
211 node->data.to_parent = transform;
212 node->data.is_invertible = transform.GetInverse(&node->data.from_parent);
213
214 data_from_ancestor.transform_tree->UpdateScreenSpaceTransform(node->id);
215
216 layer->set_offset_to_transform_parent(gfx::Vector2dF());
217 layer->set_transform_tree_index(node->id);
218 }
219
220 void BuildPropertyTreesInternal(Layer* layer,
221 const DataForRecursion& data_from_parent) {
222 DataForRecursion data_for_children(data_from_parent);
223 if (layer->render_surface())
224 data_for_children.render_target = layer;
225
226 AddTransformNodeIfNeeded(data_from_parent, layer, &data_for_children);
227 AddClipNodeIfNeeded(data_from_parent, layer, &data_for_children);
228
229 for (size_t i = 0; i < layer->children().size(); ++i) {
230 if (!layer->children()[i]->scroll_parent())
231 BuildPropertyTreesInternal(layer->children()[i].get(), data_for_children);
232 }
233
234 if (layer->scroll_children()) {
235 for (Layer* scroll_child : *layer->scroll_children()) {
236 BuildPropertyTreesInternal(scroll_child, data_for_children);
237 }
238 }
239
240 if (layer->has_replica())
241 BuildPropertyTreesInternal(layer->replica_layer(), data_for_children);
242 }
243
244 } // namespace
245
246 void PropertyTreeBuilder::BuildPropertyTrees(
247 Layer* root_layer,
248 const Layer* page_scale_layer,
249 float page_scale_factor,
250 float device_scale_factor,
251 const gfx::Rect& viewport,
252 const gfx::Transform& device_transform,
253 TransformTree* transform_tree,
254 ClipTree* clip_tree) {
255 DataForRecursion data_for_recursion;
256 data_for_recursion.transform_tree = transform_tree;
257 data_for_recursion.clip_tree = clip_tree;
258 data_for_recursion.transform_tree_parent = nullptr;
259 data_for_recursion.transform_fixed_parent = nullptr;
260 data_for_recursion.render_target = root_layer;
261 data_for_recursion.clip_tree_parent = 0;
262 data_for_recursion.page_scale_layer = page_scale_layer;
263 data_for_recursion.page_scale_factor = page_scale_factor;
264 data_for_recursion.device_scale_factor = device_scale_factor;
265
266 int transform_root_id = transform_tree->Insert(TransformNode(), 0);
267
268 ClipNode root_clip;
269 root_clip.data.clip = viewport;
270 root_clip.data.transform_id = 0;
271 data_for_recursion.clip_tree_parent = clip_tree->Insert(root_clip, 0);
272
273 BuildPropertyTreesInternal(root_layer, data_for_recursion);
274
275 TransformNode* transform_root = transform_tree->Node(transform_root_id);
276 transform_root->data.set_to_parent(device_transform *
277 transform_root->data.to_parent);
278 }
279
280 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/property_tree_builder.h ('k') | cc/trees/property_tree_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698