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

Unified Diff: cc/trees/draw_property_utils.cc

Issue 1884613005: cc : Simplify layer skipping logic (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 side-by-side diff with in-line comments
Download patch
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,

Powered by Google App Engine
This is Rietveld 408576698