summaryrefslogtreecommitdiff
path: root/chromium/cc/trees/draw_property_utils.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/cc/trees/draw_property_utils.cc')
-rw-r--r--chromium/cc/trees/draw_property_utils.cc163
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 =