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 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 = |
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->clip_tree.SetOwningLayerIdForNode( | 444 data_for_children->property_trees->clip_tree.SetOwningLayerIdForNode( |
462 data_for_children->property_trees->clip_tree.back(), layer->id()); | 445 data_for_children->property_trees->clip_tree.back(), layer->id()); |
463 } | 446 } |
464 | 447 |
465 layer->SetClipTreeIndex(data_for_children->clip_tree_parent); | 448 layer->SetClipTreeIndex(data_for_children->clip_tree_parent); |
466 } | 449 } |
467 | 450 |
468 static inline int SortingContextId(Layer* layer) { | |
469 return layer->sorting_context_id(); | |
470 } | |
471 | |
472 static inline int SortingContextId(LayerImpl* layer) { | |
473 return layer->test_properties()->sorting_context_id; | |
474 } | |
475 | |
476 static inline bool Is3dSorted(Layer* layer) { | |
477 return layer->Is3dSorted(); | |
478 } | |
479 | |
480 static inline bool Is3dSorted(LayerImpl* layer) { | |
481 return layer->test_properties()->sorting_context_id != 0; | |
482 } | |
483 | |
484 template <typename LayerType> | 451 template <typename LayerType> |
485 static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { | 452 static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { |
486 return Parent(layer) | 453 return Parent(layer) |
487 ? SortingContextId(Parent(layer)) != SortingContextId(layer) | 454 ? SortingContextId(Parent(layer)) != SortingContextId(layer) |
488 : Is3dSorted(layer); | 455 : Is3dSorted(layer); |
489 } | 456 } |
490 | 457 |
491 static inline gfx::Point3F TransformOrigin(Layer* layer) { | 458 static inline gfx::Point3F TransformOrigin(Layer* layer) { |
492 return layer->transform_origin(); | 459 return layer->transform_origin(); |
493 } | 460 } |
(...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1443 data_for_recursion.device_transform = &device_transform; | 1410 data_for_recursion.device_transform = &device_transform; |
1444 | 1411 |
1445 data_for_recursion.property_trees->clear(); | 1412 data_for_recursion.property_trees->clear(); |
1446 data_for_recursion.compound_transform_since_render_target = gfx::Transform(); | 1413 data_for_recursion.compound_transform_since_render_target = gfx::Transform(); |
1447 data_for_recursion.axis_align_since_render_target = true; | 1414 data_for_recursion.axis_align_since_render_target = true; |
1448 data_for_recursion.property_trees->transform_tree.set_device_scale_factor( | 1415 data_for_recursion.property_trees->transform_tree.set_device_scale_factor( |
1449 device_scale_factor); | 1416 device_scale_factor); |
1450 data_for_recursion.safe_opaque_background_color = color; | 1417 data_for_recursion.safe_opaque_background_color = color; |
1451 | 1418 |
1452 ClipNode root_clip; | 1419 ClipNode root_clip; |
1453 root_clip.resets_clip = true; | |
1454 root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; | 1420 root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; |
1455 root_clip.clip = gfx::RectF(viewport); | 1421 root_clip.clip = gfx::RectF(viewport); |
1456 root_clip.transform_id = TransformTree::kRootNodeId; | 1422 root_clip.transform_id = TransformTree::kRootNodeId; |
1457 root_clip.target_transform_id = TransformTree::kRootNodeId; | |
1458 data_for_recursion.clip_tree_parent = | 1423 data_for_recursion.clip_tree_parent = |
1459 data_for_recursion.property_trees->clip_tree.Insert( | 1424 data_for_recursion.property_trees->clip_tree.Insert( |
1460 root_clip, ClipTree::kRootNodeId); | 1425 root_clip, ClipTree::kRootNodeId); |
1461 | 1426 |
1462 DataForRecursionFromChild<LayerType> data_from_child; | 1427 DataForRecursionFromChild<LayerType> data_from_child; |
1463 BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child); | 1428 BuildPropertyTreesInternal(root_layer, data_for_recursion, &data_from_child); |
1464 property_trees->needs_rebuild = false; | 1429 property_trees->needs_rebuild = false; |
1465 | 1430 |
1466 // The transform tree is kept up to date as it is built, but the | 1431 // The transform tree is kept up to date as it is built, but the |
1467 // combined_clips stored in the clip tree and the screen_space_opacity and | 1432 // 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... |
1546 root_layer, page_scale_layer, inner_viewport_scroll_layer, | 1511 root_layer, page_scale_layer, inner_viewport_scroll_layer, |
1547 outer_viewport_scroll_layer, overscroll_elasticity_layer, | 1512 outer_viewport_scroll_layer, overscroll_elasticity_layer, |
1548 elastic_overscroll, page_scale_factor, device_scale_factor, viewport, | 1513 elastic_overscroll, page_scale_factor, device_scale_factor, viewport, |
1549 device_transform, property_trees, color); | 1514 device_transform, property_trees, color); |
1550 property_trees->effect_tree.CreateOrReuseRenderSurfaces( | 1515 property_trees->effect_tree.CreateOrReuseRenderSurfaces( |
1551 &render_surfaces, root_layer->layer_tree_impl()); | 1516 &render_surfaces, root_layer->layer_tree_impl()); |
1552 property_trees->ResetCachedData(); | 1517 property_trees->ResetCachedData(); |
1553 } | 1518 } |
1554 | 1519 |
1555 } // namespace cc | 1520 } // namespace cc |
OLD | NEW |