OLD | NEW |
---|---|
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 16 matching lines...) Expand all Loading... | |
27 namespace { | 27 namespace { |
28 | 28 |
29 static bool IsRootLayer(const Layer* layer) { | 29 static bool IsRootLayer(const Layer* layer) { |
30 return !layer->parent(); | 30 return !layer->parent(); |
31 } | 31 } |
32 | 32 |
33 static bool IsRootLayer(const LayerImpl* layer) { | 33 static bool IsRootLayer(const LayerImpl* layer) { |
34 return layer->layer_tree_impl()->IsRootLayer(layer); | 34 return layer->layer_tree_impl()->IsRootLayer(layer); |
35 } | 35 } |
36 | 36 |
37 static const EffectNode* ContentsTargetEffectNode( | |
38 const int effect_tree_index, | |
39 const EffectTree& effect_tree) { | |
40 const EffectNode* effect_node = effect_tree.Node(effect_tree_index); | |
41 return effect_tree.GetRenderSurface(effect_tree_index) | |
42 ? effect_node | |
43 : effect_tree.Node(effect_node->target_id); | |
44 } | |
45 | |
46 static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, | 37 static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, |
47 int source_effect_id, | 38 int source_effect_id, |
48 int dest_effect_id, | 39 int dest_effect_id, |
49 gfx::RectF clip_in_source_space, | 40 gfx::RectF clip_in_source_space, |
50 gfx::RectF* clip_in_dest_space) { | 41 gfx::RectF* clip_in_dest_space) { |
51 const EffectNode* source_effect_node = | 42 const EffectNode* source_effect_node = |
52 property_trees->effect_tree.Node(source_effect_id); | 43 property_trees->effect_tree.Node(source_effect_id); |
53 int source_transform_id = source_effect_node->transform_id; | 44 int source_transform_id = source_effect_node->transform_id; |
54 const EffectNode* dest_effect_node = | 45 const EffectNode* dest_effect_node = |
55 property_trees->effect_tree.Node(dest_effect_id); | 46 property_trees->effect_tree.Node(dest_effect_id); |
(...skipping 14 matching lines...) Expand all Loading... | |
70 PostConcatSurfaceContentsScale(dest_effect_node, &source_to_dest); | 61 PostConcatSurfaceContentsScale(dest_effect_node, &source_to_dest); |
71 *clip_in_dest_space = | 62 *clip_in_dest_space = |
72 MathUtil::ProjectClippedRect(source_to_dest, clip_in_source_space); | 63 MathUtil::ProjectClippedRect(source_to_dest, clip_in_source_space); |
73 } else { | 64 } else { |
74 return false; | 65 return false; |
75 } | 66 } |
76 } | 67 } |
77 return true; | 68 return true; |
78 } | 69 } |
79 | 70 |
80 bool ComputeClipRectInTargetSpace(const LayerImpl* layer, | |
81 const ClipNode* clip_node, | |
82 const PropertyTrees* property_trees, | |
83 int target_node_id, | |
84 bool for_visible_rect_calculation, | |
85 gfx::RectF* clip_rect_in_target_space) { | |
86 DCHECK(layer->clip_tree_index() == clip_node->id); | |
87 DCHECK(clip_node->target_transform_id != target_node_id); | |
88 | |
89 const EffectTree& effect_tree = property_trees->effect_tree; | |
90 const EffectNode* target_effect_node = | |
91 ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree); | |
92 gfx::Transform clip_to_target; | |
93 // We use the local clip for clip rect calculation and combined clip for | |
94 // visible rect calculation. | |
95 gfx::RectF clip_from_clip_node = | |
96 for_visible_rect_calculation ? clip_node->combined_clip_in_target_space | |
97 : clip_node->clip_in_target_space; | |
98 | |
99 return ConvertRectBetweenSurfaceSpaces( | |
100 property_trees, clip_node->target_effect_id, target_effect_node->id, | |
101 clip_from_clip_node, clip_rect_in_target_space); | |
102 } | |
103 | |
104 struct ConditionalClip { | |
105 bool is_clipped; | |
106 gfx::RectF clip_rect; | |
107 }; | |
108 | |
109 static ConditionalClip ComputeTargetRectInLocalSpace( | 71 static ConditionalClip ComputeTargetRectInLocalSpace( |
110 gfx::RectF rect, | 72 gfx::RectF rect, |
111 const PropertyTrees* property_trees, | 73 const PropertyTrees* property_trees, |
112 int target_transform_id, | 74 int target_transform_id, |
113 int local_transform_id, | 75 int local_transform_id, |
114 const int target_effect_id) { | 76 const int target_effect_id) { |
115 gfx::Transform target_to_local; | 77 gfx::Transform target_to_local; |
116 bool success = property_trees->GetFromTarget( | 78 const TransformNode* node = |
117 local_transform_id, target_effect_id, &target_to_local); | 79 property_trees->transform_tree.Node(local_transform_id); |
118 if (!success) | 80 if (target_transform_id == TransformTree::kRootNodeId && |
119 // If transform is not invertible, cannot apply clip. | 81 node->ancestors_are_invertible) { |
120 return ConditionalClip{false, gfx::RectF()}; | 82 target_to_local = property_trees->transform_tree.FromScreen(node->id); |
83 } else { | |
84 bool success = property_trees->GetFromTarget( | |
85 local_transform_id, target_effect_id, &target_to_local); | |
86 if (!success) | |
87 // If transform is not invertible, cannot apply clip. | |
88 return ConditionalClip{false, gfx::RectF()}; | |
89 } | |
121 | 90 |
122 if (target_transform_id > local_transform_id) | 91 if (target_transform_id > local_transform_id) |
123 return ConditionalClip{true, // is_clipped. | 92 return ConditionalClip{true, // is_clipped. |
124 MathUtil::MapClippedRect(target_to_local, rect)}; | 93 MathUtil::MapClippedRect(target_to_local, rect)}; |
125 | 94 |
126 return ConditionalClip{true, // is_clipped. | 95 return ConditionalClip{true, // is_clipped. |
127 MathUtil::ProjectClippedRect(target_to_local, rect)}; | 96 MathUtil::ProjectClippedRect(target_to_local, rect)}; |
128 } | 97 } |
129 | 98 |
130 static ConditionalClip ComputeLocalRectInTargetSpace( | 99 static ConditionalClip ComputeLocalRectInTargetSpace( |
131 gfx::RectF rect, | 100 gfx::RectF rect, |
132 const PropertyTrees* property_trees, | 101 const PropertyTrees* property_trees, |
133 int current_transform_id, | 102 int current_transform_id, |
134 int target_transform_id, | 103 int target_transform_id, |
135 int target_effect_id) { | 104 int target_effect_id) { |
136 gfx::Transform current_to_target; | 105 gfx::Transform current_to_target; |
137 if (!property_trees->GetToTarget(current_transform_id, target_effect_id, | 106 if (target_transform_id == TransformTree::kRootNodeId) { |
weiliangc
2017/03/14 22:04:30
Is it possible to make this logic part of GetToTar
jaydasika
2017/03/16 20:33:31
Ah, that makes sense, I added this to speed up tra
| |
138 ¤t_to_target)) { | 107 current_to_target = |
108 property_trees->transform_tree.ToScreen(current_transform_id); | |
109 } else if (!property_trees->GetToTarget( | |
110 current_transform_id, target_effect_id, ¤t_to_target)) { | |
139 // If transform is not invertible, cannot apply clip. | 111 // If transform is not invertible, cannot apply clip. |
140 return ConditionalClip{false, gfx::RectF()}; | 112 return ConditionalClip{false, gfx::RectF()}; |
141 } | 113 } |
142 | 114 |
143 if (current_transform_id > target_transform_id) | 115 if (current_transform_id > target_transform_id) |
144 return ConditionalClip{true, // is_clipped. | 116 return ConditionalClip{true, // is_clipped. |
145 MathUtil::MapClippedRect(current_to_target, rect)}; | 117 MathUtil::MapClippedRect(current_to_target, rect)}; |
146 | 118 |
147 return ConditionalClip{true, // is_clipped. | 119 return ConditionalClip{true, // is_clipped. |
148 MathUtil::ProjectClippedRect(current_to_target, rect)}; | 120 MathUtil::ProjectClippedRect(current_to_target, rect)}; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 | 183 |
212 // Put the expanded clip back into the original target space. | 184 // Put the expanded clip back into the original target space. |
213 success = ConvertRectBetweenSurfaceSpaces( | 185 success = ConvertRectBetweenSurfaceSpaces( |
214 property_trees, expanding_effect_node->id, target_id, | 186 property_trees, expanding_effect_node->id, target_id, |
215 expanded_clip_in_expanding_space, accumulated_clip); | 187 expanded_clip_in_expanding_space, accumulated_clip); |
216 // If transform is not invertible, no clip will be applied. | 188 // If transform is not invertible, no clip will be applied. |
217 if (!success) | 189 if (!success) |
218 return false; | 190 return false; |
219 return true; | 191 return true; |
220 } | 192 } |
221 case ClipNode::ClipType::NONE: | |
222 return true; | |
223 } | 193 } |
224 NOTREACHED(); | 194 NOTREACHED(); |
225 return true; | 195 return true; |
226 } | 196 } |
227 | 197 |
228 static ConditionalClip ComputeAccumulatedClip( | 198 static ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees, |
229 const PropertyTrees* property_trees, | 199 bool include_expanding_clips, |
230 bool include_viewport_clip, | 200 int local_clip_id, |
231 bool include_expanding_clips, | 201 int target_id) { |
232 int local_clip_id, | 202 ClipRectData& cached_data = |
233 int target_id) { | 203 property_trees->FetchClipRectFromCache(local_clip_id, target_id); |
234 DCHECK(!include_viewport_clip || | 204 if (cached_data.target_id != EffectTree::kInvalidNodeId) { |
235 target_id == EffectTree::kContentsRootNodeId); | 205 // Cache hit |
206 return cached_data.clip; | |
207 } | |
208 cached_data.target_id = target_id; | |
209 | |
236 const ClipTree& clip_tree = property_trees->clip_tree; | 210 const ClipTree& clip_tree = property_trees->clip_tree; |
211 const ClipNode* clip_node = clip_tree.Node(local_clip_id); | |
237 const EffectTree& effect_tree = property_trees->effect_tree; | 212 const EffectTree& effect_tree = property_trees->effect_tree; |
238 | |
239 const ClipNode* clip_node = clip_tree.Node(local_clip_id); | |
240 const EffectNode* target_node = effect_tree.Node(target_id); | 213 const EffectNode* target_node = effect_tree.Node(target_id); |
241 int target_transform_id = target_node->transform_id; | 214 int target_transform_id = target_node->transform_id; |
242 | 215 |
216 bool cache_hit = false; | |
217 ConditionalClip cached_clip = ConditionalClip{false, gfx::RectF()}; | |
218 ConditionalClip unclipped = ConditionalClip{false, gfx::RectF()}; | |
219 | |
243 // Collect all the clips that need to be accumulated. | 220 // Collect all the clips that need to be accumulated. |
244 std::stack<const ClipNode*> parent_chain; | 221 std::stack<const ClipNode*, std::vector<const ClipNode*>> parent_chain; |
245 | 222 |
246 // If target is not direct ancestor of clip, this will find least common | 223 // If target is not direct ancestor of clip, this will find least common |
247 // ancestor between the target and the clip. | 224 // ancestor between the target and the clip. |
248 while (target_node->clip_id > clip_node->id || | 225 while (target_node->clip_id > clip_node->id || |
249 target_node->has_unclipped_descendants) { | 226 target_node->has_unclipped_descendants) { |
250 target_node = effect_tree.Node(target_node->target_id); | 227 target_node = effect_tree.Node(target_node->target_id); |
251 } | 228 } |
252 | 229 |
253 // Collect clip nodes up to the least common ancestor. | 230 // Collect clip nodes up to the least common ancestor or till we get a cache |
231 // hit. | |
254 while (target_node->clip_id < clip_node->id) { | 232 while (target_node->clip_id < clip_node->id) { |
233 if (parent_chain.size() > 0) { | |
234 // Search the cache. | |
235 for (auto& data : clip_node->cached_clip_rects) { | |
236 if (data.target_id == target_id) { | |
237 cache_hit = true; | |
238 cached_clip = data.clip; | |
239 } | |
240 } | |
241 } | |
255 parent_chain.push(clip_node); | 242 parent_chain.push(clip_node); |
256 clip_node = clip_tree.parent(clip_node); | 243 clip_node = clip_tree.parent(clip_node); |
257 } | 244 } |
258 DCHECK_EQ(target_node->clip_id, clip_node->id); | |
259 | 245 |
260 if (!include_viewport_clip && parent_chain.size() == 0) { | 246 if (parent_chain.size() == 0) { |
261 // There aren't any clips to apply. | 247 // No accumulated clip nodes. |
262 return ConditionalClip{false, gfx::RectF()}; | 248 cached_data.clip = unclipped; |
249 return unclipped; | |
263 } | 250 } |
264 | 251 |
265 if (!include_viewport_clip) { | 252 clip_node = parent_chain.top(); |
266 clip_node = parent_chain.top(); | 253 parent_chain.pop(); |
267 parent_chain.pop(); | 254 |
255 gfx::RectF accumulated_clip; | |
256 if (cache_hit && cached_clip.is_clipped) { | |
257 // Apply the first clip in parent_chain to the cached clip. | |
258 accumulated_clip = cached_clip.clip_rect; | |
259 bool success = ApplyClipNodeToAccumulatedClip( | |
260 property_trees, include_expanding_clips, target_id, target_transform_id, | |
261 clip_node, &accumulated_clip); | |
262 if (!success) { | |
263 // Singular transform | |
264 cached_data.clip = unclipped; | |
265 return unclipped; | |
266 } | |
267 } else { | |
268 // No cache hit or the cached clip has no clip to apply. We need to find | |
269 // the first clip that applies clip as there is no clip to expand. | |
270 while (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP && | |
271 parent_chain.size() > 0) { | |
272 clip_node = parent_chain.top(); | |
273 parent_chain.pop(); | |
274 } | |
275 | |
276 if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) { | |
277 // No clip to apply. | |
278 cached_data.clip = unclipped; | |
279 return unclipped; | |
280 } | |
281 ConditionalClip current_clip = ComputeCurrentClip( | |
282 clip_node, property_trees, target_transform_id, target_id); | |
283 if (!current_clip.is_clipped) { | |
284 // Singular transform | |
285 cached_data.clip = unclipped; | |
286 return unclipped; | |
287 } | |
288 accumulated_clip = current_clip.clip_rect; | |
268 } | 289 } |
269 | 290 |
270 // Find the first clip in the chain that we need to apply. | 291 // Apply remaining clips |
271 while (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP && | |
272 parent_chain.size() > 0) { | |
273 clip_node = parent_chain.top(); | |
274 parent_chain.pop(); | |
275 } | |
276 | |
277 if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) { | |
278 // No clip node applying clip in between. | |
279 return ConditionalClip{false, gfx::RectF()}; | |
280 } | |
281 | |
282 ConditionalClip current_clip = ComputeCurrentClip( | |
283 clip_node, property_trees, target_transform_id, target_id); | |
284 | |
285 // If transform is not invertible, no clip will be applied. | |
286 if (!current_clip.is_clipped) | |
287 return ConditionalClip{false, gfx::RectF()}; | |
288 gfx::RectF accumulated_clip = current_clip.clip_rect; | |
289 | |
290 while (parent_chain.size() > 0) { | 292 while (parent_chain.size() > 0) { |
291 clip_node = parent_chain.top(); | 293 clip_node = parent_chain.top(); |
292 parent_chain.pop(); | 294 parent_chain.pop(); |
293 bool success = ApplyClipNodeToAccumulatedClip( | 295 bool success = ApplyClipNodeToAccumulatedClip( |
294 property_trees, include_expanding_clips, target_id, target_transform_id, | 296 property_trees, include_expanding_clips, target_id, target_transform_id, |
295 clip_node, &accumulated_clip); | 297 clip_node, &accumulated_clip); |
296 | 298 if (!success) { |
297 // Failure to apply the clip means we encountered an uninvertible transform, | 299 // Singular transform |
298 // so no clip will be applied. | 300 cached_data.clip = unclipped; |
299 if (!success) | 301 return unclipped; |
300 return ConditionalClip{false /* is_clipped */, gfx::RectF()}; | 302 } |
301 } | 303 } |
302 | 304 |
303 return ConditionalClip{true /* is_clipped */, accumulated_clip.IsEmpty() | 305 ConditionalClip clip = ConditionalClip{ |
304 ? gfx::RectF() | 306 true /* is_clipped */, |
305 : accumulated_clip}; | 307 accumulated_clip.IsEmpty() ? gfx::RectF() : accumulated_clip}; |
306 } | 308 cached_data.clip = clip; |
307 | 309 return clip; |
308 static gfx::RectF ComputeAccumulatedClipInRootSpaceForVisibleRect( | |
309 const PropertyTrees* property_trees, | |
310 int local_clip_id) { | |
311 const int root_effect_id = EffectTree::kContentsRootNodeId; | |
312 bool include_viewport_clip = true; | |
313 bool include_expanding_clips = true; | |
314 ConditionalClip accumulated_clip = ComputeAccumulatedClip( | |
315 property_trees, include_viewport_clip, include_expanding_clips, | |
316 local_clip_id, root_effect_id); | |
317 DCHECK(accumulated_clip.is_clipped); | |
318 return accumulated_clip.clip_rect; | |
319 } | |
320 | |
321 void CalculateClipRects(const std::vector<LayerImpl*>& visible_layer_list, | |
322 const PropertyTrees* property_trees, | |
323 bool non_root_surfaces_enabled) { | |
324 const ClipTree& clip_tree = property_trees->clip_tree; | |
325 for (auto* layer : visible_layer_list) { | |
326 const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index()); | |
327 bool layer_needs_clip_rect = | |
328 non_root_surfaces_enabled | |
329 ? clip_node->layers_are_clipped | |
330 : clip_node->layers_are_clipped_when_surfaces_disabled; | |
331 if (!layer_needs_clip_rect) { | |
332 layer->set_clip_rect(gfx::Rect()); | |
333 continue; | |
334 } | |
335 if (!non_root_surfaces_enabled) { | |
336 layer->set_clip_rect( | |
337 gfx::ToEnclosingRect(clip_node->clip_in_target_space)); | |
338 continue; | |
339 } | |
340 | |
341 const TransformTree& transform_tree = property_trees->transform_tree; | |
342 const TransformNode* transform_node = | |
343 transform_tree.Node(layer->transform_tree_index()); | |
344 int target_node_id = transform_tree.ContentTargetId(transform_node->id); | |
345 | |
346 // The clip node stores clip rect in its target space. | |
347 gfx::RectF clip_rect_in_target_space = clip_node->clip_in_target_space; | |
348 | |
349 // If required, this clip rect should be mapped to the current layer's | |
350 // target space. | |
351 if (clip_node->target_transform_id != target_node_id) { | |
352 // In this case, layer has a clip parent or scroll parent (or shares the | |
353 // target with an ancestor layer that has clip parent) and the clip | |
354 // parent's target is different from the layer's target. As the layer's | |
355 // target has unclippped descendants, it is unclippped. | |
356 if (!clip_node->layers_are_clipped) | |
357 continue; | |
358 | |
359 // Compute the clip rect in target space and store it. | |
360 bool for_visible_rect_calculation = false; | |
361 if (!ComputeClipRectInTargetSpace( | |
362 layer, clip_node, property_trees, target_node_id, | |
363 for_visible_rect_calculation, &clip_rect_in_target_space)) | |
364 continue; | |
365 } | |
366 | |
367 if (!clip_rect_in_target_space.IsEmpty()) { | |
368 layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space)); | |
369 } else { | |
370 layer->set_clip_rect(gfx::Rect()); | |
371 } | |
372 } | |
373 } | |
374 | |
375 void CalculateVisibleRects(const LayerImplList& visible_layer_list, | |
376 const PropertyTrees* property_trees, | |
377 bool non_root_surfaces_enabled) { | |
378 const EffectTree& effect_tree = property_trees->effect_tree; | |
379 const TransformTree& transform_tree = property_trees->transform_tree; | |
380 const ClipTree& clip_tree = property_trees->clip_tree; | |
381 for (auto* layer : visible_layer_list) { | |
382 gfx::Size layer_bounds = layer->bounds(); | |
383 | |
384 int effect_ancestor_with_copy_request = | |
385 effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index()); | |
386 if (effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId) { | |
387 // Non root copy request. | |
388 bool include_viewport_clip = false; | |
389 bool include_expanding_clips = true; | |
390 ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( | |
391 property_trees, include_viewport_clip, include_expanding_clips, | |
392 layer->clip_tree_index(), effect_ancestor_with_copy_request); | |
393 if (!accumulated_clip_rect.is_clipped) { | |
394 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
395 continue; | |
396 } | |
397 | |
398 gfx::RectF accumulated_clip_in_copy_request_space = | |
399 accumulated_clip_rect.clip_rect; | |
400 | |
401 const EffectNode* copy_request_effect_node = | |
402 effect_tree.Node(effect_ancestor_with_copy_request); | |
403 ConditionalClip clip_in_layer_space = ComputeTargetRectInLocalSpace( | |
404 accumulated_clip_in_copy_request_space, property_trees, | |
405 copy_request_effect_node->transform_id, layer->transform_tree_index(), | |
406 copy_request_effect_node->id); | |
407 | |
408 if (clip_in_layer_space.is_clipped) { | |
409 gfx::RectF clip_rect = clip_in_layer_space.clip_rect; | |
410 clip_rect.Offset(-layer->offset_to_transform_parent()); | |
411 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect); | |
412 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
413 layer->set_visible_layer_rect(visible_rect); | |
414 } else { | |
415 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
416 } | |
417 continue; | |
418 } | |
419 | |
420 const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index()); | |
421 const TransformNode* transform_node = | |
422 transform_tree.Node(layer->transform_tree_index()); | |
423 if (!non_root_surfaces_enabled) { | |
424 // When we only have a root surface, the clip node and the layer must | |
425 // necessarily have the same target (the root). | |
426 if (transform_node->ancestors_are_invertible) { | |
427 gfx::RectF combined_clip_rect_in_target_space = | |
428 clip_node->combined_clip_in_target_space; | |
429 gfx::Transform target_to_content; | |
430 target_to_content.Translate(-layer->offset_to_transform_parent().x(), | |
431 -layer->offset_to_transform_parent().y()); | |
432 target_to_content.PreconcatTransform( | |
433 transform_tree.FromScreen(transform_node->id)); | |
434 | |
435 gfx::Rect visible_rect = | |
436 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | |
437 target_to_content, combined_clip_rect_in_target_space)); | |
438 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
439 layer->set_visible_layer_rect(visible_rect); | |
440 } else { | |
441 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
442 } | |
443 continue; | |
444 } | |
445 | |
446 // When both the layer and the target are unclipped, we only have to apply | |
447 // the viewport clip. | |
448 const bool fully_visible = | |
449 !clip_node->layers_are_clipped && | |
450 !effect_tree.Node(clip_node->target_effect_id)->surface_is_clipped; | |
451 | |
452 if (fully_visible) { | |
453 if (!transform_node->ancestors_are_invertible) { | |
454 // An animated singular transform may become non-singular during the | |
455 // animation, so we still need to compute a visible rect. In this | |
456 // situation, we treat the entire layer as visible. | |
457 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
458 } else { | |
459 gfx::Transform from_screen; | |
460 from_screen.Translate(-layer->offset_to_transform_parent().x(), | |
461 -layer->offset_to_transform_parent().y()); | |
462 from_screen.PreconcatTransform( | |
463 property_trees->transform_tree.FromScreen(transform_node->id)); | |
464 gfx::Rect visible_rect = | |
465 gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | |
466 from_screen, property_trees->clip_tree.ViewportClip())); | |
467 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
468 layer->set_visible_layer_rect(visible_rect); | |
469 } | |
470 continue; | |
471 } | |
472 | |
473 int target_node_id = transform_tree.ContentTargetId(transform_node->id); | |
474 | |
475 // The clip node stores clip rect in its target space. If required, | |
476 // this clip rect should be mapped to the current layer's target space. | |
477 gfx::RectF combined_clip_rect_in_target_space; | |
478 | |
479 if (clip_node->target_transform_id != target_node_id) { | |
480 // In this case, layer has a clip parent or scroll parent (or shares the | |
481 // target with an ancestor layer that has clip parent) and the clip | |
482 // parent's target is different from the layer's target. As the layer's | |
483 // target has unclippped descendants, it is unclippped. | |
484 if (!clip_node->layers_are_clipped) { | |
485 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
486 continue; | |
487 } | |
488 | |
489 bool for_visible_rect_calculation = true; | |
490 if (!ComputeClipRectInTargetSpace(layer, clip_node, property_trees, | |
491 target_node_id, | |
492 for_visible_rect_calculation, | |
493 &combined_clip_rect_in_target_space)) { | |
494 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
495 continue; | |
496 } | |
497 } else { | |
498 combined_clip_rect_in_target_space = | |
499 clip_node->combined_clip_in_target_space; | |
500 } | |
501 | |
502 // The clip rect should be intersected with layer rect in target space. | |
503 gfx::Transform content_to_target; | |
504 property_trees->GetToTarget(transform_node->id, | |
505 layer->render_target_effect_tree_index(), | |
506 &content_to_target); | |
507 content_to_target.Translate(layer->offset_to_transform_parent().x(), | |
508 layer->offset_to_transform_parent().y()); | |
509 gfx::Rect layer_content_rect = gfx::Rect(layer_bounds); | |
510 gfx::RectF layer_content_bounds_in_target_space = MathUtil::MapClippedRect( | |
511 content_to_target, gfx::RectF(layer_content_rect)); | |
512 // If the layer is fully contained within the clip, treat it as fully | |
513 // visible. | |
514 if (!layer_content_bounds_in_target_space.IsEmpty() && | |
515 combined_clip_rect_in_target_space.Contains( | |
516 layer_content_bounds_in_target_space)) { | |
517 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
518 continue; | |
519 } | |
520 | |
521 combined_clip_rect_in_target_space.Intersect( | |
522 layer_content_bounds_in_target_space); | |
523 if (combined_clip_rect_in_target_space.IsEmpty()) { | |
524 layer->set_visible_layer_rect(gfx::Rect()); | |
525 continue; | |
526 } | |
527 | |
528 gfx::Transform target_to_layer; | |
529 const EffectNode* target_effect_node = | |
530 ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree); | |
531 bool success = property_trees->GetFromTarget( | |
532 transform_node->id, target_effect_node->id, &target_to_layer); | |
533 if (!success) { | |
534 // An animated singular transform may become non-singular during the | |
535 // animation, so we still need to compute a visible rect. In this | |
536 // situation, we treat the entire layer as visible. | |
537 layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); | |
538 continue; | |
539 } | |
540 gfx::Transform target_to_content; | |
541 target_to_content.Translate(-layer->offset_to_transform_parent().x(), | |
542 -layer->offset_to_transform_parent().y()); | |
543 target_to_content.PreconcatTransform(target_to_layer); | |
544 | |
545 gfx::Rect visible_rect = gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( | |
546 target_to_content, combined_clip_rect_in_target_space)); | |
547 visible_rect.Intersect(gfx::Rect(layer_bounds)); | |
548 layer->set_visible_layer_rect(visible_rect); | |
549 } | |
550 } | 310 } |
551 | 311 |
552 static bool HasSingularTransform(int transform_tree_index, | 312 static bool HasSingularTransform(int transform_tree_index, |
553 const TransformTree& tree) { | 313 const TransformTree& tree) { |
554 const TransformNode* node = tree.Node(transform_tree_index); | 314 const TransformNode* node = tree.Node(transform_tree_index); |
555 return !node->is_invertible || !node->ancestors_are_invertible; | 315 return !node->is_invertible || !node->ancestors_are_invertible; |
556 } | 316 } |
557 | 317 |
558 template <typename LayerType> | 318 template <typename LayerType> |
559 static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, | 319 static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
646 // backface is not visible. | 406 // backface is not visible. |
647 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && | 407 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && |
648 !HasSingularTransform(backface_transform_id, tree) && | 408 !HasSingularTransform(backface_transform_id, tree) && |
649 IsLayerBackFaceVisible(layer, backface_transform_id, property_trees)) | 409 IsLayerBackFaceVisible(layer, backface_transform_id, property_trees)) |
650 return false; | 410 return false; |
651 } | 411 } |
652 | 412 |
653 return true; | 413 return true; |
654 } | 414 } |
655 | 415 |
656 void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, | |
657 const PropertyTrees* property_trees, | |
658 std::vector<LayerImpl*>* visible_layer_list) { | |
659 const TransformTree& transform_tree = property_trees->transform_tree; | |
660 const EffectTree& effect_tree = property_trees->effect_tree; | |
661 | 416 |
662 for (auto* layer_impl : *layer_tree_impl) { | |
663 if (!IsRootLayer(layer_impl) && | |
664 LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree)) | |
665 continue; | |
666 | |
667 bool layer_is_drawn = | |
668 effect_tree.Node(layer_impl->effect_tree_index())->is_drawn; | |
669 | |
670 if (LayerNeedsUpdate(layer_impl, layer_is_drawn, property_trees)) | |
671 visible_layer_list->push_back(layer_impl); | |
672 } | |
673 } | |
674 | 417 |
675 } // namespace | 418 } // namespace |
676 | 419 |
677 template <typename LayerType> | 420 template <typename LayerType> |
678 static inline bool LayerShouldBeSkippedInternal( | 421 static inline bool LayerShouldBeSkippedInternal( |
679 LayerType* layer, | 422 LayerType* layer, |
680 const TransformTree& transform_tree, | 423 const TransformTree& transform_tree, |
681 const EffectTree& effect_tree) { | 424 const EffectTree& effect_tree) { |
682 const TransformNode* transform_node = | 425 const TransformNode* transform_node = |
683 transform_tree.Node(layer->transform_tree_index()); | 426 transform_tree.Node(layer->transform_tree_index()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
723 update_layer_list->push_back(layer); | 466 update_layer_list->push_back(layer); |
724 } | 467 } |
725 | 468 |
726 // Append mask layers to the update layer list. They don't have valid | 469 // Append mask layers to the update layer list. They don't have valid |
727 // visible rects, so need to get added after the above calculation. | 470 // visible rects, so need to get added after the above calculation. |
728 if (Layer* mask_layer = layer->mask_layer()) | 471 if (Layer* mask_layer = layer->mask_layer()) |
729 update_layer_list->push_back(mask_layer); | 472 update_layer_list->push_back(mask_layer); |
730 } | 473 } |
731 } | 474 } |
732 | 475 |
733 static void ResetIfHasNanCoordinate(gfx::RectF* rect) { | 476 void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, |
734 if (std::isnan(rect->x()) || std::isnan(rect->y()) || | 477 const PropertyTrees* property_trees, |
735 std::isnan(rect->right()) || std::isnan(rect->bottom())) | 478 std::vector<LayerImpl*>* visible_layer_list) { |
736 *rect = gfx::RectF(); | 479 const TransformTree& transform_tree = property_trees->transform_tree; |
480 const EffectTree& effect_tree = property_trees->effect_tree; | |
481 | |
482 for (auto* layer_impl : *layer_tree_impl) { | |
483 if (!IsRootLayer(layer_impl) && | |
484 LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree)) | |
485 continue; | |
486 | |
487 bool layer_is_drawn = | |
488 effect_tree.Node(layer_impl->effect_tree_index())->is_drawn; | |
489 | |
490 if (LayerNeedsUpdate(layer_impl, layer_is_drawn, property_trees)) | |
491 visible_layer_list->push_back(layer_impl); | |
492 } | |
737 } | 493 } |
738 | 494 |
739 void PostConcatSurfaceContentsScale(const EffectNode* effect_node, | 495 void PostConcatSurfaceContentsScale(const EffectNode* effect_node, |
740 gfx::Transform* transform) { | 496 gfx::Transform* transform) { |
741 if (!effect_node) { | 497 if (!effect_node) { |
742 // This can happen when PaintArtifactCompositor builds property trees as it | 498 // This can happen when PaintArtifactCompositor builds property trees as it |
743 // doesn't set effect ids on clip nodes. | 499 // doesn't set effect ids on clip nodes. |
744 return; | 500 return; |
745 } | 501 } |
746 DCHECK(effect_node->has_render_surface); | 502 DCHECK(effect_node->has_render_surface); |
747 transform->matrix().postScale(effect_node->surface_contents_scale.x(), | 503 transform->matrix().postScale(effect_node->surface_contents_scale.x(), |
748 effect_node->surface_contents_scale.y(), 1.f); | 504 effect_node->surface_contents_scale.y(), 1.f); |
749 } | 505 } |
750 | 506 |
751 void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, | 507 void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, |
752 gfx::Transform* transform) { | 508 gfx::Transform* transform) { |
753 DCHECK(effect_node->has_render_surface); | 509 DCHECK(effect_node->has_render_surface); |
754 if (effect_node->surface_contents_scale.x() != 0.0 && | 510 if (effect_node->surface_contents_scale.x() != 0.0 && |
755 effect_node->surface_contents_scale.y() != 0.0) | 511 effect_node->surface_contents_scale.y() != 0.0) |
756 transform->Scale(1.0 / effect_node->surface_contents_scale.x(), | 512 transform->Scale(1.0 / effect_node->surface_contents_scale.x(), |
757 1.0 / effect_node->surface_contents_scale.y()); | 513 1.0 / effect_node->surface_contents_scale.y()); |
758 } | 514 } |
759 | 515 |
760 void ComputeClips(PropertyTrees* property_trees, | |
761 bool non_root_surfaces_enabled) { | |
762 ClipTree* clip_tree = &property_trees->clip_tree; | |
763 if (!clip_tree->needs_update()) | |
764 return; | |
765 for (int i = ClipTree::kViewportNodeId; | |
766 i < static_cast<int>(clip_tree->size()); ++i) { | |
767 ClipNode* clip_node = clip_tree->Node(i); | |
768 | |
769 if (clip_node->id == ClipTree::kViewportNodeId) { | |
770 ResetIfHasNanCoordinate(&clip_node->clip); | |
771 clip_node->clip_in_target_space = clip_node->clip; | |
772 clip_node->combined_clip_in_target_space = clip_node->clip; | |
773 continue; | |
774 } | |
775 const TransformTree& transform_tree = property_trees->transform_tree; | |
776 const EffectTree& effect_tree = property_trees->effect_tree; | |
777 const TransformNode* transform_node = | |
778 transform_tree.Node(clip_node->transform_id); | |
779 ClipNode* parent_clip_node = clip_tree->parent(clip_node); | |
780 | |
781 bool target_is_clipped = | |
782 effect_tree.Node(clip_node->target_effect_id)->surface_is_clipped; | |
783 | |
784 gfx::Transform parent_to_current; | |
785 const TransformNode* parent_target_transform_node = | |
786 transform_tree.Node(parent_clip_node->target_transform_id); | |
787 bool success = true; | |
788 | |
789 // Clips must be combined in target space. We cannot, for example, combine | |
790 // clips in the space of the child clip. The reason is non-affine | |
791 // transforms. Say we have the following tree T->A->B->C, and B clips C, but | |
792 // draw into target T. It may be the case that A applies a perspective | |
793 // transform, and B and C are at different z positions. When projected into | |
794 // target space, the relative sizes and positions of B and C can shift. | |
795 // Since it's the relationship in target space that matters, that's where we | |
796 // must combine clips. For each clip node, we save the clip rects in its | |
797 // target space. So, we need to get the ancestor clip rect in the current | |
798 // clip node's target space. | |
799 gfx::RectF parent_combined_clip_in_target_space = | |
800 parent_clip_node->combined_clip_in_target_space; | |
801 gfx::RectF parent_clip_in_target_space = | |
802 parent_clip_node->clip_in_target_space; | |
803 if (parent_target_transform_node && | |
804 parent_target_transform_node->id != clip_node->target_transform_id && | |
805 non_root_surfaces_enabled) { | |
806 success &= ConvertRectBetweenSurfaceSpaces( | |
807 property_trees, parent_clip_node->target_effect_id, | |
808 clip_node->target_effect_id, | |
809 parent_clip_node->combined_clip_in_target_space, | |
810 &parent_combined_clip_in_target_space); | |
811 // If we can't compute a transform, it's because we had to use the inverse | |
812 // of a singular transform. We won't draw in this case, so there's no need | |
813 // to compute clips. | |
814 if (!success) | |
815 continue; | |
816 if (clip_node->clip_type == ClipNode::ClipType::EXPANDS_CLIP) { | |
817 parent_combined_clip_in_target_space = | |
818 gfx::RectF(clip_node->clip_expander->MapRectReverse( | |
819 gfx::ToEnclosingRect(parent_combined_clip_in_target_space), | |
820 property_trees)); | |
821 } | |
822 ConvertRectBetweenSurfaceSpaces( | |
823 property_trees, parent_clip_node->target_effect_id, | |
824 clip_node->target_effect_id, parent_clip_node->clip_in_target_space, | |
825 &parent_clip_in_target_space); | |
826 } | |
827 // Only nodes affected by ancestor clips will have their clip adjusted due | |
828 // to intersecting with an ancestor clip. But, we still need to propagate | |
829 // the combined clip to our children because if they are clipped, they may | |
830 // need to clip using our parent clip and if we don't propagate it here, | |
831 // it will be lost. | |
832 if (clip_node->resets_clip && non_root_surfaces_enabled) { | |
833 if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) { | |
834 gfx::Transform to_target; | |
835 property_trees->GetToTarget(clip_node->transform_id, | |
836 clip_node->target_effect_id, &to_target); | |
837 clip_node->clip_in_target_space = | |
838 MathUtil::MapClippedRect(to_target, clip_node->clip); | |
839 ResetIfHasNanCoordinate(&clip_node->clip_in_target_space); | |
840 clip_node->combined_clip_in_target_space = | |
841 gfx::IntersectRects(clip_node->clip_in_target_space, | |
842 parent_combined_clip_in_target_space); | |
843 } else { | |
844 DCHECK(!target_is_clipped); | |
845 DCHECK(!clip_node->layers_are_clipped); | |
846 clip_node->combined_clip_in_target_space = | |
847 parent_combined_clip_in_target_space; | |
848 } | |
849 ResetIfHasNanCoordinate(&clip_node->combined_clip_in_target_space); | |
850 continue; | |
851 } | |
852 bool use_only_parent_clip = | |
853 clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP; | |
854 if (use_only_parent_clip) { | |
855 clip_node->combined_clip_in_target_space = | |
856 parent_combined_clip_in_target_space; | |
857 if (!non_root_surfaces_enabled) { | |
858 clip_node->clip_in_target_space = | |
859 parent_clip_node->clip_in_target_space; | |
860 } else if (!target_is_clipped) { | |
861 clip_node->clip_in_target_space = parent_clip_in_target_space; | |
862 } else { | |
863 // Render Surface applies clip and the owning layer itself applies | |
864 // no clip. So, clip_in_target_space is not used and hence we can set | |
865 // it to an empty rect. | |
866 clip_node->clip_in_target_space = gfx::RectF(); | |
867 } | |
868 } else { | |
869 gfx::Transform source_to_target; | |
870 | |
871 if (!non_root_surfaces_enabled) { | |
872 source_to_target = transform_tree.ToScreen(clip_node->transform_id); | |
873 } else if (transform_tree.ContentTargetId(transform_node->id) == | |
874 clip_node->target_transform_id) { | |
875 property_trees->GetToTarget(clip_node->transform_id, | |
876 clip_node->target_effect_id, | |
877 &source_to_target); | |
878 } else { | |
879 success = property_trees->GetToTarget( | |
880 transform_node->id, clip_node->target_effect_id, &source_to_target); | |
881 // source_to_target computation should be successful as target is an | |
882 // ancestor of the transform node. | |
883 DCHECK(success); | |
884 } | |
885 | |
886 gfx::RectF source_clip_in_target_space = | |
887 MathUtil::MapClippedRect(source_to_target, clip_node->clip); | |
888 | |
889 // With surfaces disabled, the only case where we use only the local clip | |
890 // for layer clipping is the case where no non-viewport ancestor node | |
891 // applies a local clip. | |
892 bool layer_clipping_uses_only_local_clip = | |
893 non_root_surfaces_enabled | |
894 ? clip_node->layer_clipping_uses_only_local_clip | |
895 : !parent_clip_node->layers_are_clipped_when_surfaces_disabled; | |
896 if (!layer_clipping_uses_only_local_clip) { | |
897 clip_node->clip_in_target_space = gfx::IntersectRects( | |
898 parent_clip_in_target_space, source_clip_in_target_space); | |
899 } else { | |
900 clip_node->clip_in_target_space = source_clip_in_target_space; | |
901 } | |
902 | |
903 clip_node->combined_clip_in_target_space = gfx::IntersectRects( | |
904 parent_combined_clip_in_target_space, source_clip_in_target_space); | |
905 } | |
906 ResetIfHasNanCoordinate(&clip_node->clip_in_target_space); | |
907 ResetIfHasNanCoordinate(&clip_node->combined_clip_in_target_space); | |
908 } | |
909 clip_tree->set_needs_update(false); | |
910 } | |
911 | |
912 void ComputeTransforms(TransformTree* transform_tree) { | 516 void ComputeTransforms(TransformTree* transform_tree) { |
913 if (!transform_tree->needs_update()) | 517 if (!transform_tree->needs_update()) |
914 return; | 518 return; |
915 for (int i = TransformTree::kContentsRootNodeId; | 519 for (int i = TransformTree::kContentsRootNodeId; |
916 i < static_cast<int>(transform_tree->size()); ++i) | 520 i < static_cast<int>(transform_tree->size()); ++i) |
917 transform_tree->UpdateTransforms(i); | 521 transform_tree->UpdateTransforms(i); |
918 transform_tree->set_needs_update(false); | 522 transform_tree->set_needs_update(false); |
919 } | 523 } |
920 | 524 |
921 void UpdateRenderTarget(EffectTree* effect_tree, | 525 void UpdateRenderTarget(EffectTree* effect_tree, |
(...skipping 16 matching lines...) Expand all Loading... | |
938 | 542 |
939 void ComputeEffects(EffectTree* effect_tree) { | 543 void ComputeEffects(EffectTree* effect_tree) { |
940 if (!effect_tree->needs_update()) | 544 if (!effect_tree->needs_update()) |
941 return; | 545 return; |
942 for (int i = EffectTree::kContentsRootNodeId; | 546 for (int i = EffectTree::kContentsRootNodeId; |
943 i < static_cast<int>(effect_tree->size()); ++i) | 547 i < static_cast<int>(effect_tree->size()); ++i) |
944 effect_tree->UpdateEffects(i); | 548 effect_tree->UpdateEffects(i); |
945 effect_tree->set_needs_update(false); | 549 effect_tree->set_needs_update(false); |
946 } | 550 } |
947 | 551 |
948 static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) { | 552 void ComputeClips(PropertyTrees* property_trees) { |
949 EffectTree* effect_tree = &property_trees->effect_tree; | 553 ClipTree* clip_tree = &property_trees->clip_tree; |
950 const ClipTree* clip_tree = &property_trees->clip_tree; | 554 if (!clip_tree->needs_update()) |
951 EffectNode* root_effect_node = | 555 return; |
952 effect_tree->Node(EffectTree::kContentsRootNodeId); | 556 const int target_effect_id = EffectTree::kContentsRootNodeId; |
953 const RenderSurfaceImpl* root_render_surface = | 557 const int target_transform_id = TransformTree::kRootNodeId; |
954 effect_tree->GetRenderSurface(EffectTree::kContentsRootNodeId); | 558 const bool include_expanding_clips = true; |
955 gfx::Rect root_clip = | 559 for (int i = ClipTree::kViewportNodeId; |
956 gfx::ToEnclosingRect(clip_tree->Node(root_effect_node->clip_id)->clip); | 560 i < static_cast<int>(clip_tree->size()); ++i) { |
957 if (root_render_surface->is_clipped()) | 561 ClipNode* clip_node = clip_tree->Node(i); |
958 DCHECK(root_clip == root_render_surface->clip_rect()) | 562 // Clear the clip rect cache |
959 << "clip on root render surface: " | 563 clip_node->cached_clip_rects = std::vector<ClipRectData>(1); |
960 << root_render_surface->clip_rect().ToString() | 564 if (clip_node->id == ClipTree::kViewportNodeId) { |
961 << " v.s. root effect node's clip: " << root_clip.ToString(); | 565 clip_node->accumulated_rect_in_screen_space = clip_node->clip; |
962 for (int i = 2; i < static_cast<int>(effect_tree->size()); ++i) { | 566 continue; |
963 EffectNode* effect_node = effect_tree->Node(i); | |
964 const EffectNode* target_node = effect_tree->Node(effect_node->target_id); | |
965 bool include_viewport_clip = false; | |
966 bool include_expanding_clips = false; | |
967 ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( | |
968 property_trees, include_viewport_clip, include_expanding_clips, | |
969 effect_node->clip_id, target_node->id); | |
970 gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect; | |
971 const RenderSurfaceImpl* render_surface = effect_tree->GetRenderSurface(i); | |
972 if (render_surface && render_surface->is_clipped()) { | |
973 DCHECK(gfx::ToEnclosingRect(accumulated_clip) == | |
974 render_surface->clip_rect()) | |
975 << " render surface's clip rect: " | |
976 << render_surface->clip_rect().ToString() | |
977 << " v.s. accumulated clip: " | |
978 << gfx::ToEnclosingRect(accumulated_clip).ToString(); | |
979 } | 567 } |
568 ClipNode* parent_clip_node = clip_tree->parent(clip_node); | |
569 DCHECK(parent_clip_node); | |
570 gfx::RectF accumulated_clip = | |
571 parent_clip_node->accumulated_rect_in_screen_space; | |
572 bool success = ApplyClipNodeToAccumulatedClip( | |
573 property_trees, include_expanding_clips, target_effect_id, | |
574 target_transform_id, clip_node, &accumulated_clip); | |
575 DCHECK(success); | |
576 clip_node->accumulated_rect_in_screen_space = accumulated_clip; | |
weiliangc
2017/03/14 22:04:30
Have you tried not calculating acculated_rect_in_s
jaydasika
2017/03/16 20:33:31
I tried that. The performance was almost same. I d
| |
980 } | 577 } |
578 clip_tree->set_needs_update(false); | |
981 } | 579 } |
982 | 580 |
983 static void ComputeLayerClipRect(const PropertyTrees* property_trees, | 581 static ConditionalClip LayerClipRect(PropertyTrees* property_trees, |
984 const LayerImpl* layer) { | 582 LayerImpl* layer) { |
985 const EffectTree* effect_tree = &property_trees->effect_tree; | 583 const EffectTree* effect_tree = &property_trees->effect_tree; |
986 const ClipTree* clip_tree = &property_trees->clip_tree; | |
987 const ClipNode* clip_node = clip_tree->Node(layer->clip_tree_index()); | |
988 const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); | 584 const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); |
989 const EffectNode* target_node = | 585 const EffectNode* target_node = |
990 effect_node->has_render_surface | 586 effect_node->has_render_surface |
991 ? effect_node | 587 ? effect_node |
992 : effect_tree->Node(effect_node->target_id); | 588 : effect_tree->Node(effect_node->target_id); |
993 // TODO(weiliangc): When effect node has up to date render surface info on | 589 // TODO(weiliangc): When effect node has up to date render surface info on |
994 // compositor thread, no need to check for resourceless draw mode | 590 // compositor thread, no need to check for resourceless draw mode |
995 if (!property_trees->non_root_surfaces_enabled) { | 591 if (!property_trees->non_root_surfaces_enabled) { |
996 target_node = effect_tree->Node(1); | 592 target_node = effect_tree->Node(1); |
997 } | 593 } |
998 | 594 |
999 bool include_viewport_clip = false; | |
1000 bool include_expanding_clips = false; | 595 bool include_expanding_clips = false; |
1001 ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( | 596 return ComputeAccumulatedClip(property_trees, include_expanding_clips, |
1002 property_trees, include_viewport_clip, include_expanding_clips, | 597 layer->clip_tree_index(), target_node->id); |
1003 layer->clip_tree_index(), target_node->id); | |
1004 | |
1005 bool is_clipped_from_clip_tree = | |
1006 property_trees->non_root_surfaces_enabled | |
1007 ? clip_node->layers_are_clipped | |
1008 : clip_node->layers_are_clipped_when_surfaces_disabled; | |
1009 DCHECK_EQ(is_clipped_from_clip_tree, accumulated_clip_rect.is_clipped); | |
1010 | |
1011 gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect; | |
1012 | |
1013 DCHECK(layer->clip_rect() == gfx::ToEnclosingRect(accumulated_clip)) | |
1014 << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index() | |
1015 << " layer clip: " << layer->clip_rect().ToString() << " v.s. " | |
1016 << gfx::ToEnclosingRect(accumulated_clip).ToString() | |
1017 << " and clip node clip: " | |
1018 << gfx::ToEnclosingRect(clip_node->clip_in_target_space).ToString(); | |
1019 } | 598 } |
1020 | 599 |
1021 void ComputeVisibleRects(LayerImpl* root_layer, | 600 static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, |
1022 PropertyTrees* property_trees, | 601 LayerImpl* layer) { |
1023 bool can_render_to_separate_surface, | |
1024 LayerImplList* visible_layer_list) { | |
1025 bool render_surfaces_need_update = false; | |
1026 if (property_trees->non_root_surfaces_enabled != | |
1027 can_render_to_separate_surface) { | |
1028 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | |
1029 property_trees->transform_tree.set_needs_update(true); | |
1030 render_surfaces_need_update = true; | |
1031 } | |
1032 if (property_trees->transform_tree.needs_update()) { | |
1033 property_trees->clip_tree.set_needs_update(true); | |
1034 property_trees->effect_tree.set_needs_update(true); | |
1035 } | |
1036 | |
1037 if (render_surfaces_need_update) { | |
1038 property_trees->effect_tree.UpdateRenderSurfaces( | |
1039 root_layer->layer_tree_impl(), | |
1040 property_trees->non_root_surfaces_enabled); | |
1041 } | |
1042 UpdateRenderTarget(&property_trees->effect_tree, | |
1043 property_trees->non_root_surfaces_enabled); | |
1044 ComputeTransforms(&property_trees->transform_tree); | |
1045 // Computation of clips uses surface contents scale which is updated while | |
1046 // computing effects. So, ComputeEffects should be before ComputeClips. | |
1047 ComputeEffects(&property_trees->effect_tree); | |
1048 ComputeClips(property_trees, can_render_to_separate_surface); | |
1049 | |
1050 FindLayersThatNeedUpdates(root_layer->layer_tree_impl(), property_trees, | |
1051 visible_layer_list); | |
1052 CalculateClipRects(*visible_layer_list, property_trees, | |
1053 can_render_to_separate_surface); | |
1054 CalculateVisibleRects(*visible_layer_list, property_trees, | |
1055 can_render_to_separate_surface); | |
1056 } | |
1057 | |
1058 void UpdatePropertyTrees(PropertyTrees* property_trees, | |
1059 bool can_render_to_separate_surface) { | |
1060 if (property_trees->non_root_surfaces_enabled != | |
1061 can_render_to_separate_surface) { | |
1062 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | |
1063 property_trees->transform_tree.set_needs_update(true); | |
1064 } | |
1065 if (property_trees->transform_tree.needs_update()) { | |
1066 property_trees->clip_tree.set_needs_update(true); | |
1067 property_trees->effect_tree.set_needs_update(true); | |
1068 } | |
1069 ComputeTransforms(&property_trees->transform_tree); | |
1070 // Computation of clips uses surface contents scale which is updated while | |
1071 // computing effects. So, ComputeEffects should be before ComputeClips. | |
1072 ComputeEffects(&property_trees->effect_tree); | |
1073 ComputeClips(property_trees, can_render_to_separate_surface); | |
1074 } | |
1075 | |
1076 void BuildPropertyTreesAndComputeVisibleRects( | |
1077 LayerImpl* root_layer, | |
1078 const LayerImpl* page_scale_layer, | |
1079 const LayerImpl* inner_viewport_scroll_layer, | |
1080 const LayerImpl* outer_viewport_scroll_layer, | |
1081 const LayerImpl* overscroll_elasticity_layer, | |
1082 const gfx::Vector2dF& elastic_overscroll, | |
1083 float page_scale_factor, | |
1084 float device_scale_factor, | |
1085 const gfx::Rect& viewport, | |
1086 const gfx::Transform& device_transform, | |
1087 bool can_render_to_separate_surface, | |
1088 PropertyTrees* property_trees, | |
1089 LayerImplList* visible_layer_list) { | |
1090 PropertyTreeBuilder::BuildPropertyTrees( | |
1091 root_layer, page_scale_layer, inner_viewport_scroll_layer, | |
1092 outer_viewport_scroll_layer, overscroll_elasticity_layer, | |
1093 elastic_overscroll, page_scale_factor, device_scale_factor, viewport, | |
1094 device_transform, property_trees); | |
1095 ComputeVisibleRects(root_layer, property_trees, | |
1096 can_render_to_separate_surface, visible_layer_list); | |
1097 } | |
1098 | |
1099 void VerifyClipTreeCalculations(const LayerImplList& layer_list, | |
1100 PropertyTrees* property_trees) { | |
1101 if (property_trees->non_root_surfaces_enabled) { | |
1102 ComputeClipsWithEffectTree(property_trees); | |
1103 } | |
1104 for (auto* layer : layer_list) | |
1105 ComputeLayerClipRect(property_trees, layer); | |
1106 } | |
1107 | |
1108 gfx::Rect ComputeLayerVisibleRectDynamic(const PropertyTrees* property_trees, | |
1109 const LayerImpl* layer) { | |
1110 int effect_ancestor_with_copy_request = | 602 int effect_ancestor_with_copy_request = |
1111 property_trees->effect_tree.ClosestAncestorWithCopyRequest( | 603 property_trees->effect_tree.ClosestAncestorWithCopyRequest( |
1112 layer->effect_tree_index()); | 604 layer->effect_tree_index()); |
1113 bool non_root_copy_request = | 605 bool non_root_copy_request = |
1114 effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId; | 606 effect_ancestor_with_copy_request > EffectTree::kContentsRootNodeId; |
1115 gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); | 607 gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); |
1116 gfx::RectF accumulated_clip_in_root_space; | 608 gfx::RectF accumulated_clip_in_root_space; |
1117 if (non_root_copy_request) { | 609 if (non_root_copy_request) { |
1118 bool include_viewport_clip = false; | |
1119 bool include_expanding_clips = true; | 610 bool include_expanding_clips = true; |
1120 ConditionalClip accumulated_clip = ComputeAccumulatedClip( | 611 ConditionalClip accumulated_clip = ComputeAccumulatedClip( |
1121 property_trees, include_viewport_clip, include_expanding_clips, | 612 property_trees, include_expanding_clips, layer->clip_tree_index(), |
1122 layer->clip_tree_index(), effect_ancestor_with_copy_request); | 613 effect_ancestor_with_copy_request); |
1123 if (!accumulated_clip.is_clipped) | 614 if (!accumulated_clip.is_clipped) |
1124 return layer_content_rect; | 615 return layer_content_rect; |
1125 accumulated_clip_in_root_space = accumulated_clip.clip_rect; | 616 accumulated_clip_in_root_space = accumulated_clip.clip_rect; |
1126 } else { | 617 } else { |
618 const ClipNode* clip_node = | |
619 property_trees->clip_tree.Node(layer->clip_tree_index()); | |
1127 accumulated_clip_in_root_space = | 620 accumulated_clip_in_root_space = |
1128 ComputeAccumulatedClipInRootSpaceForVisibleRect( | 621 clip_node->accumulated_rect_in_screen_space; |
1129 property_trees, layer->clip_tree_index()); | |
1130 } | 622 } |
1131 | 623 |
1132 const EffectNode* root_effect_node = | 624 const EffectNode* root_effect_node = |
1133 non_root_copy_request | 625 non_root_copy_request |
1134 ? property_trees->effect_tree.Node(effect_ancestor_with_copy_request) | 626 ? property_trees->effect_tree.Node(effect_ancestor_with_copy_request) |
1135 : property_trees->effect_tree.Node(EffectTree::kContentsRootNodeId); | 627 : property_trees->effect_tree.Node(EffectTree::kContentsRootNodeId); |
1136 ConditionalClip accumulated_clip_in_layer_space = | 628 ConditionalClip accumulated_clip_in_layer_space = |
1137 ComputeTargetRectInLocalSpace( | 629 ComputeTargetRectInLocalSpace( |
1138 accumulated_clip_in_root_space, property_trees, | 630 accumulated_clip_in_root_space, property_trees, |
1139 root_effect_node->transform_id, layer->transform_tree_index(), | 631 root_effect_node->transform_id, layer->transform_tree_index(), |
1140 root_effect_node->id); | 632 root_effect_node->id); |
1141 if (!accumulated_clip_in_layer_space.is_clipped) | 633 if (!accumulated_clip_in_layer_space.is_clipped) { |
1142 return layer_content_rect; | 634 return layer_content_rect; |
635 } | |
1143 gfx::RectF clip_in_layer_space = accumulated_clip_in_layer_space.clip_rect; | 636 gfx::RectF clip_in_layer_space = accumulated_clip_in_layer_space.clip_rect; |
1144 clip_in_layer_space.Offset(-layer->offset_to_transform_parent()); | 637 clip_in_layer_space.Offset(-layer->offset_to_transform_parent()); |
1145 | 638 |
1146 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_in_layer_space); | 639 gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_in_layer_space); |
1147 visible_rect.Intersect(layer_content_rect); | 640 visible_rect.Intersect(layer_content_rect); |
1148 return visible_rect; | 641 return visible_rect; |
1149 } | 642 } |
1150 | 643 |
1151 void VerifyVisibleRectsCalculations(const LayerImplList& layer_list, | 644 void UpdatePropertyTrees(PropertyTrees* property_trees, |
1152 const PropertyTrees* property_trees) { | 645 bool can_render_to_separate_surface) { |
1153 for (auto* layer : layer_list) { | 646 if (property_trees->non_root_surfaces_enabled != |
1154 gfx::Rect visible_rect_dynamic = | 647 can_render_to_separate_surface) { |
1155 ComputeLayerVisibleRectDynamic(property_trees, layer); | 648 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; |
1156 DCHECK(layer->visible_layer_rect() == visible_rect_dynamic) | 649 property_trees->transform_tree.set_needs_update(true); |
1157 << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index() | |
1158 << " visible rect cached: " << layer->visible_layer_rect().ToString() | |
1159 << " v.s. " | |
1160 << " visible rect dynamic: " << visible_rect_dynamic.ToString(); | |
1161 } | 650 } |
651 if (property_trees->transform_tree.needs_update()) { | |
652 property_trees->clip_tree.set_needs_update(true); | |
653 property_trees->effect_tree.set_needs_update(true); | |
654 } | |
655 ComputeTransforms(&property_trees->transform_tree); | |
656 // Computation of clips uses surface contents scale which is updated while | |
657 // computing effects. So, ComputeEffects should be before ComputeClips. | |
658 ComputeEffects(&property_trees->effect_tree); | |
659 ComputeClips(property_trees); | |
weiliangc
2017/03/14 22:04:29
Also DCHECK in ComputeClips that effect tree doesn
jaydasika
2017/03/16 20:33:31
Actually, after creating a fast-path of using ToSc
| |
660 } | |
661 | |
662 void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, | |
663 PropertyTrees* property_trees, | |
664 bool can_render_to_separate_surface) { | |
665 bool render_surfaces_need_update = false; | |
666 if (property_trees->non_root_surfaces_enabled != | |
667 can_render_to_separate_surface) { | |
668 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | |
669 property_trees->transform_tree.set_needs_update(true); | |
670 render_surfaces_need_update = true; | |
671 } | |
672 if (property_trees->transform_tree.needs_update()) { | |
673 property_trees->clip_tree.set_needs_update(true); | |
674 property_trees->effect_tree.set_needs_update(true); | |
675 } | |
676 if (render_surfaces_need_update) { | |
677 property_trees->effect_tree.UpdateRenderSurfaces( | |
678 root_layer->layer_tree_impl(), | |
679 property_trees->non_root_surfaces_enabled); | |
680 } | |
681 UpdateRenderTarget(&property_trees->effect_tree, | |
682 property_trees->non_root_surfaces_enabled); | |
683 | |
684 ComputeTransforms(&property_trees->transform_tree); | |
685 // Computation of clips uses surface contents scale which is updated while | |
686 // computing effects. So, ComputeEffects should be before ComputeClips. | |
687 ComputeEffects(&property_trees->effect_tree); | |
688 ComputeClips(property_trees); | |
weiliangc
2017/03/14 22:04:30
DCHECK like above.
jaydasika
2017/03/16 20:33:30
Done.
| |
1162 } | 689 } |
1163 | 690 |
1164 bool LayerNeedsUpdate(Layer* layer, | 691 bool LayerNeedsUpdate(Layer* layer, |
1165 bool layer_is_drawn, | 692 bool layer_is_drawn, |
1166 const PropertyTrees* property_trees) { | 693 const PropertyTrees* property_trees) { |
1167 return LayerNeedsUpdateInternal(layer, layer_is_drawn, property_trees); | 694 return LayerNeedsUpdateInternal(layer, layer_is_drawn, property_trees); |
1168 } | 695 } |
1169 | 696 |
1170 bool LayerNeedsUpdate(LayerImpl* layer, | 697 bool LayerNeedsUpdate(LayerImpl* layer, |
1171 bool layer_is_drawn, | 698 bool layer_is_drawn, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1211 const EffectNode* target_effect_node = | 738 const EffectNode* target_effect_node = |
1212 effect_tree.Node(effect_node->target_id); | 739 effect_tree.Node(effect_node->target_id); |
1213 property_trees->GetToTarget(transform_node->id, target_effect_node->id, | 740 property_trees->GetToTarget(transform_node->id, target_effect_node->id, |
1214 &render_surface_transform); | 741 &render_surface_transform); |
1215 | 742 |
1216 ConcatInverseSurfaceContentsScale(effect_node, &render_surface_transform); | 743 ConcatInverseSurfaceContentsScale(effect_node, &render_surface_transform); |
1217 render_surface->SetDrawTransform(render_surface_transform); | 744 render_surface->SetDrawTransform(render_surface_transform); |
1218 } | 745 } |
1219 | 746 |
1220 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, | 747 static void SetSurfaceClipRect(const ClipNode* parent_clip_node, |
1221 const PropertyTrees* property_trees, | 748 PropertyTrees* property_trees, |
1222 RenderSurfaceImpl* render_surface) { | 749 RenderSurfaceImpl* render_surface) { |
1223 if (!render_surface->is_clipped()) { | 750 if (!render_surface->is_clipped()) { |
1224 render_surface->SetClipRect(gfx::Rect()); | 751 render_surface->SetClipRect(gfx::Rect()); |
1225 return; | 752 return; |
1226 } | 753 } |
1227 | 754 |
1228 const EffectTree& effect_tree = property_trees->effect_tree; | 755 const EffectTree& effect_tree = property_trees->effect_tree; |
1229 const TransformTree& transform_tree = property_trees->transform_tree; | 756 const ClipTree& clip_tree = property_trees->clip_tree; |
1230 const TransformNode* transform_node = | |
1231 transform_tree.Node(render_surface->TransformTreeIndex()); | |
1232 if (transform_tree.TargetId(transform_node->id) == | |
1233 parent_clip_node->target_transform_id) { | |
1234 render_surface->SetClipRect( | |
1235 gfx::ToEnclosingRect(parent_clip_node->clip_in_target_space)); | |
1236 return; | |
1237 } | |
1238 | |
1239 // In this case, the clip child has reset the clip node for subtree and hence | |
1240 // the parent clip node's clip rect is in clip parent's target space and not | |
1241 // our target space. We need to transform it to our target space. | |
1242 const EffectNode* effect_node = | 757 const EffectNode* effect_node = |
1243 effect_tree.Node(render_surface->EffectTreeIndex()); | 758 effect_tree.Node(render_surface->EffectTreeIndex()); |
1244 int target_effect_id = effect_node->target_id; | 759 const EffectNode* target_node = effect_tree.Node(effect_node->target_id); |
1245 gfx::RectF clip_rect; | 760 bool include_expanding_clips = false; |
1246 const bool success = ConvertRectBetweenSurfaceSpaces( | 761 if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { |
1247 property_trees, parent_clip_node->target_effect_id, target_effect_id, | 762 render_surface->SetClipRect( |
1248 parent_clip_node->clip_in_target_space, &clip_rect); | 763 gfx::ToEnclosingRect(clip_tree.Node(effect_node->clip_id)->clip)); |
1249 | 764 } else { |
1250 if (!success) { | 765 ConditionalClip accumulated_clip_rect = |
1251 render_surface->SetClipRect(gfx::Rect()); | 766 ComputeAccumulatedClip(property_trees, include_expanding_clips, |
1252 return; | 767 effect_node->clip_id, target_node->id); |
768 render_surface->SetClipRect( | |
769 gfx::ToEnclosingRect(accumulated_clip_rect.clip_rect)); | |
1253 } | 770 } |
1254 render_surface->SetClipRect(gfx::ToEnclosingRect(clip_rect)); | |
1255 } | 771 } |
1256 | 772 |
1257 template <typename LayerType> | 773 template <typename LayerType> |
1258 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, | 774 static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, |
1259 const TransformTree& tree) { | 775 const TransformTree& tree) { |
1260 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), | 776 gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), |
1261 layer->offset_to_transform_parent().y()); | 777 layer->offset_to_transform_parent().y()); |
1262 gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); | 778 gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); |
1263 xform.ConcatTransform(ssxform); | 779 xform.ConcatTransform(ssxform); |
1264 if (layer->should_flatten_transform_from_property_tree()) | 780 if (layer->should_flatten_transform_from_property_tree()) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1311 const LayerImpl* layer, | 827 const LayerImpl* layer, |
1312 const gfx::Rect& layer_bounds_in_target_space, | 828 const gfx::Rect& layer_bounds_in_target_space, |
1313 const gfx::Rect& clip_rect) { | 829 const gfx::Rect& clip_rect) { |
1314 if (layer->is_clipped()) | 830 if (layer->is_clipped()) |
1315 return IntersectRects(layer_bounds_in_target_space, clip_rect); | 831 return IntersectRects(layer_bounds_in_target_space, clip_rect); |
1316 | 832 |
1317 return layer_bounds_in_target_space; | 833 return layer_bounds_in_target_space; |
1318 } | 834 } |
1319 | 835 |
1320 void ComputeLayerDrawProperties(LayerImpl* layer, | 836 void ComputeLayerDrawProperties(LayerImpl* layer, |
1321 const PropertyTrees* property_trees) { | 837 PropertyTrees* property_trees) { |
1322 const TransformNode* transform_node = | 838 const TransformNode* transform_node = |
1323 property_trees->transform_tree.Node(layer->transform_tree_index()); | 839 property_trees->transform_tree.Node(layer->transform_tree_index()); |
1324 const ClipNode* clip_node = | |
1325 property_trees->clip_tree.Node(layer->clip_tree_index()); | |
1326 | 840 |
1327 layer->draw_properties().screen_space_transform = | 841 layer->draw_properties().screen_space_transform = |
1328 ScreenSpaceTransformInternal(layer, property_trees->transform_tree); | 842 ScreenSpaceTransformInternal(layer, property_trees->transform_tree); |
1329 layer->draw_properties().target_space_transform = DrawTransform( | 843 layer->draw_properties().target_space_transform = DrawTransform( |
1330 layer, property_trees->transform_tree, property_trees->effect_tree); | 844 layer, property_trees->transform_tree, property_trees->effect_tree); |
1331 layer->draw_properties().screen_space_transform_is_animating = | 845 layer->draw_properties().screen_space_transform_is_animating = |
1332 transform_node->to_screen_is_potentially_animated; | 846 transform_node->to_screen_is_potentially_animated; |
1333 | 847 |
1334 layer->draw_properties().opacity = | 848 layer->draw_properties().opacity = |
1335 LayerDrawOpacity(layer, property_trees->effect_tree); | 849 LayerDrawOpacity(layer, property_trees->effect_tree); |
1336 if (property_trees->non_root_surfaces_enabled) { | |
1337 layer->draw_properties().is_clipped = clip_node->layers_are_clipped; | |
1338 } else { | |
1339 layer->draw_properties().is_clipped = | |
1340 clip_node->layers_are_clipped_when_surfaces_disabled; | |
1341 } | |
1342 | 850 |
1343 gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( | 851 gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( |
1344 layer->draw_properties().target_space_transform, | 852 layer->draw_properties().target_space_transform, |
1345 gfx::Rect(layer->bounds())); | 853 gfx::Rect(layer->bounds())); |
854 ConditionalClip clip = LayerClipRect(property_trees, layer); | |
855 layer->draw_properties().is_clipped = clip.is_clipped; | |
856 layer->draw_properties().clip_rect = gfx::ToEnclosingRect(clip.clip_rect); | |
857 layer->draw_properties().visible_layer_rect = | |
858 LayerVisibleRect(property_trees, layer); | |
1346 layer->draw_properties().drawable_content_rect = LayerDrawableContentRect( | 859 layer->draw_properties().drawable_content_rect = LayerDrawableContentRect( |
1347 layer, bounds_in_target_space, layer->draw_properties().clip_rect); | 860 layer, bounds_in_target_space, layer->draw_properties().clip_rect); |
1348 } | 861 } |
1349 | 862 |
1350 void ComputeMaskDrawProperties(LayerImpl* mask_layer, | 863 void ComputeMaskDrawProperties(LayerImpl* mask_layer, |
1351 const PropertyTrees* property_trees) { | 864 const PropertyTrees* property_trees) { |
1352 // Mask draw properties are used only for rastering, so most of the draw | 865 // Mask draw properties are used only for rastering, so most of the draw |
1353 // properties computed for other layers are not needed. | 866 // properties computed for other layers are not needed. |
1354 mask_layer->draw_properties().screen_space_transform = | 867 mask_layer->draw_properties().screen_space_transform = |
1355 ScreenSpaceTransformInternal(mask_layer, | 868 ScreenSpaceTransformInternal(mask_layer, |
1356 property_trees->transform_tree); | 869 property_trees->transform_tree); |
1357 mask_layer->draw_properties().visible_layer_rect = | 870 mask_layer->draw_properties().visible_layer_rect = |
1358 gfx::Rect(mask_layer->bounds()); | 871 gfx::Rect(mask_layer->bounds()); |
1359 } | 872 } |
1360 | 873 |
1361 void ComputeSurfaceDrawProperties(const PropertyTrees* property_trees, | 874 void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, |
1362 RenderSurfaceImpl* render_surface) { | 875 RenderSurfaceImpl* render_surface) { |
1363 const EffectNode* effect_node = | 876 const EffectNode* effect_node = |
1364 property_trees->effect_tree.Node(render_surface->EffectTreeIndex()); | 877 property_trees->effect_tree.Node(render_surface->EffectTreeIndex()); |
1365 render_surface->SetIsClipped(effect_node->surface_is_clipped); | 878 render_surface->SetIsClipped(effect_node->surface_is_clipped); |
1366 SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); | 879 SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); |
1367 SetSurfaceDrawTransform(property_trees, render_surface); | 880 SetSurfaceDrawTransform(property_trees, render_surface); |
1368 render_surface->SetScreenSpaceTransform( | 881 render_surface->SetScreenSpaceTransform( |
1369 property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( | 882 property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( |
1370 render_surface->TransformTreeIndex(), | 883 render_surface->TransformTreeIndex(), |
1371 render_surface->EffectTreeIndex())); | 884 render_surface->EffectTreeIndex())); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1471 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 984 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
1472 const Layer* overscroll_elasticity_layer, | 985 const Layer* overscroll_elasticity_layer, |
1473 const gfx::Vector2dF& elastic_overscroll) { | 986 const gfx::Vector2dF& elastic_overscroll) { |
1474 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 987 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
1475 elastic_overscroll); | 988 elastic_overscroll); |
1476 } | 989 } |
1477 | 990 |
1478 } // namespace draw_property_utils | 991 } // namespace draw_property_utils |
1479 | 992 |
1480 } // namespace cc | 993 } // namespace cc |
OLD | NEW |