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/draw_property_utils.h" | 5 #include "cc/trees/draw_property_utils.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 Layer* layer) { | 371 Layer* layer) { |
| 372 UpdateRenderSurfaceForLayer(effect_tree, true, layer); | 372 UpdateRenderSurfaceForLayer(effect_tree, true, layer); |
| 373 | 373 |
| 374 for (size_t i = 0; i < layer->children().size(); ++i) { | 374 for (size_t i = 0; i < layer->children().size(); ++i) { |
| 375 UpdateRenderSurfacesForLayersRecursive(effect_tree, layer->child_at(i)); | 375 UpdateRenderSurfacesForLayersRecursive(effect_tree, layer->child_at(i)); |
| 376 } | 376 } |
| 377 } | 377 } |
| 378 | 378 |
| 379 } // namespace | 379 } // namespace |
| 380 | 380 |
| 381 static inline bool LayerShouldBeSkipped(Layer* layer, | 381 template <typename LayerType> |
| 382 bool layer_is_drawn, | 382 static inline bool LayerShouldBeSkippedInternal( |
| 383 const TransformTree& transform_tree, | 383 LayerType* layer, |
| 384 const EffectTree& effect_tree) { | 384 bool layer_is_drawn, |
| 385 const TransformTree& transform_tree, | |
| 386 const EffectTree& effect_tree) { | |
| 385 const TransformNode* transform_node = | 387 const TransformNode* transform_node = |
| 386 transform_tree.Node(layer->transform_tree_index()); | 388 transform_tree.Node(layer->transform_tree_index()); |
| 387 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); | 389 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); |
| 388 | 390 |
| 389 // If the layer transform is not invertible, it should not be drawn. | 391 // If the layer transform is not invertible, it should be skipped. |
| 390 if (!transform_node->data.node_and_ancestors_are_animated_or_invertible) | 392 // TODO(ajuma): Correctly process subtrees with singular transform for the |
| 391 return true; | 393 // case where we may animate to a non-singular transform and wish to |
| 392 | 394 // pre-raster. |
| 393 // When we need to do a readback/copy of a layer's output, we can not skip | 395 return !transform_node->data.node_and_ancestors_are_animated_or_invertible || |
| 394 // it or any of its ancestors. | 396 effect_node->data.hidden_by_backface_visibility || |
| 395 if (effect_node->data.num_copy_requests_in_subtree > 0) | 397 !effect_node->data.is_drawn; |
| 396 return false; | |
| 397 | |
| 398 // If the layer is not drawn, then skip it and its subtree. | |
| 399 if (!effect_node->data.is_drawn) | |
| 400 return true; | |
| 401 | |
| 402 if (!transform_node->data.to_screen_is_potentially_animated && | |
| 403 effect_node->data.hidden_by_backface_visibility) | |
| 404 return true; | |
| 405 | |
| 406 // If layer has a background filter, don't skip the layer, even it the | |
| 407 // opacity is 0. | |
| 408 if (effect_node->data.node_or_ancestor_has_background_filters) | |
| 409 return false; | |
| 410 | |
| 411 // If the opacity is being animated then the opacity on the main thread is | |
| 412 // unreliable (since the impl thread may be using a different opacity), so it | |
| 413 // should not be trusted. | |
| 414 // In particular, it should not cause the subtree to be skipped. | |
| 415 // Similarly, for layers that might animate opacity using an impl-only | |
| 416 // animation, their subtree should also not be skipped. | |
| 417 return !effect_node->data.screen_space_opacity && | |
| 418 !effect_node->data.to_screen_opacity_is_animated; | |
| 419 } | 398 } |
| 420 | 399 |
| 421 bool LayerShouldBeSkipped(LayerImpl* layer, | 400 bool LayerShouldBeSkipped(LayerImpl* layer, |
| 422 bool layer_is_drawn, | 401 bool layer_is_drawn, |
| 423 const TransformTree& transform_tree, | 402 const TransformTree& transform_tree, |
| 424 const EffectTree& effect_tree) { | 403 const EffectTree& effect_tree) { |
| 425 const TransformNode* transform_node = | 404 return LayerShouldBeSkippedInternal(layer, layer_is_drawn, transform_tree, |
| 426 transform_tree.Node(layer->transform_tree_index()); | 405 effect_tree); |
| 427 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); | 406 } |
| 428 // If the layer transform is not invertible, it should not be drawn. | |
| 429 // TODO(ajuma): Correctly process subtrees with singular transform for the | |
| 430 // case where we may animate to a non-singular transform and wish to | |
| 431 // pre-raster. | |
| 432 if (!transform_node->data.node_and_ancestors_are_animated_or_invertible) | |
| 433 return true; | |
| 434 | 407 |
| 435 // When we need to do a readback/copy of a layer's output, we can not skip | 408 bool LayerShouldBeSkipped(Layer* layer, |
| 436 // it or any of its ancestors. | 409 bool layer_is_drawn, |
| 437 if (effect_node->data.num_copy_requests_in_subtree > 0) | 410 const TransformTree& transform_tree, |
| 438 return false; | 411 const EffectTree& effect_tree) { |
| 439 | 412 return LayerShouldBeSkippedInternal(layer, layer_is_drawn, transform_tree, |
| 440 // If the layer is not drawn, then skip it and its subtree. | 413 effect_tree); |
| 441 if (!effect_node->data.is_drawn) | |
| 442 return true; | |
| 443 | |
| 444 if (effect_node->data.hidden_by_backface_visibility) | |
| 445 return true; | |
| 446 | |
| 447 // If layer is on the pending tree and opacity is being animated then | |
| 448 // this subtree can't be skipped as we need to create, prioritize and | |
| 449 // include tiles for this layer when deciding if tree can be activated. | |
| 450 if (!transform_tree.property_trees()->is_active && | |
| 451 effect_node->data.to_screen_opacity_is_animated) | |
| 452 return false; | |
| 453 | |
| 454 // If layer has a background filter, don't skip the layer, even it the | |
| 455 // opacity is 0. | |
| 456 if (effect_node->data.node_or_ancestor_has_background_filters) | |
| 457 return false; | |
| 458 | |
| 459 // The opacity of a layer always applies to its children (either implicitly | |
| 460 // via a render surface or explicitly if the parent preserves 3D), so the | |
| 461 // entire subtree can be skipped if this layer is fully transparent. | |
| 462 return !effect_node->data.screen_space_opacity; | |
| 463 } | 414 } |
| 464 | 415 |
| 465 void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, | 416 void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, |
| 466 const TransformTree& transform_tree, | 417 const TransformTree& transform_tree, |
| 467 const EffectTree& effect_tree, | 418 const EffectTree& effect_tree, |
| 468 LayerList* update_layer_list) { | 419 LayerList* update_layer_list) { |
| 469 LayerTreeHostCommon::CallFunctionForEveryLayer( | 420 LayerTreeHostCommon::CallFunctionForEveryLayer( |
| 470 layer_tree_host, | 421 layer_tree_host, |
| 471 [&](Layer* layer) { | 422 [&](Layer* layer) { |
| 472 bool layer_is_drawn = | 423 bool layer_is_drawn = |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 656 } else if (!can_render_to_separate_surface) { | 607 } else if (!can_render_to_separate_surface) { |
| 657 node->data.target_id = 1; | 608 node->data.target_id = 1; |
| 658 } else if (effect_tree->parent(node)->data.has_render_surface) { | 609 } else if (effect_tree->parent(node)->data.has_render_surface) { |
| 659 node->data.target_id = node->parent_id; | 610 node->data.target_id = node->parent_id; |
| 660 } else { | 611 } else { |
| 661 node->data.target_id = effect_tree->parent(node)->data.target_id; | 612 node->data.target_id = effect_tree->parent(node)->data.target_id; |
| 662 } | 613 } |
| 663 } | 614 } |
| 664 } | 615 } |
| 665 | 616 |
| 666 void ComputeEffects(EffectTree* effect_tree) { | 617 bool ComputeEffects(EffectTree* effect_tree) { |
| 667 if (!effect_tree->needs_update()) | 618 if (!effect_tree->needs_update()) |
| 668 return; | 619 return false; |
| 669 for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) | 620 bool has_transparent_node_with_animating_opacity = false; |
| 621 for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) { | |
| 670 effect_tree->UpdateEffects(i); | 622 effect_tree->UpdateEffects(i); |
| 623 EffectNode* node = effect_tree->Node(i); | |
| 624 has_transparent_node_with_animating_opacity = | |
| 625 !node->data.opacity && node->data.has_animated_opacity; | |
| 626 } | |
| 671 effect_tree->set_needs_update(false); | 627 effect_tree->set_needs_update(false); |
| 628 return has_transparent_node_with_animating_opacity; | |
| 672 } | 629 } |
| 673 | 630 |
| 674 static void ComputeVisibleRectsInternal( | 631 static void ComputeVisibleRectsInternal( |
| 675 LayerImpl* root_layer, | 632 LayerImpl* root_layer, |
| 676 PropertyTrees* property_trees, | 633 PropertyTrees* property_trees, |
| 677 bool can_render_to_separate_surface, | 634 bool can_render_to_separate_surface, |
| 678 LayerImplList* update_layer_list, | 635 LayerImplList* update_layer_list, |
| 679 std::vector<LayerImpl*>* visible_layer_list) { | 636 std::vector<LayerImpl*>* visible_layer_list) { |
| 680 if (property_trees->non_root_surfaces_enabled != | 637 if (property_trees->non_root_surfaces_enabled != |
| 681 can_render_to_separate_surface) { | 638 can_render_to_separate_surface) { |
| 682 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; | 639 property_trees->non_root_surfaces_enabled = can_render_to_separate_surface; |
| 683 property_trees->transform_tree.set_needs_update(true); | 640 property_trees->transform_tree.set_needs_update(true); |
| 684 } | 641 } |
| 685 if (property_trees->transform_tree.needs_update()) | 642 if (property_trees->transform_tree.needs_update()) |
| 686 property_trees->clip_tree.set_needs_update(true); | 643 property_trees->clip_tree.set_needs_update(true); |
| 687 UpdateRenderTarget(&property_trees->effect_tree, | 644 UpdateRenderTarget(&property_trees->effect_tree, |
| 688 property_trees->non_root_surfaces_enabled); | 645 property_trees->non_root_surfaces_enabled); |
| 689 ComputeTransforms(&property_trees->transform_tree); | 646 ComputeTransforms(&property_trees->transform_tree); |
| 690 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, | 647 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, |
| 691 can_render_to_separate_surface); | 648 can_render_to_separate_surface); |
| 692 ComputeEffects(&property_trees->effect_tree); | 649 bool needs_update_again_after_activation = |
| 650 ComputeEffects(&property_trees->effect_tree); | |
| 651 if (!property_trees->is_active) | |
| 652 property_trees->effect_tree.set_needs_update( | |
| 653 needs_update_again_after_activation); | |
|
ajuma
2016/04/13 19:53:06
This would also make us update every frame on the
jaydasika
2016/04/13 20:21:24
This function is called only on compositor thread.
ajuma
2016/04/13 20:34:18
Ah, ok. But then what about when trees are pushed
jaydasika
2016/04/13 20:53:07
Ah! I forgot that case. I think its better to do w
| |
| 693 | 654 |
| 694 FindLayersThatNeedUpdates( | 655 FindLayersThatNeedUpdates( |
| 695 root_layer->layer_tree_impl(), property_trees->transform_tree, | 656 root_layer->layer_tree_impl(), property_trees->transform_tree, |
| 696 property_trees->effect_tree, update_layer_list, visible_layer_list); | 657 property_trees->effect_tree, update_layer_list, visible_layer_list); |
| 697 CalculateVisibleRects<LayerImpl>( | 658 CalculateVisibleRects<LayerImpl>( |
| 698 *visible_layer_list, property_trees->clip_tree, | 659 *visible_layer_list, property_trees->clip_tree, |
| 699 property_trees->transform_tree, can_render_to_separate_surface); | 660 property_trees->transform_tree, can_render_to_separate_surface); |
| 700 } | 661 } |
| 701 | 662 |
| 702 void UpdateRenderSurfaces(Layer* root_layer, PropertyTrees* property_trees) { | 663 void UpdateRenderSurfaces(Layer* root_layer, PropertyTrees* property_trees) { |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1158 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1119 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
| 1159 const Layer* overscroll_elasticity_layer, | 1120 const Layer* overscroll_elasticity_layer, |
| 1160 const gfx::Vector2dF& elastic_overscroll) { | 1121 const gfx::Vector2dF& elastic_overscroll) { |
| 1161 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1122 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
| 1162 elastic_overscroll); | 1123 elastic_overscroll); |
| 1163 } | 1124 } |
| 1164 | 1125 |
| 1165 } // namespace draw_property_utils | 1126 } // namespace draw_property_utils |
| 1166 | 1127 |
| 1167 } // namespace cc | 1128 } // namespace cc |
| OLD | NEW |