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 |