diff options
Diffstat (limited to 'chromium/cc/trees/draw_property_utils.cc')
-rw-r--r-- | chromium/cc/trees/draw_property_utils.cc | 163 |
1 files changed, 117 insertions, 46 deletions
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc index f9fdebf8218..7c65e513700 100644 --- a/chromium/cc/trees/draw_property_utils.cc +++ b/chromium/cc/trees/draw_property_utils.cc @@ -11,6 +11,7 @@ #include "base/containers/adapters.h" #include "base/containers/stack.h" +#include "base/logging.h" #include "cc/base/math_util.h" #include "cc/layers/draw_properties.h" #include "cc/layers/layer.h" @@ -381,6 +382,12 @@ bool IsTargetSpaceTransformBackFaceVisible( LayerImpl* layer, int transform_tree_index, const PropertyTrees* property_trees) { + const TransformTree& transform_tree = property_trees->transform_tree; + const TransformNode& transform_node = + *transform_tree.Node(transform_tree_index); + if (transform_node.delegates_to_parent_for_backface) + transform_tree_index = transform_node.parent_id; + gfx::Transform to_target; property_trees->GetToTarget(transform_tree_index, layer->render_target_effect_tree_index(), @@ -388,12 +395,42 @@ bool IsTargetSpaceTransformBackFaceVisible( return to_target.IsBackFaceVisible(); } -template <typename LayerType> -bool IsLayerBackFaceVisible(LayerType* layer, - int transform_tree_index, - const PropertyTrees* property_trees) { - return IsTargetSpaceTransformBackFaceVisible(layer, transform_tree_index, - property_trees); +bool IsTransformToRootOf3DRenderingContextBackFaceVisible( + Layer* layer, + int transform_tree_index, + const PropertyTrees* property_trees) { + // We do not skip back face invisible layers on main thread as target space + // transform will not be available here. + return false; +} + +bool IsTransformToRootOf3DRenderingContextBackFaceVisible( + LayerImpl* layer, + int transform_tree_index, + const PropertyTrees* property_trees) { + const TransformTree& transform_tree = property_trees->transform_tree; + + const TransformNode& transform_node = + *transform_tree.Node(transform_tree_index); + if (transform_node.delegates_to_parent_for_backface) + transform_tree_index = transform_node.parent_id; + + int root_id = transform_tree_index; + int sorting_context_id = transform_node.sorting_context_id; + + while (root_id > 0 && transform_tree.Node(root_id - 1)->sorting_context_id == + sorting_context_id) + root_id--; + + // TODO(chrishtr): cache this on the transform trees if needed, similar to + // |to_target| and |to_screen|. + gfx::Transform to_3d_root; + if (transform_tree_index != root_id) + property_trees->transform_tree.CombineTransformsBetween( + transform_tree_index, root_id, &to_3d_root); + to_3d_root.PreconcatTransform( + property_trees->transform_tree.Node(root_id)->to_parent); + return to_3d_root.IsBackFaceVisible(); } inline bool TransformToScreenIsKnown(Layer* layer, @@ -445,7 +482,8 @@ bool LayerNeedsUpdate(LayerType* layer, // backface is not visible. if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && !HasSingularTransform(backface_transform_id, tree) && - IsLayerBackFaceVisible(layer, backface_transform_id, property_trees)) { + draw_property_utils::IsLayerBackFaceVisible( + layer, backface_transform_id, property_trees)) { UMA_HISTOGRAM_BOOLEAN( "Compositing.Renderer.LayerUpdateSkippedDueToBackface", true); return false; @@ -474,35 +512,6 @@ inline bool LayerShouldBeSkippedForDrawPropertiesComputation( !effect_node->is_drawn; } -inline bool LayerShouldBeSkippedForDrawPropertiesComputation( - LayerImpl* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree) { - const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); - - if (effect_node->HasRenderSurface() && effect_node->subtree_has_copy_request) - return false; - - // Skip if the node's subtree is hidden and no need to cache. - if (effect_node->subtree_hidden && !effect_node->cache_render_surface) - return true; - - // If the layer transform is not invertible, it should be skipped. In case the - // transform is animating and singular, we should not skip it. - const TransformNode* transform_node = - transform_tree.Node(layer->transform_tree_index()); - - if (!transform_node->node_and_ancestors_are_animated_or_invertible || - !effect_node->is_drawn) - return true; - - UMA_HISTOGRAM_BOOLEAN( - "Compositing.Renderer.LayerSkippedForDrawPropertiesDueToBackface", - effect_node->hidden_by_backface_visibility); - - return effect_node->hidden_by_backface_visibility; -} - gfx::Rect LayerDrawableContentRect( const LayerImpl* layer, const gfx::Rect& layer_bounds_in_target_space, @@ -922,8 +931,8 @@ void ComputeInitialRenderSurfaceList(LayerTreeImpl* layer_tree_impl, bool is_root = layer_tree_impl->IsRootLayer(layer); bool skip_draw_properties_computation = - LayerShouldBeSkippedForDrawPropertiesComputation( - layer, property_trees->transform_tree, property_trees->effect_tree); + draw_property_utils::LayerShouldBeSkippedForDrawPropertiesComputation( + layer, property_trees); bool skip_for_invertibility = SkipForInvertibility(layer, property_trees); @@ -1138,11 +1147,19 @@ void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, // Compute drawable content rects for (LayerImpl* layer : *layer_list) { - gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( - layer->draw_properties().target_space_transform, - gfx::Rect(layer->bounds())); - layer->draw_properties().drawable_content_rect = LayerDrawableContentRect( - layer, bounds_in_target_space, layer->draw_properties().clip_rect); + bool only_draws_visible_content = + property_trees->effect_tree.Node(layer->effect_tree_index()) + ->only_draws_visible_content; + gfx::Rect drawable_bounds = gfx::Rect(layer->visible_layer_rect()); + if (!only_draws_visible_content) { + drawable_bounds = gfx::Rect(layer->bounds()); + } + gfx::Rect visible_bounds_in_target_space = + MathUtil::MapEnclosingClippedRect( + layer->draw_properties().target_space_transform, drawable_bounds); + layer->draw_properties().visible_drawable_content_rect = + LayerDrawableContentRect(layer, visible_bounds_in_target_space, + layer->draw_properties().clip_rect); } } @@ -1164,6 +1181,61 @@ bool NodeMayContainBackdropBlurFilter(const EffectNode& node) { } // namespace +bool CC_EXPORT LayerShouldBeSkippedForDrawPropertiesComputation( + LayerImpl* layer, + const PropertyTrees* property_trees) { + const TransformTree& transform_tree = property_trees->transform_tree; + const EffectTree& effect_tree = property_trees->effect_tree; + const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); + + if (effect_node->HasRenderSurface() && effect_node->subtree_has_copy_request) + return false; + + // Skip if the node's subtree is hidden and no need to cache. + if (effect_node->subtree_hidden && !effect_node->cache_render_surface) + return true; + + // If the layer transform is not invertible, it should be skipped. In case the + // transform is animating and singular, we should not skip it. + const TransformNode* transform_node = + transform_tree.Node(layer->transform_tree_index()); + + if (!transform_node->node_and_ancestors_are_animated_or_invertible || + !effect_node->is_drawn) + return true; + if (layer->layer_tree_impl()->settings().enable_transform_interop) { + return layer->should_check_backface_visibility() && + IsLayerBackFaceVisible(layer, layer->transform_tree_index(), + property_trees); + } else { + return effect_node->hidden_by_backface_visibility; + } +} + +bool CC_EXPORT IsLayerBackFaceVisible(LayerImpl* layer, + int transform_tree_index, + const PropertyTrees* property_trees) { + if (layer->layer_tree_impl()->settings().enable_transform_interop) { + return IsTransformToRootOf3DRenderingContextBackFaceVisible( + layer, transform_tree_index, property_trees); + } else { + return IsTargetSpaceTransformBackFaceVisible(layer, transform_tree_index, + property_trees); + } +} + +bool CC_EXPORT IsLayerBackFaceVisible(Layer* layer, + int transform_tree_index, + const PropertyTrees* property_trees) { + if (layer->layer_tree_host()->GetSettings().enable_transform_interop) { + return IsTransformToRootOf3DRenderingContextBackFaceVisible( + layer, transform_tree_index, property_trees); + } else { + return IsTargetSpaceTransformBackFaceVisible(layer, transform_tree_index, + property_trees); + } +} + void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, gfx::Transform* transform) { DCHECK(effect_node->HasRenderSurface()); @@ -1195,7 +1267,6 @@ void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, std::vector<LayerImpl*>* visible_layer_list) { const PropertyTrees* property_trees = layer_tree_impl->property_trees(); - const TransformTree& transform_tree = property_trees->transform_tree; const EffectTree& effect_tree = property_trees->effect_tree; for (auto* layer_impl : *layer_tree_impl) { @@ -1204,8 +1275,8 @@ void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, layer_impl->EnsureValidPropertyTreeIndices(); if (!IsRootLayer(layer_impl) && - LayerShouldBeSkippedForDrawPropertiesComputation( - layer_impl, transform_tree, effect_tree)) + LayerShouldBeSkippedForDrawPropertiesComputation(layer_impl, + property_trees)) continue; bool layer_is_drawn = |