summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjaydasika <jaydasika@chromium.org>2016-01-28 12:18:33 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-28 20:19:33 +0000
commite00c8a4bf6e38da254c9624602b2a74e45853103 (patch)
tree88b1d74e21508dd49cefbe0021b29e41172856cf
parent21a110d3e3c2367300904f9337da966f6f531b59 (diff)
downloadchromium_src-e00c8a4bf6e38da254c9624602b2a74e45853103.zip
chromium_src-e00c8a4bf6e38da254c9624602b2a74e45853103.tar.gz
chromium_src-e00c8a4bf6e38da254c9624602b2a74e45853103.tar.bz2
cc:: Add transform nodes at boundaries of 3d rendering contexts
We then store the sorting context id in transform nodes and use it to determine layer and surface backface visibility. This patch also fixes a bug in backface visibility computation when we have nested 3d rendering contexts. BUG=568746,581570 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1624693004 Cr-Commit-Position: refs/heads/master@{#372150}
-rw-r--r--cc/proto/property_tree.proto1
-rw-r--r--cc/trees/draw_property_utils.cc47
-rw-r--r--cc/trees/layer_tree_host_common_unittest.cc45
-rw-r--r--cc/trees/property_tree.cc4
-rw-r--r--cc/trees/property_tree.h5
-rw-r--r--cc/trees/property_tree_builder.cc9
6 files changed, 75 insertions, 36 deletions
diff --git a/cc/proto/property_tree.proto b/cc/proto/property_tree.proto
index d7d74b2..f70c8bd 100644
--- a/cc/proto/property_tree.proto
+++ b/cc/proto/property_tree.proto
@@ -58,6 +58,7 @@ message TranformNodeData {
optional Vector2dF scroll_snap = 36;
optional Vector2dF source_offset = 37;
optional Vector2dF source_to_parent = 38;
+ optional int64 sorting_context_id = 39;
}
// Proto for struct ClipNodeData.
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 6899816..de3505c 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -204,20 +204,6 @@ void CalculateVisibleRects(const std::vector<LayerType*>& visible_layer_list,
}
template <typename LayerType>
-static bool IsRootLayerOfNewRenderingContext(LayerType* layer) {
- if (layer->parent())
- return !layer->parent()->Is3dSorted() && layer->Is3dSorted();
- return layer->Is3dSorted();
-}
-
-template <typename LayerType>
-static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) {
- return layer->Is3dSorted() && layer->parent() &&
- layer->parent()->Is3dSorted() &&
- layer->parent()->sorting_context_id() == layer->sorting_context_id();
-}
-
-template <typename LayerType>
static bool TransformToScreenIsKnown(LayerType* layer,
const TransformTree& tree) {
const TransformNode* node = tree.Node(layer->transform_tree_index());
@@ -242,8 +228,17 @@ static bool IsLayerBackFaceVisible(LayerType* layer,
// rendering context" or not. For Chromium code, we can determine whether we
// are in a 3d rendering context by checking if the parent preserves 3d.
- if (LayerIsInExisting3DRenderingContext(layer))
+ const TransformNode* node = tree.Node(layer->transform_tree_index());
+ const TransformNode* parent_node = tree.parent(node);
+ const bool is_3d_sorted = (node->data.sorting_context_id != 0);
+ const bool no_transfrom_node_created = (layer->id() != node->owner_id);
+ const bool parent_also_in_same_rendering_context =
+ parent_node &&
+ parent_node->data.sorting_context_id == node->data.sorting_context_id;
+ if (is_3d_sorted &&
+ (no_transfrom_node_created || parent_also_in_same_rendering_context)) {
return DrawTransformFromPropertyTrees(layer, tree).IsBackFaceVisible();
+ }
// In this case, either the layer establishes a new 3d rendering context, or
// is not in a 3d rendering context at all.
@@ -255,8 +250,16 @@ static bool IsSurfaceBackFaceVisible(LayerType* layer,
const TransformTree& tree) {
if (HasSingularTransform(layer, tree))
return false;
- if (LayerIsInExisting3DRenderingContext(layer)) {
- const TransformNode* node = tree.Node(layer->transform_tree_index());
+ const TransformNode* node = tree.Node(layer->transform_tree_index());
+ // If the render_surface is not part of a new or existing rendering context,
+ // then the layers that contribute to this surface will decide back-face
+ // visibility for themselves.
+ if (!node->data.sorting_context_id)
+ return false;
+
+ const TransformNode* parent_node = tree.parent(node);
+ if (parent_node &&
+ parent_node->data.sorting_context_id == node->data.sorting_context_id) {
// Draw transform as a contributing render surface.
// TODO(enne): we shouldn't walk the tree during a tree walk.
gfx::Transform surface_draw_transform;
@@ -265,13 +268,9 @@ static bool IsSurfaceBackFaceVisible(LayerType* layer,
return surface_draw_transform.IsBackFaceVisible();
}
- if (IsRootLayerOfNewRenderingContext(layer))
- return layer->transform().IsBackFaceVisible();
-
- // If the render_surface is not part of a new or existing rendering context,
- // then the layers that contribute to this surface will decide back-face
- // visibility for themselves.
- return false;
+ // We use layer's transform to determine back face visibility when its the
+ // root of a new rendering context.
+ return layer->transform().IsBackFaceVisible();
}
template <typename LayerType>
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index e98e138..d5ba0ce 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -6390,29 +6390,48 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) {
TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) {
LayerImpl* root = root_layer();
- LayerImpl* render_surface = AddChild<LayerImpl>(root);
- LayerImpl* child = AddChild<LayerImpl>(render_surface);
- child->SetDrawsContent(true);
+ LayerImpl* back_facing = AddChild<LayerImpl>(root);
+ LayerImpl* render_surface1 = AddChild<LayerImpl>(back_facing);
+ LayerImpl* render_surface2 = AddChild<LayerImpl>(back_facing);
+ LayerImpl* child1 = AddChild<LayerImpl>(render_surface1);
+ LayerImpl* child2 = AddChild<LayerImpl>(render_surface2);
+ child1->SetDrawsContent(true);
+ child2->SetDrawsContent(true);
gfx::Transform identity_transform;
SetLayerPropertiesForTesting(root, identity_transform, gfx::Point3F(),
gfx::PointF(), gfx::Size(50, 50), true, false,
true);
- SetLayerPropertiesForTesting(render_surface, identity_transform,
+ SetLayerPropertiesForTesting(back_facing, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(50, 50), true, false,
+ false);
+ SetLayerPropertiesForTesting(render_surface1, identity_transform,
gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
false, true, true);
- SetLayerPropertiesForTesting(child, identity_transform, gfx::Point3F(),
+ SetLayerPropertiesForTesting(render_surface2, identity_transform,
+ gfx::Point3F(), gfx::PointF(), gfx::Size(30, 30),
+ false, true, true);
+ SetLayerPropertiesForTesting(child1, identity_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(20, 20), true, false,
+ false);
+ SetLayerPropertiesForTesting(child2, identity_transform, gfx::Point3F(),
gfx::PointF(), gfx::Size(20, 20), true, false,
false);
root->SetShouldFlattenTransform(false);
root->Set3dSortingContextId(1);
- render_surface->SetDoubleSided(false);
+ back_facing->Set3dSortingContextId(1);
+ back_facing->SetShouldFlattenTransform(false);
+ render_surface1->SetDoubleSided(false);
+ render_surface2->Set3dSortingContextId(2);
+ render_surface2->SetDoubleSided(false);
ExecuteCalculateDrawProperties(root);
- EXPECT_EQ(2u, render_surface_layer_list_impl()->size());
- EXPECT_EQ(1u, render_surface_layer_list_impl()
+ EXPECT_EQ(render_surface1->sorting_context_id(), root->sorting_context_id());
+ EXPECT_NE(render_surface2->sorting_context_id(), root->sorting_context_id());
+ EXPECT_EQ(3u, render_surface_layer_list_impl()->size());
+ EXPECT_EQ(2u, render_surface_layer_list_impl()
->at(0)
->render_surface()
->layer_list()
@@ -6426,13 +6445,17 @@ TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) {
gfx::Transform rotation_transform = identity_transform;
rotation_transform.RotateAboutXAxis(180.0);
- render_surface->SetTransform(rotation_transform);
+ back_facing->SetTransform(rotation_transform);
root->layer_tree_impl()->property_trees()->needs_rebuild = true;
ExecuteCalculateDrawProperties(root);
- EXPECT_EQ(1u, render_surface_layer_list_impl()->size());
- EXPECT_EQ(0u, render_surface_layer_list_impl()
+ // render_surface1 is in the same 3d rendering context as back_facing and is
+ // not double sided, so it should not be in RSLL. render_surface2 is also not
+ // double-sided, but will still be in RSLL as it's in a different 3d rendering
+ // context.
+ EXPECT_EQ(2u, render_surface_layer_list_impl()->size());
+ EXPECT_EQ(1u, render_surface_layer_list_impl()
->at(0)
->render_surface()
->layer_list()
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 54d885e..2f88c83 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -125,6 +125,7 @@ TransformNodeData::TransformNodeData()
: target_id(-1),
content_target_id(-1),
source_node_id(-1),
+ sorting_context_id(0),
needs_local_transform_update(true),
is_invertible(true),
ancestors_are_invertible(true),
@@ -159,6 +160,7 @@ bool TransformNodeData::operator==(const TransformNodeData& other) const {
target_id == other.target_id &&
content_target_id == other.content_target_id &&
source_node_id == other.source_node_id &&
+ sorting_context_id == other.sorting_context_id &&
needs_local_transform_update == other.needs_local_transform_update &&
is_invertible == other.is_invertible &&
ancestors_are_invertible == other.ancestors_are_invertible &&
@@ -236,6 +238,7 @@ void TransformNodeData::ToProtobuf(proto::TreeNode* proto) const {
data->set_target_id(target_id);
data->set_content_target_id(content_target_id);
data->set_source_node_id(source_node_id);
+ data->set_sorting_context_id(sorting_context_id);
data->set_needs_local_transform_update(needs_local_transform_update);
@@ -300,6 +303,7 @@ void TransformNodeData::FromProtobuf(const proto::TreeNode& proto) {
target_id = data.target_id();
content_target_id = data.content_target_id();
source_node_id = data.source_node_id();
+ sorting_context_id = data.sorting_context_id();
needs_local_transform_update = data.needs_local_transform_update();
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index d6b4787..52aa419 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -91,6 +91,11 @@ struct CC_EXPORT TransformNodeData {
// tree.
int source_node_id;
+ // This id determines which 3d rendering context the node is in. 0 is a
+ // special value and indicates that the node is not in any 3d rendering
+ // context.
+ int sorting_context_id;
+
// TODO(vollick): will be moved when accelerated effects are implemented.
bool needs_local_transform_update : 1;
diff --git a/cc/trees/property_tree_builder.cc b/cc/trees/property_tree_builder.cc
index 8bb23ca..0dc9e13 100644
--- a/cc/trees/property_tree_builder.cc
+++ b/cc/trees/property_tree_builder.cc
@@ -244,10 +244,15 @@ bool AddTransformNodeIfNeeded(
layer->parent()->effect_tree_index() !=
layer->scroll_parent()->effect_tree_index();
+ const bool is_at_boundary_of_3d_rendering_context =
+ layer->parent()
+ ? layer->parent()->sorting_context_id() != layer->sorting_context_id()
+ : layer->Is3dSorted();
bool requires_node = is_root || is_scrollable || has_significant_transform ||
has_any_transform_animation || has_surface || is_fixed ||
is_page_scale_layer || is_overscroll_elasticity_layer ||
- scroll_child_has_different_target;
+ scroll_child_has_different_target ||
+ is_at_boundary_of_3d_rendering_context;
LayerType* transform_parent = GetTransformParent(data_from_ancestor, layer);
DCHECK(is_root || transform_parent);
@@ -324,6 +329,8 @@ bool AddTransformNodeIfNeeded(
node->data.scrolls = is_scrollable;
node->data.flattens_inherited_transform = data_for_children->should_flatten;
+ node->data.sorting_context_id = layer->sorting_context_id();
+
if (layer == data_from_ancestor.page_scale_layer)
data_for_children->in_subtree_of_page_scale_layer = true;
node->data.in_subtree_of_page_scale_layer =