| 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 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 data_for_children->render_target); | 351 data_for_children->render_target); |
| 352 DCHECK_EQ(effect_node->owning_layer_id, layer->id()); | 352 DCHECK_EQ(effect_node->owning_layer_id, layer->id()); |
| 353 effect_node->surface_is_clipped = | 353 effect_node->surface_is_clipped = |
| 354 apply_ancestor_clip && !NumUnclippedDescendants(layer); | 354 apply_ancestor_clip && !NumUnclippedDescendants(layer); |
| 355 // The ancestor clip should propagate to children only if the surface doesn't | 355 // The ancestor clip should propagate to children only if the surface doesn't |
| 356 // apply the clip. | 356 // apply the clip. |
| 357 data_for_children->apply_ancestor_clip = | 357 data_for_children->apply_ancestor_clip = |
| 358 apply_ancestor_clip && !effect_node->surface_is_clipped; | 358 apply_ancestor_clip && !effect_node->surface_is_clipped; |
| 359 } | 359 } |
| 360 | 360 |
| 361 static inline int SortingContextId(Layer* layer) { |
| 362 return layer->sorting_context_id(); |
| 363 } |
| 364 |
| 365 static inline int SortingContextId(LayerImpl* layer) { |
| 366 return layer->test_properties()->sorting_context_id; |
| 367 } |
| 368 |
| 369 static inline bool Is3dSorted(Layer* layer) { |
| 370 return layer->Is3dSorted(); |
| 371 } |
| 372 |
| 373 static inline bool Is3dSorted(LayerImpl* layer) { |
| 374 return layer->test_properties()->sorting_context_id != 0; |
| 375 } |
| 376 |
| 361 template <typename LayerType> | 377 template <typename LayerType> |
| 362 void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, | 378 void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, |
| 363 LayerType* layer, | 379 LayerType* layer, |
| 364 bool created_render_surface, | 380 bool created_render_surface, |
| 365 bool created_transform_node, | 381 bool created_transform_node, |
| 366 DataForRecursion<LayerType>* data_for_children) { | 382 DataForRecursion<LayerType>* data_for_children) { |
| 367 const bool inherits_clip = !ClipParent(layer); | 383 const bool inherits_clip = !ClipParent(layer); |
| 368 const int parent_id = inherits_clip ? data_from_ancestor.clip_tree_parent | 384 const int parent_id = inherits_clip ? data_from_ancestor.clip_tree_parent |
| 369 : ClipParent(layer)->clip_tree_index(); | 385 : ClipParent(layer)->clip_tree_index(); |
| 370 ClipNode* parent = | 386 ClipNode* parent = |
| 371 data_from_ancestor.property_trees->clip_tree.Node(parent_id); | 387 data_from_ancestor.property_trees->clip_tree.Node(parent_id); |
| 372 | 388 |
| 373 bool apply_ancestor_clip = inherits_clip | 389 bool apply_ancestor_clip = false; |
| 374 ? data_from_ancestor.apply_ancestor_clip | 390 if (inherits_clip) { |
| 375 : parent->layers_are_clipped; | 391 apply_ancestor_clip = data_from_ancestor.apply_ancestor_clip; |
| 376 | 392 } else { |
| 377 bool layers_are_clipped = false; | 393 const EffectNode* parent_effect_node = |
| 378 bool has_unclipped_surface = false; | 394 data_from_ancestor.property_trees->effect_tree.Node( |
| 379 | 395 ClipParent(layer)->effect_tree_index()); |
| 380 if (created_render_surface) { | 396 if (parent_effect_node->clip_id == parent->id) { |
| 397 if (parent_effect_node->surface_is_clipped) { |
| 398 // In this case, there is no clipping layer between the clip parent and |
| 399 // its target and the target has applied the clip. |
| 400 apply_ancestor_clip = false; |
| 401 } else { |
| 402 // In this case, there is no clipping layer between the clip parent and |
| 403 // its target and the target has not applied the clip. There are two |
| 404 // cases when a target doesn't apply clip. First, there is no ancestor |
| 405 // clip to apply, in this case apply_ancestor_clip should be false. |
| 406 // Second, there is a clip to apply but there are unclipped descendants, |
| 407 // so the target cannot apply the clip. In this case, |
| 408 // apply_ancestor_clip should be true. |
| 409 apply_ancestor_clip = parent_effect_node->has_unclipped_descendants; |
| 410 } |
| 411 } else { |
| 412 // In this case, there is a clipping layer between the clip parent and |
| 413 // its target. |
| 414 apply_ancestor_clip = true; |
| 415 } |
| 416 } |
| 417 if (created_render_surface) |
| 381 SetSurfaceIsClipped(data_for_children, apply_ancestor_clip, layer); | 418 SetSurfaceIsClipped(data_for_children, apply_ancestor_clip, layer); |
| 382 // Clips can usually be applied to a surface's descendants simply by | |
| 383 // clipping the surface (or applied implicitly by the surface's bounds). | |
| 384 // However, if the surface has unclipped descendants (layers that aren't | |
| 385 // affected by the ancestor clip), we cannot clip the surface itself, and | |
| 386 // must instead apply clips to the clipped descendants. | |
| 387 if (apply_ancestor_clip && NumUnclippedDescendants(layer) > 0) { | |
| 388 layers_are_clipped = true; | |
| 389 } else if (!apply_ancestor_clip) { | |
| 390 // When there are no ancestor clips that need to be applied to a render | |
| 391 // surface, we reset clipping state. The surface might contribute a clip | |
| 392 // of its own, but clips from ancestor nodes don't need to be considered | |
| 393 // when computing clip rects or visibility. | |
| 394 has_unclipped_surface = true; | |
| 395 DCHECK_NE(parent->clip_type, ClipNode::ClipType::APPLIES_LOCAL_CLIP); | |
| 396 } | |
| 397 } else { | |
| 398 // Without a new render surface, layer clipping state from ancestors needs | |
| 399 // to continue to propagate. | |
| 400 layers_are_clipped = apply_ancestor_clip; | |
| 401 } | |
| 402 | 419 |
| 403 bool layer_clips_subtree = LayerClipsSubtree(layer); | 420 bool layer_clips_subtree = LayerClipsSubtree(layer); |
| 404 if (layer_clips_subtree) { | 421 if (layer_clips_subtree) { |
| 405 layers_are_clipped = true; | |
| 406 data_for_children->apply_ancestor_clip = true; | 422 data_for_children->apply_ancestor_clip = true; |
| 407 } | 423 } |
| 408 | 424 |
| 409 // Without surfaces, all non-viewport clips have to be applied using layer | 425 bool requires_node = |
| 410 // clipping. | 426 layer_clips_subtree || Filters(layer).HasFilterThatMovesPixels(); |
| 411 bool layers_are_clipped_when_surfaces_disabled = | |
| 412 layer_clips_subtree || parent->layers_are_clipped_when_surfaces_disabled; | |
| 413 | |
| 414 // Render surface's clip is needed during hit testing. So, we need to create | |
| 415 // a clip node for every render surface. | |
| 416 bool requires_node = layer_clips_subtree || created_render_surface; | |
| 417 | |
| 418 if (!requires_node) { | 427 if (!requires_node) { |
| 419 data_for_children->clip_tree_parent = parent_id; | 428 data_for_children->clip_tree_parent = parent_id; |
| 420 DCHECK_EQ(layers_are_clipped, parent->layers_are_clipped); | |
| 421 DCHECK_EQ(layers_are_clipped_when_surfaces_disabled, | |
| 422 parent->layers_are_clipped_when_surfaces_disabled); | |
| 423 } else { | 429 } else { |
| 424 LayerType* transform_parent = data_for_children->transform_tree_parent; | 430 LayerType* transform_parent = data_for_children->transform_tree_parent; |
| 425 if (PositionConstraint(layer).is_fixed_position() && | 431 if (PositionConstraint(layer).is_fixed_position() && |
| 426 !created_transform_node) { | 432 !created_transform_node) { |
| 427 transform_parent = data_for_children->transform_fixed_parent; | 433 transform_parent = data_for_children->transform_fixed_parent; |
| 428 } | 434 } |
| 429 ClipNode node; | 435 ClipNode node; |
| 430 node.clip = gfx::RectF(gfx::PointF() + layer->offset_to_transform_parent(), | 436 node.clip = gfx::RectF(gfx::PointF() + layer->offset_to_transform_parent(), |
| 431 gfx::SizeF(layer->bounds())); | 437 gfx::SizeF(layer->bounds())); |
| 432 node.transform_id = transform_parent->transform_tree_index(); | 438 node.transform_id = transform_parent->transform_tree_index(); |
| 433 node.target_effect_id = data_for_children->render_target; | |
| 434 node.target_transform_id = data_for_children->property_trees->effect_tree | |
| 435 .Node(data_for_children->render_target) | |
| 436 ->transform_id; | |
| 437 node.owning_layer_id = layer->id(); | 439 node.owning_layer_id = layer->id(); |
| 438 | |
| 439 if (apply_ancestor_clip || layer_clips_subtree) { | |
| 440 // Surfaces reset the rect used for layer clipping. At other nodes, layer | |
| 441 // clipping state from ancestors must continue to get propagated. | |
| 442 node.layer_clipping_uses_only_local_clip = | |
| 443 (created_render_surface && NumUnclippedDescendants(layer) == 0) || | |
| 444 !apply_ancestor_clip; | |
| 445 } else { | |
| 446 // Otherwise, we're either unclipped, or exist only in order to apply our | |
| 447 // parent's clips in our space. | |
| 448 node.layer_clipping_uses_only_local_clip = false; | |
| 449 } | |
| 450 | |
| 451 if (layer_clips_subtree) { | 440 if (layer_clips_subtree) { |
| 452 node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; | 441 node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; |
| 453 } else if (Filters(layer).HasFilterThatMovesPixels()) { | 442 } else { |
| 443 DCHECK(Filters(layer).HasFilterThatMovesPixels()); |
| 454 node.clip_type = ClipNode::ClipType::EXPANDS_CLIP; | 444 node.clip_type = ClipNode::ClipType::EXPANDS_CLIP; |
| 455 node.clip_expander = | 445 node.clip_expander = |
| 456 base::MakeUnique<ClipExpander>(layer->effect_tree_index()); | 446 base::MakeUnique<ClipExpander>(layer->effect_tree_index()); |
| 457 } else { | |
| 458 node.clip_type = ClipNode::ClipType::NONE; | |
| 459 } | 447 } |
| 460 node.resets_clip = has_unclipped_surface; | |
| 461 node.layers_are_clipped = layers_are_clipped; | |
| 462 node.layers_are_clipped_when_surfaces_disabled = | |
| 463 layers_are_clipped_when_surfaces_disabled; | |
| 464 | |
| 465 data_for_children->clip_tree_parent = | 448 data_for_children->clip_tree_parent = |
| 466 data_for_children->property_trees->clip_tree.Insert(node, parent_id); | 449 data_for_children->property_trees->clip_tree.Insert(node, parent_id); |
| 467 data_for_children->property_trees->clip_tree.SetOwningLayerIdForNode( | 450 data_for_children->property_trees->clip_tree.SetOwningLayerIdForNode( |
| 468 data_for_children->property_trees->clip_tree.back(), layer->id()); | 451 data_for_children->property_trees->clip_tree.back(), layer->id()); |
| 469 } | 452 } |
| 470 | 453 |
| 471 layer->SetClipTreeIndex(data_for_children->clip_tree_parent); | 454 layer->SetClipTreeIndex(data_for_children->clip_tree_parent); |
| 472 } | 455 } |
| 473 | 456 |
| 474 static inline int SortingContextId(Layer* layer) { | |
| 475 return layer->sorting_context_id(); | |
| 476 } | |
| 477 | |
| 478 static inline int SortingContextId(LayerImpl* layer) { | |
| 479 return layer->test_properties()->sorting_context_id; | |
| 480 } | |
| 481 | |
| 482 static inline bool Is3dSorted(Layer* layer) { | |
| 483 return layer->Is3dSorted(); | |
| 484 } | |
| 485 | |
| 486 static inline bool Is3dSorted(LayerImpl* layer) { | |
| 487 return layer->test_properties()->sorting_context_id != 0; | |
| 488 } | |
| 489 | |
| 490 template <typename LayerType> | 457 template <typename LayerType> |
| 491 static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { | 458 static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { |
| 492 return Parent(layer) | 459 return Parent(layer) |
| 493 ? SortingContextId(Parent(layer)) != SortingContextId(layer) | 460 ? SortingContextId(Parent(layer)) != SortingContextId(layer) |
| 494 : Is3dSorted(layer); | 461 : Is3dSorted(layer); |
| 495 } | 462 } |
| 496 | 463 |
| 497 static inline gfx::Point3F TransformOrigin(Layer* layer) { | 464 static inline gfx::Point3F TransformOrigin(Layer* layer) { |
| 498 return layer->transform_origin(); | 465 return layer->transform_origin(); |
| 499 } | 466 } |
| (...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1450 data_for_recursion.device_transform = &device_transform; | 1417 data_for_recursion.device_transform = &device_transform; |
| 1451 | 1418 |
| 1452 data_for_recursion.property_trees->clear(); | 1419 data_for_recursion.property_trees->clear(); |
| 1453 data_for_recursion.compound_transform_since_render_target = gfx::Transform(); | 1420 data_for_recursion.compound_transform_since_render_target = gfx::Transform(); |
| 1454 data_for_recursion.axis_align_since_render_target = true; | 1421 data_for_recursion.axis_align_since_render_target = true; |
| 1455 data_for_recursion.property_trees->transform_tree.set_device_scale_factor( | 1422 data_for_recursion.property_trees->transform_tree.set_device_scale_factor( |
| 1456 device_scale_factor); | 1423 device_scale_factor); |
| 1457 data_for_recursion.safe_opaque_background_color = color; | 1424 data_for_recursion.safe_opaque_background_color = color; |
| 1458 | 1425 |
| 1459 ClipNode root_clip; | 1426 ClipNode root_clip; |
| 1460 root_clip.resets_clip = true; | |
| 1461 root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; | 1427 root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; |
| 1462 root_clip.clip = gfx::RectF(viewport); | 1428 root_clip.clip = gfx::RectF(viewport); |
| 1463 root_clip.transform_id = TransformTree::kRootNodeId; | 1429 root_clip.transform_id = TransformTree::kRootNodeId; |
| 1464 root_clip.target_transform_id = TransformTree::kRootNodeId; | |
| 1465 data_for_recursion.clip_tree_parent = | 1430 data_for_recursion.clip_tree_parent = |
| 1466 data_for_recursion.property_trees->clip_tree.Insert( | 1431 data_for_recursion.property_trees->clip_tree.Insert( |
| 1467 root_clip, ClipTree::kRootNodeId); | 1432 root_clip, ClipTree::kRootNodeId); |
| 1468 | 1433 |
| 1469 DataForRecursionFromChild<LayerType> data_from_child; | 1434 DataForRecursionFromChild<LayerType> data_from_child; |
| 1470 BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child); | 1435 BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child); |
| 1471 property_trees->needs_rebuild = false; | 1436 property_trees->needs_rebuild = false; |
| 1472 | 1437 |
| 1473 // The transform tree is kept up to date as it is built, but the | 1438 // The transform tree is kept up to date as it is built, but the |
| 1474 // combined_clips stored in the clip tree and the screen_space_opacity and | 1439 // combined_clips stored in the clip tree and the screen_space_opacity and |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1553 root_layer, page_scale_layer, inner_viewport_scroll_layer, | 1518 root_layer, page_scale_layer, inner_viewport_scroll_layer, |
| 1554 outer_viewport_scroll_layer, overscroll_elasticity_layer, | 1519 outer_viewport_scroll_layer, overscroll_elasticity_layer, |
| 1555 elastic_overscroll, page_scale_factor, device_scale_factor, viewport, | 1520 elastic_overscroll, page_scale_factor, device_scale_factor, viewport, |
| 1556 device_transform, property_trees, color); | 1521 device_transform, property_trees, color); |
| 1557 property_trees->effect_tree.CreateOrReuseRenderSurfaces( | 1522 property_trees->effect_tree.CreateOrReuseRenderSurfaces( |
| 1558 &render_surfaces, root_layer->layer_tree_impl()); | 1523 &render_surfaces, root_layer->layer_tree_impl()); |
| 1559 property_trees->ResetCachedData(); | 1524 property_trees->ResetCachedData(); |
| 1560 } | 1525 } |
| 1561 | 1526 |
| 1562 } // namespace cc | 1527 } // namespace cc |
| OLD | NEW |