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