Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: cc/trees/draw_property_utils.cc

Issue 1864183002: cc: Main thread skip single layers instead of subtrees (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix the dependency problem Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 const TransformTree& tree) { 307 const TransformTree& tree) {
308 return true; 308 return true;
309 } 309 }
310 310
311 template <typename LayerType> 311 template <typename LayerType>
312 static bool HasInvertibleOrAnimatedTransform(LayerType* layer) { 312 static bool HasInvertibleOrAnimatedTransform(LayerType* layer) {
313 return layer->transform_is_invertible() || 313 return layer->transform_is_invertible() ||
314 layer->HasPotentiallyRunningTransformAnimation(); 314 layer->HasPotentiallyRunningTransformAnimation();
315 } 315 }
316 316
317 static inline bool SubtreeShouldBeSkipped(Layer* layer,
318 bool layer_is_drawn,
319 const TransformTree& tree) {
320 // If the layer transform is not invertible, it should not be drawn.
321 if (!layer->transform_is_invertible() &&
322 !layer->HasPotentiallyRunningTransformAnimation())
323 return true;
324
325 // When we need to do a readback/copy of a layer's output, we can not skip
326 // it or any of its ancestors.
327 if (layer->num_copy_requests_in_target_subtree() > 0)
328 return false;
329
330 // If the layer is not drawn, then skip it and its subtree.
331 if (!layer_is_drawn)
332 return true;
333
334 if (layer->has_render_surface() && !layer->double_sided() &&
335 !layer->HasPotentiallyRunningTransformAnimation() &&
336 IsSurfaceBackFaceVisible(layer, tree))
337 return true;
338
339 // If layer has a background filter, don't skip the layer, even it the
340 // opacity is 0.
341 if (!layer->background_filters().IsEmpty())
342 return false;
343
344 // If the opacity is being animated then the opacity on the main thread is
345 // unreliable (since the impl thread may be using a different opacity), so it
346 // should not be trusted.
347 // In particular, it should not cause the subtree to be skipped.
348 // Similarly, for layers that might animate opacity using an impl-only
349 // animation, their subtree should also not be skipped.
350 return !layer->EffectiveOpacity() &&
351 !layer->HasPotentiallyRunningOpacityAnimation() &&
352 !layer->OpacityCanAnimateOnImplThread();
353 }
354
355 template <typename LayerType> 317 template <typename LayerType>
356 static bool LayerNeedsUpdateInternal(LayerType* layer, 318 static bool LayerNeedsUpdateInternal(LayerType* layer,
357 bool layer_is_drawn, 319 bool layer_is_drawn,
358 const TransformTree& tree) { 320 const TransformTree& tree) {
359 // Layers can be skipped if any of these conditions are met. 321 // Layers can be skipped if any of these conditions are met.
360 // - is not drawn due to it or one of its ancestors being hidden (or having 322 // - is not drawn due to it or one of its ancestors being hidden (or having
361 // no copy requests). 323 // no copy requests).
362 // - does not draw content. 324 // - does not draw content.
363 // - is transparent. 325 // - is transparent.
364 // - has empty bounds 326 // - has empty bounds
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 Layer* layer) { 404 Layer* layer) {
443 UpdateRenderSurfaceForLayer(effect_tree, true, layer); 405 UpdateRenderSurfaceForLayer(effect_tree, true, layer);
444 406
445 for (size_t i = 0; i < layer->children().size(); ++i) { 407 for (size_t i = 0; i < layer->children().size(); ++i) {
446 UpdateRenderSurfacesForLayersRecursive(effect_tree, layer->child_at(i)); 408 UpdateRenderSurfacesForLayersRecursive(effect_tree, layer->child_at(i));
447 } 409 }
448 } 410 }
449 411
450 } // namespace 412 } // namespace
451 413
414 static inline bool LayerShouldBeSkipped(Layer* layer,
415 bool layer_is_drawn,
416 const TransformTree& transform_tree) {
417 const TransformNode* transform_node =
418 transform_tree.Node(layer->transform_tree_index());
419 const EffectTree& effect_tree = transform_tree.property_trees()->effect_tree;
Ian Vollick 2016/04/06 19:42:26 nit: I'd just pass this in since you have it handy
sunxd 2016/04/07 15:37:13 Done.
420 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index());
421
422 // If the layer transform is not invertible, it should not be drawn.
423 bool has_inherited_invertible_or_animated_transform =
424 (transform_node->data.is_invertible &&
425 transform_node->data.ancestors_are_invertible) ||
426 transform_node->data.to_screen_is_animated;
Ian Vollick 2016/04/06 19:42:26 This isn't worth doing anything about in this CL,
sunxd 2016/04/07 15:37:13 I think so. When updating animation properties, to
427 if (!has_inherited_invertible_or_animated_transform)
428 return true;
429
430 // When we need to do a readback/copy of a layer's output, we can not skip
431 // it or any of its ancestors.
432 if (effect_node->data.num_copy_requests_in_subtree > 0)
433 return false;
434
435 // If the layer is not drawn, then skip it and its subtree.
436 if (!effect_node->data.is_drawn)
437 return true;
438
439 if (!transform_node->data.to_screen_is_animated &&
440 effect_node->data.hidden_by_backface_visibility)
441 return true;
442
443 // If layer has a background filter, don't skip the layer, even it the
444 // opacity is 0.
445 if (effect_node->data.node_or_ancestor_has_background_filters)
446 return false;
447
448 // If the opacity is being animated then the opacity on the main thread is
449 // unreliable (since the impl thread may be using a different opacity), so it
450 // should not be trusted.
451 // In particular, it should not cause the subtree to be skipped.
452 // Similarly, for layers that might animate opacity using an impl-only
453 // animation, their subtree should also not be skipped.
454 return !effect_node->data.screen_space_opacity &&
455 !effect_node->data.to_screen_opacity_is_animated &&
456 !effect_node->data.to_screen_opacity_can_animate_on_impl;
sunxd 2016/04/06 18:48:48 I'm also considering merging the logic of main/imp
Ian Vollick 2016/04/06 19:42:26 It would be fantastic if you could do this. This s
sunxd 2016/04/07 15:37:12 Yes, jaydasika@ is going to work on simplifying th
Ian Vollick 2016/04/07 17:20:25 kk. makes sense.
457 }
458
459 bool LayerShouldBeSkipped(LayerImpl* layer,
460 bool layer_is_drawn,
461 const TransformTree& transform_tree) {
462 const TransformNode* transform_node =
463 transform_tree.Node(layer->transform_tree_index());
464 const EffectTree& effect_tree = transform_tree.property_trees()->effect_tree;
465 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index());
466 // If the layer transform is not invertible, it should not be drawn.
467 // TODO(ajuma): Correctly process subtrees with singular transform for the
468 // case where we may animate to a non-singular transform and wish to
469 // pre-raster.
470 bool has_inherited_invertible_or_animated_transform =
471 (transform_node->data.is_invertible &&
472 transform_node->data.ancestors_are_invertible) ||
473 transform_node->data.to_screen_is_animated;
474 if (!has_inherited_invertible_or_animated_transform)
475 return true;
476
477 // When we need to do a readback/copy of a layer's output, we can not skip
478 // it or any of its ancestors.
479 if (effect_node->data.num_copy_requests_in_subtree > 0)
480 return false;
481
482 // If the layer is not drawn, then skip it and its subtree.
483 if (!effect_node->data.is_drawn)
484 return true;
485
486 if (effect_node->data.hidden_by_backface_visibility)
487 return true;
488
489 // If layer is on the pending tree and opacity is being animated then
490 // this subtree can't be skipped as we need to create, prioritize and
491 // include tiles for this layer when deciding if tree can be activated.
492 if (!transform_tree.property_trees()->is_active &&
493 effect_node->data.to_screen_opacity_is_animated)
494 return false;
495
496 // If layer has a background filter, don't skip the layer, even it the
497 // opacity is 0.
498 if (effect_node->data.node_or_ancestor_has_background_filters)
499 return false;
500
501 // The opacity of a layer always applies to its children (either implicitly
502 // via a render surface or explicitly if the parent preserves 3D), so the
503 // entire subtree can be skipped if this layer is fully transparent.
504 return !effect_node->data.screen_space_opacity;
505 }
506
507 void FindLayersThatNeedUpdates(Layer* root_layer,
508 const TransformTree& transform_tree,
509 const EffectTree& effect_tree,
510 LayerList* update_layer_list) {
511 DCHECK_GE(root_layer->effect_tree_index(), 0);
512 LayerTreeHostCommon::CallFunctionForEveryLayer(
513 root_layer->layer_tree_host(),
sunxd 2016/04/06 18:48:48 I'm also considering merging the logic of main/imp
514 [&](Layer* layer) {
515 bool layer_is_drawn =
516 effect_tree.Node(layer->effect_tree_index())->data.is_drawn;
517
518 if (!IsRootLayer(layer) &&
519 LayerShouldBeSkipped(layer, layer_is_drawn, transform_tree))
520 return;
521
522 if (LayerNeedsUpdate(layer, layer_is_drawn, transform_tree)) {
523 update_layer_list->push_back(layer);
524 }
525
526 // Append mask layers to the update layer list. They don't have valid
527 // visible
528 // rects, so need to get added after the above calculation. Replica
529 // layers
530 // don't need to be updated.
Ian Vollick 2016/04/06 19:42:26 nit: wrapping issues.
sunxd 2016/04/07 15:37:13 Done.
ajuma 2016/04/07 18:46:47 The wrapping of the comment still needs fixing.
531 if (Layer* mask_layer = layer->mask_layer()) {
532 update_layer_list->push_back(mask_layer);
533 }
534 if (Layer* replica_layer = layer->replica_layer()) {
535 if (Layer* mask_layer = replica_layer->mask_layer()) {
536 update_layer_list->push_back(mask_layer);
537 }
538 }
539 },
540 CallFunctionLayerType::BASIC_LAYER);
541 }
542
452 static void ResetIfHasNanCoordinate(gfx::RectF* rect) { 543 static void ResetIfHasNanCoordinate(gfx::RectF* rect) {
453 if (std::isnan(rect->x()) || std::isnan(rect->y()) || 544 if (std::isnan(rect->x()) || std::isnan(rect->y()) ||
454 std::isnan(rect->right()) || std::isnan(rect->bottom())) 545 std::isnan(rect->right()) || std::isnan(rect->bottom()))
455 *rect = gfx::RectF(); 546 *rect = gfx::RectF();
456 } 547 }
457 548
458 void ComputeClips(ClipTree* clip_tree, 549 void ComputeClips(ClipTree* clip_tree,
459 const TransformTree& transform_tree, 550 const TransformTree& transform_tree,
460 bool non_root_surfaces_enabled) { 551 bool non_root_surfaces_enabled) {
461 if (!clip_tree->needs_update()) 552 if (!clip_tree->needs_update())
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 property_trees->transform_tree.set_needs_update(true); 742 property_trees->transform_tree.set_needs_update(true);
652 } 743 }
653 if (property_trees->transform_tree.needs_update()) 744 if (property_trees->transform_tree.needs_update())
654 property_trees->clip_tree.set_needs_update(true); 745 property_trees->clip_tree.set_needs_update(true);
655 ComputeTransforms(&property_trees->transform_tree); 746 ComputeTransforms(&property_trees->transform_tree);
656 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, 747 ComputeClips(&property_trees->clip_tree, property_trees->transform_tree,
657 can_render_to_separate_surface); 748 can_render_to_separate_surface);
658 ComputeEffects(&property_trees->effect_tree); 749 ComputeEffects(&property_trees->effect_tree);
659 } 750 }
660 751
661 void FindLayersThatNeedUpdates(Layer* layer,
662 const TransformTree& transform_tree,
663 const EffectTree& effect_tree,
664 LayerList* update_layer_list) {
665 DCHECK_GE(layer->effect_tree_index(), 0);
666 bool layer_is_drawn =
667 effect_tree.Node(layer->effect_tree_index())->data.is_drawn;
668
669 if (!IsRootLayer(layer) &&
670 SubtreeShouldBeSkipped(layer, layer_is_drawn, transform_tree))
671 return;
672
673 if (LayerNeedsUpdate(layer, layer_is_drawn, transform_tree))
674 update_layer_list->push_back(layer);
675 if (Layer* mask_layer = layer->mask_layer())
676 update_layer_list->push_back(mask_layer);
677 if (Layer* replica_layer = layer->replica_layer()) {
678 if (Layer* mask_layer = replica_layer->mask_layer())
679 update_layer_list->push_back(mask_layer);
680 }
681
682 for (size_t i = 0; i < layer->children().size(); ++i) {
683 FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree,
684 update_layer_list);
685 }
686 }
687
688 void ComputeVisibleRectsForTesting(PropertyTrees* property_trees, 752 void ComputeVisibleRectsForTesting(PropertyTrees* property_trees,
689 bool can_render_to_separate_surface, 753 bool can_render_to_separate_surface,
690 LayerList* update_layer_list) { 754 LayerList* update_layer_list) {
691 CalculateVisibleRects<Layer>(*update_layer_list, property_trees->clip_tree, 755 CalculateVisibleRects<Layer>(*update_layer_list, property_trees->clip_tree,
692 property_trees->transform_tree, 756 property_trees->transform_tree,
693 can_render_to_separate_surface); 757 can_render_to_separate_surface);
694 } 758 }
695 759
696 void BuildPropertyTreesAndComputeVisibleRects( 760 void BuildPropertyTreesAndComputeVisibleRects(
697 LayerImpl* root_layer, 761 LayerImpl* root_layer,
(...skipping 29 matching lines...) Expand all
727 if (can_render_to_separate_surface) 791 if (can_render_to_separate_surface)
728 ValidateRenderSurfaceForLayer(layer); 792 ValidateRenderSurfaceForLayer(layer);
729 #endif 793 #endif
730 } 794 }
731 LayerImplList update_layer_list; 795 LayerImplList update_layer_list;
732 ComputeVisibleRectsInternal(root_layer, property_trees, 796 ComputeVisibleRectsInternal(root_layer, property_trees,
733 can_render_to_separate_surface, 797 can_render_to_separate_surface,
734 &update_layer_list, visible_layer_list); 798 &update_layer_list, visible_layer_list);
735 } 799 }
736 800
737 bool LayerShouldBeSkipped(LayerImpl* layer,
738 bool layer_is_drawn,
739 const TransformTree& transform_tree) {
740 const TransformNode* transform_node =
741 transform_tree.Node(layer->transform_tree_index());
742 const EffectTree& effect_tree = transform_tree.property_trees()->effect_tree;
743 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index());
744 // If the layer transform is not invertible, it should not be drawn.
745 // TODO(ajuma): Correctly process subtrees with singular transform for the
746 // case where we may animate to a non-singular transform and wish to
747 // pre-raster.
748 bool has_inherited_invertible_or_animated_transform =
749 (transform_node->data.is_invertible &&
750 transform_node->data.ancestors_are_invertible) ||
751 transform_node->data.to_screen_is_animated;
752 if (!has_inherited_invertible_or_animated_transform)
753 return true;
754
755 // When we need to do a readback/copy of a layer's output, we can not skip
756 // it or any of its ancestors.
757 if (effect_node->data.num_copy_requests_in_subtree > 0)
758 return false;
759
760 // If the layer is not drawn, then skip it and its subtree.
761 if (!effect_node->data.is_drawn)
762 return true;
763
764 if (effect_node->data.hidden_by_backface_visibility)
765 return true;
766
767 // If layer is on the pending tree and opacity is being animated then
768 // this subtree can't be skipped as we need to create, prioritize and
769 // include tiles for this layer when deciding if tree can be activated.
770 if (!transform_tree.property_trees()->is_active &&
771 effect_node->data.to_screen_opacity_is_animated)
772 return false;
773
774 // If layer has a background filter, don't skip the layer, even it the
775 // opacity is 0.
776 if (effect_node->data.node_or_ancestor_has_background_filters)
777 return false;
778
779 // The opacity of a layer always applies to its children (either implicitly
780 // via a render surface or explicitly if the parent preserves 3D), so the
781 // entire subtree can be skipped if this layer is fully transparent.
782 return !effect_node->data.screen_space_opacity;
783 }
784
785 bool LayerNeedsUpdate(Layer* layer, 801 bool LayerNeedsUpdate(Layer* layer,
786 bool layer_is_drawn, 802 bool layer_is_drawn,
787 const TransformTree& tree) { 803 const TransformTree& tree) {
788 return LayerNeedsUpdateInternal(layer, layer_is_drawn, tree); 804 return LayerNeedsUpdateInternal(layer, layer_is_drawn, tree);
789 } 805 }
790 806
791 bool LayerNeedsUpdate(LayerImpl* layer, 807 bool LayerNeedsUpdate(LayerImpl* layer,
792 bool layer_is_drawn, 808 bool layer_is_drawn,
793 const TransformTree& tree) { 809 const TransformTree& tree) {
794 return LayerNeedsUpdateInternal(layer, layer_is_drawn, tree); 810 return LayerNeedsUpdateInternal(layer, layer_is_drawn, tree);
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 void UpdateElasticOverscroll(PropertyTrees* property_trees, 1181 void UpdateElasticOverscroll(PropertyTrees* property_trees,
1166 const Layer* overscroll_elasticity_layer, 1182 const Layer* overscroll_elasticity_layer,
1167 const gfx::Vector2dF& elastic_overscroll) { 1183 const gfx::Vector2dF& elastic_overscroll) {
1168 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, 1184 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer,
1169 elastic_overscroll); 1185 elastic_overscroll);
1170 } 1186 }
1171 1187
1172 } // namespace draw_property_utils 1188 } // namespace draw_property_utils
1173 1189
1174 } // namespace cc 1190 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698