Chromium Code Reviews| Index: cc/trees/draw_property_utils.cc |
| diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc |
| index 27ef742570cf0370b73c3065465b1c4e44630450..80bf3d1f5251f280aa512119b0b7cdca04e9bd38 100644 |
| --- a/cc/trees/draw_property_utils.cc |
| +++ b/cc/trees/draw_property_utils.cc |
| @@ -378,88 +378,39 @@ void UpdateRenderSurfacesForLayersRecursive(EffectTree* effect_tree, |
| } // namespace |
| -static inline bool LayerShouldBeSkipped(Layer* layer, |
| - bool layer_is_drawn, |
| - const TransformTree& transform_tree, |
| - const EffectTree& effect_tree) { |
| +template <typename LayerType> |
| +static inline bool LayerShouldBeSkippedInternal( |
| + LayerType* layer, |
| + bool layer_is_drawn, |
| + const TransformTree& transform_tree, |
| + const EffectTree& effect_tree) { |
| const TransformNode* transform_node = |
| transform_tree.Node(layer->transform_tree_index()); |
| const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); |
| - // If the layer transform is not invertible, it should not be drawn. |
| - if (!transform_node->data.node_and_ancestors_are_animated_or_invertible) |
| - return true; |
| - |
| - // When we need to do a readback/copy of a layer's output, we can not skip |
| - // it or any of its ancestors. |
| - if (effect_node->data.num_copy_requests_in_subtree > 0) |
| - return false; |
| - |
| - // If the layer is not drawn, then skip it and its subtree. |
| - if (!effect_node->data.is_drawn) |
| - return true; |
| - |
| - if (!transform_node->data.to_screen_is_potentially_animated && |
| - effect_node->data.hidden_by_backface_visibility) |
| - return true; |
| - |
| - // If layer has a background filter, don't skip the layer, even it the |
| - // opacity is 0. |
| - if (effect_node->data.node_or_ancestor_has_background_filters) |
| - return false; |
| - |
| - // If the opacity is being animated then the opacity on the main thread is |
| - // unreliable (since the impl thread may be using a different opacity), so it |
| - // should not be trusted. |
| - // In particular, it should not cause the subtree to be skipped. |
| - // Similarly, for layers that might animate opacity using an impl-only |
| - // animation, their subtree should also not be skipped. |
| - return !effect_node->data.screen_space_opacity && |
| - !effect_node->data.to_screen_opacity_is_animated; |
| + // If the layer transform is not invertible, it should be skipped. |
| + // TODO(ajuma): Correctly process subtrees with singular transform for the |
| + // case where we may animate to a non-singular transform and wish to |
| + // pre-raster. |
| + return !transform_node->data.node_and_ancestors_are_animated_or_invertible || |
| + effect_node->data.hidden_by_backface_visibility || |
| + !effect_node->data.is_drawn; |
| } |
| bool LayerShouldBeSkipped(LayerImpl* layer, |
| bool layer_is_drawn, |
| const TransformTree& transform_tree, |
| const EffectTree& effect_tree) { |
| - const TransformNode* transform_node = |
| - transform_tree.Node(layer->transform_tree_index()); |
| - const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); |
| - // If the layer transform is not invertible, it should not be drawn. |
| - // TODO(ajuma): Correctly process subtrees with singular transform for the |
| - // case where we may animate to a non-singular transform and wish to |
| - // pre-raster. |
| - if (!transform_node->data.node_and_ancestors_are_animated_or_invertible) |
| - return true; |
| - |
| - // When we need to do a readback/copy of a layer's output, we can not skip |
| - // it or any of its ancestors. |
| - if (effect_node->data.num_copy_requests_in_subtree > 0) |
| - return false; |
| - |
| - // If the layer is not drawn, then skip it and its subtree. |
| - if (!effect_node->data.is_drawn) |
| - return true; |
| - |
| - if (effect_node->data.hidden_by_backface_visibility) |
| - return true; |
| - |
| - // If layer is on the pending tree and opacity is being animated then |
| - // this subtree can't be skipped as we need to create, prioritize and |
| - // include tiles for this layer when deciding if tree can be activated. |
| - if (!transform_tree.property_trees()->is_active && |
| - effect_node->data.to_screen_opacity_is_animated) |
| - return false; |
| - |
| - // If layer has a background filter, don't skip the layer, even it the |
| - // opacity is 0. |
| - if (effect_node->data.node_or_ancestor_has_background_filters) |
| - return false; |
| + return LayerShouldBeSkippedInternal(layer, layer_is_drawn, transform_tree, |
| + effect_tree); |
| +} |
| - // The opacity of a layer always applies to its children (either implicitly |
| - // via a render surface or explicitly if the parent preserves 3D), so the |
| - // entire subtree can be skipped if this layer is fully transparent. |
| - return !effect_node->data.screen_space_opacity; |
| +bool LayerShouldBeSkipped(Layer* layer, |
| + bool layer_is_drawn, |
| + const TransformTree& transform_tree, |
| + const EffectTree& effect_tree) { |
| + return LayerShouldBeSkippedInternal(layer, layer_is_drawn, transform_tree, |
| + effect_tree); |
| } |
| void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, |
| @@ -663,12 +614,18 @@ void UpdateRenderTarget(EffectTree* effect_tree, |
| } |
| } |
| -void ComputeEffects(EffectTree* effect_tree) { |
| +bool ComputeEffects(EffectTree* effect_tree) { |
| if (!effect_tree->needs_update()) |
| - return; |
| - for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) |
| + return false; |
| + bool has_transparent_node_with_animating_opacity = false; |
| + for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) { |
| effect_tree->UpdateEffects(i); |
| + EffectNode* node = effect_tree->Node(i); |
| + has_transparent_node_with_animating_opacity = |
| + !node->data.opacity && node->data.has_animated_opacity; |
| + } |
| effect_tree->set_needs_update(false); |
| + return has_transparent_node_with_animating_opacity; |
| } |
| static void ComputeVisibleRectsInternal( |
| @@ -689,7 +646,11 @@ static void ComputeVisibleRectsInternal( |
| ComputeTransforms(&property_trees->transform_tree); |
| ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, |
| can_render_to_separate_surface); |
| - ComputeEffects(&property_trees->effect_tree); |
| + bool needs_update_again_after_activation = |
| + ComputeEffects(&property_trees->effect_tree); |
| + if (!property_trees->is_active) |
| + property_trees->effect_tree.set_needs_update( |
| + 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
|
| FindLayersThatNeedUpdates( |
| root_layer->layer_tree_impl(), property_trees->transform_tree, |