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 |