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/property_tree_builder.h" | 5 #include "cc/trees/property_tree_builder.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 const LayerType* inner_viewport_scroll_layer; | 46 const LayerType* inner_viewport_scroll_layer; |
47 const LayerType* outer_viewport_scroll_layer; | 47 const LayerType* outer_viewport_scroll_layer; |
48 const LayerType* overscroll_elasticity_layer; | 48 const LayerType* overscroll_elasticity_layer; |
49 gfx::Vector2dF elastic_overscroll; | 49 gfx::Vector2dF elastic_overscroll; |
50 float page_scale_factor; | 50 float page_scale_factor; |
51 bool in_subtree_of_page_scale_layer; | 51 bool in_subtree_of_page_scale_layer; |
52 bool affected_by_inner_viewport_bounds_delta; | 52 bool affected_by_inner_viewport_bounds_delta; |
53 bool affected_by_outer_viewport_bounds_delta; | 53 bool affected_by_outer_viewport_bounds_delta; |
54 bool should_flatten; | 54 bool should_flatten; |
55 bool is_hidden; | 55 bool is_hidden; |
| 56 bool apply_ancestor_clip; |
56 uint32_t main_thread_scrolling_reasons; | 57 uint32_t main_thread_scrolling_reasons; |
57 bool scroll_tree_parent_created_by_uninheritable_criteria; | 58 bool scroll_tree_parent_created_by_uninheritable_criteria; |
58 const gfx::Transform* device_transform; | 59 const gfx::Transform* device_transform; |
59 gfx::Transform compound_transform_since_render_target; | 60 gfx::Transform compound_transform_since_render_target; |
60 bool axis_align_since_render_target; | 61 bool axis_align_since_render_target; |
61 SkColor safe_opaque_background_color; | 62 SkColor safe_opaque_background_color; |
62 }; | 63 }; |
63 | 64 |
64 template <typename LayerType> | 65 template <typename LayerType> |
65 struct DataForRecursionFromChild { | 66 struct DataForRecursionFromChild { |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 | 301 |
301 template <typename LayerType> | 302 template <typename LayerType> |
302 static LayerType* GetTransformParent(const DataForRecursion<LayerType>& data, | 303 static LayerType* GetTransformParent(const DataForRecursion<LayerType>& data, |
303 LayerType* layer) { | 304 LayerType* layer) { |
304 return PositionConstraint(layer).is_fixed_position() | 305 return PositionConstraint(layer).is_fixed_position() |
305 ? data.transform_fixed_parent | 306 ? data.transform_fixed_parent |
306 : data.transform_tree_parent; | 307 : data.transform_tree_parent; |
307 } | 308 } |
308 | 309 |
309 template <typename LayerType> | 310 template <typename LayerType> |
310 static ClipNode* GetClipParent(const DataForRecursion<LayerType>& data, | |
311 LayerType* layer) { | |
312 const bool inherits_clip = !ClipParent(layer); | |
313 const int id = inherits_clip ? data.clip_tree_parent | |
314 : ClipParent(layer)->clip_tree_index(); | |
315 return data.property_trees->clip_tree.Node(id); | |
316 } | |
317 | |
318 template <typename LayerType> | |
319 static bool LayerClipsSubtree(LayerType* layer) { | 311 static bool LayerClipsSubtree(LayerType* layer) { |
320 return layer->masks_to_bounds() || MaskLayer(layer); | 312 return layer->masks_to_bounds() || MaskLayer(layer); |
321 } | 313 } |
322 | 314 |
323 template <typename LayerType> | 315 template <typename LayerType> |
324 static int GetScrollParentId(const DataForRecursion<LayerType>& data, | 316 static int GetScrollParentId(const DataForRecursion<LayerType>& data, |
325 LayerType* layer) { | 317 LayerType* layer) { |
326 const bool inherits_scroll = !ScrollParent(layer); | 318 const bool inherits_scroll = !ScrollParent(layer); |
327 const int id = inherits_scroll ? data.scroll_tree_parent | 319 const int id = inherits_scroll ? data.scroll_tree_parent |
328 : ScrollParent(layer)->scroll_tree_index(); | 320 : ScrollParent(layer)->scroll_tree_index(); |
329 return id; | 321 return id; |
330 } | 322 } |
331 | 323 |
332 static Layer* Parent(Layer* layer) { | 324 static Layer* Parent(Layer* layer) { |
333 return layer->parent(); | 325 return layer->parent(); |
334 } | 326 } |
335 | 327 |
336 static LayerImpl* Parent(LayerImpl* layer) { | 328 static LayerImpl* Parent(LayerImpl* layer) { |
337 return layer->test_properties()->parent; | 329 return layer->test_properties()->parent; |
338 } | 330 } |
339 | 331 |
340 template <typename LayerType> | 332 template <typename LayerType> |
| 333 static void SetSurfaceIsClipped(DataForRecursion<LayerType>* data_for_children, |
| 334 bool apply_ancestor_clip, |
| 335 LayerType* layer) { |
| 336 // A surface with unclipped descendants cannot be clipped by its ancestor |
| 337 // clip at draw time since the unclipped descendants aren't affected by the |
| 338 // ancestor clip. |
| 339 EffectNode* effect_node = data_for_children->property_trees->effect_tree.Node( |
| 340 data_for_children->render_target); |
| 341 DCHECK_EQ(effect_node->owner_id, layer->id()); |
| 342 effect_node->surface_is_clipped = |
| 343 apply_ancestor_clip && !NumUnclippedDescendants(layer); |
| 344 // The ancestor clip should propagate to children only if the surface doesn't |
| 345 // apply the clip. |
| 346 data_for_children->apply_ancestor_clip = |
| 347 apply_ancestor_clip && !effect_node->surface_is_clipped; |
| 348 } |
| 349 |
| 350 template <typename LayerType> |
341 void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, | 351 void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, |
342 LayerType* layer, | 352 LayerType* layer, |
343 bool created_render_surface, | 353 bool created_render_surface, |
344 bool created_transform_node, | 354 bool created_transform_node, |
345 DataForRecursion<LayerType>* data_for_children) { | 355 DataForRecursion<LayerType>* data_for_children) { |
346 ClipNode* parent = GetClipParent(data_from_ancestor, layer); | 356 const bool inherits_clip = !ClipParent(layer); |
347 int parent_id = parent->id; | 357 const int parent_id = inherits_clip ? data_from_ancestor.clip_tree_parent |
| 358 : ClipParent(layer)->clip_tree_index(); |
| 359 ClipNode* parent = |
| 360 data_from_ancestor.property_trees->clip_tree.Node(parent_id); |
348 | 361 |
349 bool is_root = !Parent(layer); | 362 bool apply_ancestor_clip = inherits_clip |
350 | 363 ? data_from_ancestor.apply_ancestor_clip |
351 // Whether we have an ancestor clip that we might need to apply. | 364 : parent->layers_are_clipped; |
352 bool ancestor_clips_subtree = is_root || parent->layers_are_clipped; | |
353 | 365 |
354 bool layers_are_clipped = false; | 366 bool layers_are_clipped = false; |
355 bool has_unclipped_surface = false; | 367 bool has_unclipped_surface = false; |
356 | 368 |
357 if (created_render_surface) { | 369 if (created_render_surface) { |
| 370 SetSurfaceIsClipped(data_for_children, apply_ancestor_clip, layer); |
358 // Clips can usually be applied to a surface's descendants simply by | 371 // Clips can usually be applied to a surface's descendants simply by |
359 // clipping the surface (or applied implicitly by the surface's bounds). | 372 // clipping the surface (or applied implicitly by the surface's bounds). |
360 // However, if the surface has unclipped descendants (layers that aren't | 373 // However, if the surface has unclipped descendants (layers that aren't |
361 // affected by the ancestor clip), we cannot clip the surface itself, and | 374 // affected by the ancestor clip), we cannot clip the surface itself, and |
362 // must instead apply clips to the clipped descendants. | 375 // must instead apply clips to the clipped descendants. |
363 if (ancestor_clips_subtree && NumUnclippedDescendants(layer) > 0) { | 376 if (apply_ancestor_clip && NumUnclippedDescendants(layer) > 0) { |
364 layers_are_clipped = true; | 377 layers_are_clipped = true; |
365 } else if (!ancestor_clips_subtree) { | 378 } else if (!apply_ancestor_clip) { |
366 // When there are no ancestor clips that need to be applied to a render | 379 // When there are no ancestor clips that need to be applied to a render |
367 // surface, we reset clipping state. The surface might contribute a clip | 380 // surface, we reset clipping state. The surface might contribute a clip |
368 // of its own, but clips from ancestor nodes don't need to be considered | 381 // of its own, but clips from ancestor nodes don't need to be considered |
369 // when computing clip rects or visibility. | 382 // when computing clip rects or visibility. |
370 has_unclipped_surface = true; | 383 has_unclipped_surface = true; |
371 DCHECK_NE(parent->clip_type, ClipNode::ClipType::APPLIES_LOCAL_CLIP); | 384 DCHECK_NE(parent->clip_type, ClipNode::ClipType::APPLIES_LOCAL_CLIP); |
372 } | 385 } |
373 // A surface with unclipped descendants cannot be clipped by its ancestor | |
374 // clip at draw time since the unclipped descendants aren't affected by the | |
375 // ancestor clip. | |
376 EffectNode* effect_node = | |
377 data_for_children->property_trees->effect_tree.Node( | |
378 data_for_children->render_target); | |
379 DCHECK(effect_node->owner_id == layer->id()); | |
380 effect_node->surface_is_clipped = | |
381 ancestor_clips_subtree && !NumUnclippedDescendants(layer); | |
382 } else { | 386 } else { |
383 // Without a new render surface, layer clipping state from ancestors needs | 387 // Without a new render surface, layer clipping state from ancestors needs |
384 // to continue to propagate. | 388 // to continue to propagate. |
385 layers_are_clipped = ancestor_clips_subtree; | 389 layers_are_clipped = apply_ancestor_clip; |
386 } | 390 } |
387 | 391 |
388 bool layer_clips_subtree = LayerClipsSubtree(layer); | 392 bool layer_clips_subtree = LayerClipsSubtree(layer); |
389 if (layer_clips_subtree) | 393 if (layer_clips_subtree) { |
390 layers_are_clipped = true; | 394 layers_are_clipped = true; |
| 395 data_for_children->apply_ancestor_clip = true; |
| 396 } |
391 | 397 |
392 // Without surfaces, all non-viewport clips have to be applied using layer | 398 // Without surfaces, all non-viewport clips have to be applied using layer |
393 // clipping. | 399 // clipping. |
394 bool layers_are_clipped_when_surfaces_disabled = | 400 bool layers_are_clipped_when_surfaces_disabled = |
395 layer_clips_subtree || parent->layers_are_clipped_when_surfaces_disabled; | 401 layer_clips_subtree || parent->layers_are_clipped_when_surfaces_disabled; |
396 | 402 |
397 // Render surface's clip is needed during hit testing. So, we need to create | 403 // Render surface's clip is needed during hit testing. So, we need to create |
398 // a clip node for every render surface. | 404 // a clip node for every render surface. |
399 bool requires_node = layer_clips_subtree || created_render_surface; | 405 bool requires_node = layer_clips_subtree || created_render_surface; |
400 | 406 |
(...skipping 11 matching lines...) Expand all Loading... |
412 ClipNode node; | 418 ClipNode node; |
413 node.clip = gfx::RectF(gfx::PointF() + layer->offset_to_transform_parent(), | 419 node.clip = gfx::RectF(gfx::PointF() + layer->offset_to_transform_parent(), |
414 gfx::SizeF(layer->bounds())); | 420 gfx::SizeF(layer->bounds())); |
415 node.transform_id = transform_parent->transform_tree_index(); | 421 node.transform_id = transform_parent->transform_tree_index(); |
416 node.target_effect_id = data_for_children->render_target; | 422 node.target_effect_id = data_for_children->render_target; |
417 node.target_transform_id = data_for_children->property_trees->effect_tree | 423 node.target_transform_id = data_for_children->property_trees->effect_tree |
418 .Node(data_for_children->render_target) | 424 .Node(data_for_children->render_target) |
419 ->transform_id; | 425 ->transform_id; |
420 node.owner_id = layer->id(); | 426 node.owner_id = layer->id(); |
421 | 427 |
422 if (ancestor_clips_subtree || layer_clips_subtree) { | 428 if (apply_ancestor_clip || layer_clips_subtree) { |
423 // Surfaces reset the rect used for layer clipping. At other nodes, layer | 429 // Surfaces reset the rect used for layer clipping. At other nodes, layer |
424 // clipping state from ancestors must continue to get propagated. | 430 // clipping state from ancestors must continue to get propagated. |
425 node.layer_clipping_uses_only_local_clip = | 431 node.layer_clipping_uses_only_local_clip = |
426 (created_render_surface && NumUnclippedDescendants(layer) == 0) || | 432 (created_render_surface && NumUnclippedDescendants(layer) == 0) || |
427 !ancestor_clips_subtree; | 433 !apply_ancestor_clip; |
428 } else { | 434 } else { |
429 // Otherwise, we're either unclipped, or exist only in order to apply our | 435 // Otherwise, we're either unclipped, or exist only in order to apply our |
430 // parent's clips in our space. | 436 // parent's clips in our space. |
431 node.layer_clipping_uses_only_local_clip = false; | 437 node.layer_clipping_uses_only_local_clip = false; |
432 } | 438 } |
433 | 439 |
434 if (layer_clips_subtree) | 440 if (layer_clips_subtree) |
435 node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; | 441 node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; |
436 else | 442 else |
437 node.clip_type = ClipNode::ClipType::NONE; | 443 node.clip_type = ClipNode::ClipType::NONE; |
(...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1384 data_for_recursion.inner_viewport_scroll_layer = inner_viewport_scroll_layer; | 1390 data_for_recursion.inner_viewport_scroll_layer = inner_viewport_scroll_layer; |
1385 data_for_recursion.outer_viewport_scroll_layer = outer_viewport_scroll_layer; | 1391 data_for_recursion.outer_viewport_scroll_layer = outer_viewport_scroll_layer; |
1386 data_for_recursion.overscroll_elasticity_layer = overscroll_elasticity_layer; | 1392 data_for_recursion.overscroll_elasticity_layer = overscroll_elasticity_layer; |
1387 data_for_recursion.elastic_overscroll = elastic_overscroll; | 1393 data_for_recursion.elastic_overscroll = elastic_overscroll; |
1388 data_for_recursion.page_scale_factor = page_scale_factor; | 1394 data_for_recursion.page_scale_factor = page_scale_factor; |
1389 data_for_recursion.in_subtree_of_page_scale_layer = false; | 1395 data_for_recursion.in_subtree_of_page_scale_layer = false; |
1390 data_for_recursion.affected_by_inner_viewport_bounds_delta = false; | 1396 data_for_recursion.affected_by_inner_viewport_bounds_delta = false; |
1391 data_for_recursion.affected_by_outer_viewport_bounds_delta = false; | 1397 data_for_recursion.affected_by_outer_viewport_bounds_delta = false; |
1392 data_for_recursion.should_flatten = false; | 1398 data_for_recursion.should_flatten = false; |
1393 data_for_recursion.is_hidden = false; | 1399 data_for_recursion.is_hidden = false; |
| 1400 // The root clip is always applied. |
| 1401 data_for_recursion.apply_ancestor_clip = true; |
1394 data_for_recursion.main_thread_scrolling_reasons = | 1402 data_for_recursion.main_thread_scrolling_reasons = |
1395 MainThreadScrollingReason::kNotScrollingOnMain; | 1403 MainThreadScrollingReason::kNotScrollingOnMain; |
1396 data_for_recursion.scroll_tree_parent_created_by_uninheritable_criteria = | 1404 data_for_recursion.scroll_tree_parent_created_by_uninheritable_criteria = |
1397 true; | 1405 true; |
1398 data_for_recursion.device_transform = &device_transform; | 1406 data_for_recursion.device_transform = &device_transform; |
1399 | 1407 |
1400 data_for_recursion.property_trees->clear(); | 1408 data_for_recursion.property_trees->clear(); |
1401 data_for_recursion.compound_transform_since_render_target = gfx::Transform(); | 1409 data_for_recursion.compound_transform_since_render_target = gfx::Transform(); |
1402 data_for_recursion.axis_align_since_render_target = true; | 1410 data_for_recursion.axis_align_since_render_target = true; |
1403 data_for_recursion.property_trees->transform_tree.set_device_scale_factor( | 1411 data_for_recursion.property_trees->transform_tree.set_device_scale_factor( |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 color = SkColorSetA(color, 255); | 1504 color = SkColorSetA(color, 255); |
1497 BuildPropertyTreesTopLevelInternal( | 1505 BuildPropertyTreesTopLevelInternal( |
1498 root_layer, page_scale_layer, inner_viewport_scroll_layer, | 1506 root_layer, page_scale_layer, inner_viewport_scroll_layer, |
1499 outer_viewport_scroll_layer, overscroll_elasticity_layer, | 1507 outer_viewport_scroll_layer, overscroll_elasticity_layer, |
1500 elastic_overscroll, page_scale_factor, device_scale_factor, viewport, | 1508 elastic_overscroll, page_scale_factor, device_scale_factor, viewport, |
1501 device_transform, property_trees, color); | 1509 device_transform, property_trees, color); |
1502 property_trees->ResetCachedData(); | 1510 property_trees->ResetCachedData(); |
1503 } | 1511 } |
1504 | 1512 |
1505 } // namespace cc | 1513 } // namespace cc |
OLD | NEW |