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

Unified Diff: cc/trees/layer_tree_host_common_unittest.cc

Issue 1387003002: cc: Make property trees support resourceless draw mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@DontReparentUnclippedClipNodes
Patch Set: Rebased Created 5 years, 2 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
« no previous file with comments | « cc/trees/layer_tree_host_common.cc ('k') | cc/trees/property_tree.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/trees/layer_tree_host_common_unittest.cc
diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc
index 9345f28e8999cc35ca3915483242175deb063f08..6883986c7d08f65ccd910f173963a3dbd8a5f480 100644
--- a/cc/trees/layer_tree_host_common_unittest.cc
+++ b/cc/trees/layer_tree_host_common_unittest.cc
@@ -522,6 +522,61 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) {
child->render_target()->render_surface()->screen_space_transform());
}
+TEST_F(LayerTreeHostCommonTest, TransformsWhenCannotRenderToSeparateSurface) {
+ LayerImpl* root = root_layer();
+ LayerImpl* parent = AddChildToRoot<LayerImpl>();
+ LayerImpl* child = AddChild<LayerImpl>(parent);
+ LayerImpl* grand_child = AddChild<LayerImpl>(child);
+ grand_child->SetDrawsContent(true);
+
+ gfx::Transform identity_matrix;
+ SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+
+ gfx::Transform parent_transform;
+ parent_transform.Translate(10.0, 10.0);
+
+ gfx::Transform child_transform;
+ child_transform.Rotate(45.0);
+
+ // child gets a render surface when surfaces are enabled.
+ SetLayerPropertiesForTesting(parent, parent_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(10, 10), true, false,
+ false);
+ SetLayerPropertiesForTesting(child, child_transform, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(10, 10), true, false,
+ true);
+ SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(),
+ gfx::PointF(2.0, 2.0), gfx::Size(20, 20), true,
+ false, false);
+
+ gfx::Transform expected_grand_child_screen_space_transform;
+ expected_grand_child_screen_space_transform.Translate(10.0, 10.0);
+ expected_grand_child_screen_space_transform.Rotate(45.0);
+ expected_grand_child_screen_space_transform.Translate(2.0, 2.0);
+
+ // First compute draw properties with separate surfaces enabled.
+ ExecuteCalculateDrawProperties(root);
+
+ // The grand child's draw transform should be its offset wrt the child.
+ gfx::Transform expected_grand_child_draw_transform;
+ expected_grand_child_draw_transform.Translate(2.0, 2.0);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_draw_transform,
+ grand_child->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform,
+ grand_child->screen_space_transform());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+
+ // With separate surfaces disabled, the grand child's draw transform should be
+ // the same as its screen space transform.
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform,
+ grand_child->draw_transform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform,
+ grand_child->screen_space_transform());
+}
+
TEST_F(LayerTreeHostCommonTest, TransformsForReplica) {
LayerImpl* root = root_layer();
LayerImpl* parent = AddChildToRoot<LayerImpl>();
@@ -1232,6 +1287,83 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) {
EXPECT_EQ(SkXfermode::kSrcOver_Mode, child->draw_blend_mode());
}
+TEST_F(LayerTreeHostCommonTest, DrawOpacityWhenCannotRenderToSeparateSurface) {
+ // Tests that when separate surfaces are disabled, a layer's draw opacity is
+ // the product of all ancestor layer opacties and the layer's own opacity.
+ // (Rendering will still be incorrect in situations where we really do need
+ // surfaces to apply opacity, such as when we have overlapping layers with an
+ // ancestor whose opacity is <1.)
+ LayerImpl* root = root_layer();
+ LayerImpl* parent = AddChild<LayerImpl>(root);
+ LayerImpl* child1 = AddChild<LayerImpl>(parent);
+ LayerImpl* child2 = AddChild<LayerImpl>(parent);
+ LayerImpl* grand_child = AddChild<LayerImpl>(child1);
+ LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child);
+ LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2);
+
+ root->SetDrawsContent(true);
+ parent->SetDrawsContent(true);
+ child1->SetDrawsContent(true);
+ child2->SetDrawsContent(true);
+ grand_child->SetDrawsContent(true);
+ leaf_node1->SetDrawsContent(true);
+ leaf_node2->SetDrawsContent(true);
+
+ const gfx::Transform identity_matrix;
+
+ // child1 and grand_child get render surfaces when surfaces are enabled.
+ SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+ SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ false);
+ SetLayerPropertiesForTesting(child1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+ SetLayerPropertiesForTesting(child2, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ false);
+ SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+ SetLayerPropertiesForTesting(leaf_node1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ false);
+ SetLayerPropertiesForTesting(leaf_node2, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ false);
+
+ child1->SetOpacity(0.5f);
+ grand_child->SetOpacity(0.5f);
+ leaf_node1->SetOpacity(0.5f);
+ leaf_node2->SetOpacity(0.5f);
+
+ // With surfaces enabled, each layer's draw opacity is the product of layer
+ // opacities on the path from the layer to its render target, not including
+ // the opacity of the layer that owns the target surface (since that opacity
+ // is applied by the surface).
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_EQ(1.f, root->draw_opacity());
+ EXPECT_EQ(1.f, parent->draw_opacity());
+ EXPECT_EQ(1.f, child1->draw_opacity());
+ EXPECT_EQ(1.f, child2->draw_opacity());
+ EXPECT_EQ(1.f, grand_child->draw_opacity());
+ EXPECT_EQ(0.5f, leaf_node1->draw_opacity());
+ EXPECT_EQ(0.5f, leaf_node2->draw_opacity());
+
+ // With surfaces disabled, each layer's draw opacity is the product of layer
+ // opacities on the path from the layer to the root.
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_EQ(1.f, root->draw_opacity());
+ EXPECT_EQ(1.f, parent->draw_opacity());
+ EXPECT_EQ(0.5f, child1->draw_opacity());
+ EXPECT_EQ(1.f, child2->draw_opacity());
+ EXPECT_EQ(0.25f, grand_child->draw_opacity());
+ EXPECT_EQ(0.125f, leaf_node1->draw_opacity());
+ EXPECT_EQ(0.5f, leaf_node2->draw_opacity());
+}
+
TEST_F(LayerTreeHostCommonTest, ForceRenderSurface) {
scoped_refptr<Layer> parent = Layer::Create(layer_settings());
scoped_refptr<Layer> render_surface1 = Layer::Create(layer_settings());
@@ -1579,6 +1711,170 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) {
}
}
+TEST_F(LayerTreeHostCommonTest, IsClippedWhenCannotRenderToSeparateSurface) {
+ // Tests that when separate surfaces are disabled, is_clipped is true exactly
+ // when a layer or its ancestor has a clip; in particular, if a layer
+ // is_clipped, so is its entire subtree (since there are no render surfaces
+ // that can reset is_clipped).
+ LayerImpl* root = root_layer();
+ LayerImpl* parent = AddChild<LayerImpl>(root);
+ LayerImpl* child1 = AddChild<LayerImpl>(parent);
+ LayerImpl* child2 = AddChild<LayerImpl>(parent);
+ LayerImpl* grand_child = AddChild<LayerImpl>(child1);
+ LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child);
+ LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2);
+
+ root->SetDrawsContent(true);
+ parent->SetDrawsContent(true);
+ child1->SetDrawsContent(true);
+ child2->SetDrawsContent(true);
+ grand_child->SetDrawsContent(true);
+ leaf_node1->SetDrawsContent(true);
+ leaf_node2->SetDrawsContent(true);
+
+ const gfx::Transform identity_matrix;
+
+ // child1 and grand_child get render surfaces when surfaces are enabled.
+ SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+ SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ false);
+ SetLayerPropertiesForTesting(child1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+ SetLayerPropertiesForTesting(child2, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ false);
+ SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+ SetLayerPropertiesForTesting(leaf_node1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ false);
+ SetLayerPropertiesForTesting(leaf_node2, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ false);
+
+ // Case 1: Nothing is clipped. In this case, is_clipped is always false, with
+ // or without surfaces.
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_FALSE(root->is_clipped());
+ EXPECT_FALSE(parent->is_clipped());
+ EXPECT_FALSE(child1->is_clipped());
+ EXPECT_FALSE(child2->is_clipped());
+ EXPECT_FALSE(grand_child->is_clipped());
+ EXPECT_FALSE(leaf_node1->is_clipped());
+ EXPECT_FALSE(leaf_node2->is_clipped());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_FALSE(root->is_clipped());
+ EXPECT_FALSE(parent->is_clipped());
+ EXPECT_FALSE(child1->is_clipped());
+ EXPECT_FALSE(child2->is_clipped());
+ EXPECT_FALSE(grand_child->is_clipped());
+ EXPECT_FALSE(leaf_node1->is_clipped());
+ EXPECT_FALSE(leaf_node2->is_clipped());
+
+ // Case 2: The root is clipped. With surfaces, this only persists until the
+ // next render surface. Without surfaces, the entire tree is clipped.
+ root->SetMasksToBounds(true);
+ host_impl()->active_tree()->property_trees()->needs_rebuild = true;
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_TRUE(root->is_clipped());
+ EXPECT_TRUE(parent->is_clipped());
+ EXPECT_FALSE(child1->is_clipped());
+ EXPECT_TRUE(child2->is_clipped());
+ EXPECT_FALSE(grand_child->is_clipped());
+ EXPECT_FALSE(leaf_node1->is_clipped());
+ EXPECT_TRUE(leaf_node2->is_clipped());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_TRUE(root->is_clipped());
+ EXPECT_TRUE(parent->is_clipped());
+ EXPECT_TRUE(child1->is_clipped());
+ EXPECT_TRUE(child2->is_clipped());
+ EXPECT_TRUE(grand_child->is_clipped());
+ EXPECT_TRUE(leaf_node1->is_clipped());
+ EXPECT_TRUE(leaf_node2->is_clipped());
+
+ root->SetMasksToBounds(false);
+
+ // Case 3: The parent is clipped. Again, with surfaces, this only persists
+ // until the next render surface. Without surfaces, parent's entire subtree is
+ // clipped.
+ parent->SetMasksToBounds(true);
+ host_impl()->active_tree()->property_trees()->needs_rebuild = true;
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_FALSE(root->is_clipped());
+ EXPECT_TRUE(parent->is_clipped());
+ EXPECT_FALSE(child1->is_clipped());
+ EXPECT_TRUE(child2->is_clipped());
+ EXPECT_FALSE(grand_child->is_clipped());
+ EXPECT_FALSE(leaf_node1->is_clipped());
+ EXPECT_TRUE(leaf_node2->is_clipped());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_FALSE(root->is_clipped());
+ EXPECT_TRUE(parent->is_clipped());
+ EXPECT_TRUE(child1->is_clipped());
+ EXPECT_TRUE(child2->is_clipped());
+ EXPECT_TRUE(grand_child->is_clipped());
+ EXPECT_TRUE(leaf_node1->is_clipped());
+ EXPECT_TRUE(leaf_node2->is_clipped());
+
+ parent->SetMasksToBounds(false);
+
+ // Case 4: child1 is clipped. With surfaces, only child1 is_clipped, since it
+ // has no non-surface children. Without surfaces, child1's entire subtree is
+ // clipped.
+ child1->SetMasksToBounds(true);
+ host_impl()->active_tree()->property_trees()->needs_rebuild = true;
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_FALSE(root->is_clipped());
+ EXPECT_FALSE(parent->is_clipped());
+ EXPECT_TRUE(child1->is_clipped());
+ EXPECT_FALSE(child2->is_clipped());
+ EXPECT_FALSE(grand_child->is_clipped());
+ EXPECT_FALSE(leaf_node1->is_clipped());
+ EXPECT_FALSE(leaf_node2->is_clipped());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_FALSE(root->is_clipped());
+ EXPECT_FALSE(parent->is_clipped());
+ EXPECT_TRUE(child1->is_clipped());
+ EXPECT_FALSE(child2->is_clipped());
+ EXPECT_TRUE(grand_child->is_clipped());
+ EXPECT_TRUE(leaf_node1->is_clipped());
+ EXPECT_FALSE(leaf_node2->is_clipped());
+
+ child1->SetMasksToBounds(false);
+
+ // Case 5: Only the leaf nodes are clipped. The behavior with and without
+ // surfaces is the same.
+ leaf_node1->SetMasksToBounds(true);
+ leaf_node2->SetMasksToBounds(true);
+ host_impl()->active_tree()->property_trees()->needs_rebuild = true;
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_FALSE(root->is_clipped());
+ EXPECT_FALSE(parent->is_clipped());
+ EXPECT_FALSE(child1->is_clipped());
+ EXPECT_FALSE(child2->is_clipped());
+ EXPECT_FALSE(grand_child->is_clipped());
+ EXPECT_TRUE(leaf_node1->is_clipped());
+ EXPECT_TRUE(leaf_node2->is_clipped());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_FALSE(root->is_clipped());
+ EXPECT_FALSE(parent->is_clipped());
+ EXPECT_FALSE(child1->is_clipped());
+ EXPECT_FALSE(child2->is_clipped());
+ EXPECT_FALSE(grand_child->is_clipped());
+ EXPECT_TRUE(leaf_node1->is_clipped());
+ EXPECT_TRUE(leaf_node2->is_clipped());
+}
+
TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) {
// Verify that layers get the appropriate DrawableContentRect when their
// parent masksToBounds is true.
@@ -1719,6 +2015,187 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
grand_child3->render_surface()->clip_rect());
}
+TEST_F(LayerTreeHostCommonTest, ClipRectWhenCannotRenderToSeparateSurface) {
+ // Tests that when separate surfaces are disabled, a layer's clip_rect is the
+ // intersection of all ancestor clips in screen space; in particular, if a
+ // layer masks to bounds, it contributes to the clip_rect of all layers in its
+ // subtree (since there are no render surfaces that can reset the clip_rect).
+ LayerImpl* root = root_layer();
+ LayerImpl* parent = AddChild<LayerImpl>(root);
+ LayerImpl* child1 = AddChild<LayerImpl>(parent);
+ LayerImpl* child2 = AddChild<LayerImpl>(parent);
+ LayerImpl* grand_child = AddChild<LayerImpl>(child1);
+ LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child);
+ LayerImpl* leaf_node2 = AddChild<LayerImpl>(child2);
+
+ root->SetDrawsContent(true);
+ parent->SetDrawsContent(true);
+ child1->SetDrawsContent(true);
+ child2->SetDrawsContent(true);
+ grand_child->SetDrawsContent(true);
+ leaf_node1->SetDrawsContent(true);
+ leaf_node2->SetDrawsContent(true);
+
+ const gfx::Transform identity_matrix;
+
+ // child1 and grand_child get render surfaces when surfaces are enabled.
+ SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+ SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(),
+ gfx::PointF(2.f, 2.f), gfx::Size(400, 400), true,
+ false, false);
+ SetLayerPropertiesForTesting(child1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(4.f, 4.f), gfx::Size(800, 800), true,
+ false, true);
+ SetLayerPropertiesForTesting(child2, identity_matrix, gfx::Point3F(),
+ gfx::PointF(3.f, 3.f), gfx::Size(800, 800), true,
+ false, false);
+ SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(),
+ gfx::PointF(8.f, 8.f), gfx::Size(1500, 1500),
+ true, false, true);
+ SetLayerPropertiesForTesting(leaf_node1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(16.f, 16.f), gfx::Size(2000, 2000),
+ true, false, false);
+ SetLayerPropertiesForTesting(leaf_node2, identity_matrix, gfx::Point3F(),
+ gfx::PointF(9.f, 9.f), gfx::Size(2000, 2000),
+ true, false, false);
+
+ // Case 1: Nothing is clipped. In this case, each layer's clip rect is its
+ // bounds in target space. The only thing that changes when surfaces are
+ // disabled is that target space is always screen space.
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child1->clip_rect());
+ EXPECT_EQ(gfx::Rect(5, 5, 800, 800), child2->clip_rect());
+ EXPECT_EQ(gfx::Rect(1500, 1500), grand_child->clip_rect());
+ EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node1->clip_rect());
+ EXPECT_EQ(gfx::Rect(14, 14, 2000, 2000), leaf_node2->clip_rect());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect());
+ EXPECT_EQ(gfx::Rect(6, 6, 800, 800), child1->clip_rect());
+ EXPECT_EQ(gfx::Rect(5, 5, 800, 800), child2->clip_rect());
+ EXPECT_EQ(gfx::Rect(14, 14, 1500, 1500), grand_child->clip_rect());
+ EXPECT_EQ(gfx::Rect(30, 30, 2000, 2000), leaf_node1->clip_rect());
+ EXPECT_EQ(gfx::Rect(14, 14, 2000, 2000), leaf_node2->clip_rect());
+
+ // Case 2: The root is clipped. In this case, layers that draw into the root
+ // render surface are clipped by the root's bounds.
+ root->SetMasksToBounds(true);
+ host_impl()->active_tree()->property_trees()->needs_rebuild = true;
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), parent->clip_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child1->clip_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), child2->clip_rect());
+ EXPECT_EQ(gfx::Rect(1500, 1500), grand_child->clip_rect());
+ EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node1->clip_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), leaf_node2->clip_rect());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), parent->clip_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), child1->clip_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), child2->clip_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), grand_child->clip_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), leaf_node1->clip_rect());
+ EXPECT_EQ(gfx::Rect(100, 100), leaf_node2->clip_rect());
+
+ root->SetMasksToBounds(false);
+
+ // Case 3: The parent and child1 are clipped. When surfaces are enabled, the
+ // parent clip rect only contributes to the subtree rooted at child2, since
+ // the subtree rooted at child1 renders into a separate surface. Similarly,
+ // child1's clip rect doesn't contribute to its descendants, since its only
+ // child is a render surface. However, without surfaces, these clip rects
+ // contribute to all descendants.
+ parent->SetMasksToBounds(true);
+ child1->SetMasksToBounds(true);
+ host_impl()->active_tree()->property_trees()->needs_rebuild = true;
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child1->clip_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), child2->clip_rect());
+ EXPECT_EQ(gfx::Rect(1500, 1500), grand_child->clip_rect());
+ EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node1->clip_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), leaf_node2->clip_rect());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->clip_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->clip_rect());
+ EXPECT_EQ(gfx::Rect(6, 6, 396, 396), child1->clip_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), child2->clip_rect());
+ EXPECT_EQ(gfx::Rect(6, 6, 396, 396), grand_child->clip_rect());
+ EXPECT_EQ(gfx::Rect(6, 6, 396, 396), leaf_node1->clip_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), leaf_node2->clip_rect());
+}
+
+TEST_F(LayerTreeHostCommonTest, SurfacesDisabledAndReEnabled) {
+ // Tests that draw properties are computed correctly when we disable and then
+ // re-enable separate surfaces.
+ LayerImpl* root = root_layer();
+ LayerImpl* parent = AddChild<LayerImpl>(root);
+ LayerImpl* child = AddChild<LayerImpl>(parent);
+ LayerImpl* grand_child = AddChild<LayerImpl>(child);
+ LayerImpl* leaf_node = AddChild<LayerImpl>(grand_child);
+
+ root->SetDrawsContent(true);
+ parent->SetDrawsContent(true);
+ child->SetDrawsContent(true);
+ grand_child->SetDrawsContent(true);
+ leaf_node->SetDrawsContent(true);
+
+ const gfx::Transform identity_matrix;
+
+ // child and grand_child get render surfaces when surfaces are enabled.
+ SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+ SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(),
+ gfx::PointF(2.f, 2.f), gfx::Size(400, 400), true,
+ false, false);
+ SetLayerPropertiesForTesting(child, identity_matrix, gfx::Point3F(),
+ gfx::PointF(4.f, 4.f), gfx::Size(800, 800), true,
+ false, true);
+ SetLayerPropertiesForTesting(grand_child, identity_matrix, gfx::Point3F(),
+ gfx::PointF(8.f, 8.f), gfx::Size(1500, 1500),
+ true, false, true);
+ SetLayerPropertiesForTesting(leaf_node, identity_matrix, gfx::Point3F(),
+ gfx::PointF(16.f, 16.f), gfx::Size(2000, 2000),
+ true, false, false);
+
+ parent->SetMasksToBounds(true);
+ child->SetMasksToBounds(true);
+
+ gfx::Transform expected_leaf_draw_transform_with_surfaces;
+ expected_leaf_draw_transform_with_surfaces.Translate(16.0, 16.0);
+
+ gfx::Transform expected_leaf_draw_transform_without_surfaces;
+ expected_leaf_draw_transform_without_surfaces.Translate(30.0, 30.0);
+
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->clip_rect());
+ EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->drawable_content_rect());
+ EXPECT_EQ(expected_leaf_draw_transform_with_surfaces,
+ leaf_node->draw_transform());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_EQ(gfx::Rect(6, 6, 396, 396), leaf_node->clip_rect());
+ EXPECT_EQ(gfx::Rect(30, 30, 372, 372), leaf_node->drawable_content_rect());
+ EXPECT_EQ(expected_leaf_draw_transform_without_surfaces,
+ leaf_node->draw_transform());
+
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->clip_rect());
+ EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node->drawable_content_rect());
+ EXPECT_EQ(expected_leaf_draw_transform_with_surfaces,
+ leaf_node->draw_transform());
+}
+
TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) {
LayerImpl* parent = root_layer();
LayerImpl* render_surface1 = AddChildToRoot<LayerImpl>();
@@ -2406,6 +2883,194 @@ TEST_F(LayerTreeHostCommonTest,
}
TEST_F(LayerTreeHostCommonTest,
+ DrawableAndVisibleRectsWhenCannotRenderToSeparateSurface) {
+ LayerImpl* root = root_layer();
+ LayerImpl* parent = AddChild<LayerImpl>(root);
+ LayerImpl* child1 = AddChild<LayerImpl>(parent);
+ LayerImpl* child2 = AddChild<LayerImpl>(parent);
+ LayerImpl* grand_child1 = AddChild<LayerImpl>(child1);
+ LayerImpl* grand_child2 = AddChild<LayerImpl>(child2);
+ LayerImpl* leaf_node1 = AddChild<LayerImpl>(grand_child1);
+ LayerImpl* leaf_node2 = AddChild<LayerImpl>(grand_child2);
+
+ root->SetDrawsContent(true);
+ parent->SetDrawsContent(true);
+ child1->SetDrawsContent(true);
+ child2->SetDrawsContent(true);
+ grand_child1->SetDrawsContent(true);
+ grand_child2->SetDrawsContent(true);
+ leaf_node1->SetDrawsContent(true);
+ leaf_node2->SetDrawsContent(true);
+
+ const gfx::Transform identity_matrix;
+
+ // child1 and child2 get render surfaces when surfaces are enabled.
+ SetLayerPropertiesForTesting(root, identity_matrix, gfx::Point3F(),
+ gfx::PointF(), gfx::Size(100, 100), true, false,
+ true);
+ SetLayerPropertiesForTesting(parent, identity_matrix, gfx::Point3F(),
+ gfx::PointF(2.f, 2.f), gfx::Size(400, 400), true,
+ false, false);
+ SetLayerPropertiesForTesting(child1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(4.f, 4.f), gfx::Size(800, 800), true,
+ false, true);
+ SetLayerPropertiesForTesting(child2, identity_matrix, gfx::Point3F(),
+ gfx::PointF(3.f, 3.f), gfx::Size(800, 800), true,
+ false, true);
+ SetLayerPropertiesForTesting(grand_child1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(8.f, 8.f), gfx::Size(1500, 1500),
+ true, false, false);
+ SetLayerPropertiesForTesting(grand_child2, identity_matrix, gfx::Point3F(),
+ gfx::PointF(7.f, 7.f), gfx::Size(1500, 1500),
+ true, false, false);
+ SetLayerPropertiesForTesting(leaf_node1, identity_matrix, gfx::Point3F(),
+ gfx::PointF(16.f, 16.f), gfx::Size(2000, 2000),
+ true, false, false);
+ SetLayerPropertiesForTesting(leaf_node2, identity_matrix, gfx::Point3F(),
+ gfx::PointF(9.f, 9.f), gfx::Size(2000, 2000),
+ true, false, false);
+
+ // Case 1: No layers clip. Visible rects are clipped by the viewport, but the
+ // viewport clip doesn't apply to layers that draw into unclipped surfaces.
+ // Each layer's drawable content rect is its bounds in target space; the only
+ // thing that changes with surfaces disabled is that target space is always
+ // screen space.
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(0, 0, 98, 98), parent->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(1500, 1500), grand_child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(1500, 1500), grand_child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(2000, 2000), leaf_node1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(2000, 2000), leaf_node2->visible_layer_rect());
+
+ EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(8, 8, 1500, 1500), grand_child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(7, 7, 1500, 1500), grand_child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(24, 24, 2000, 2000), leaf_node1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node2->drawable_content_rect());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
+
+ EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(6, 6, 800, 800), child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(5, 5, 800, 800), child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(14, 14, 1500, 1500),
+ grand_child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(12, 12, 1500, 1500),
+ grand_child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(30, 30, 2000, 2000), leaf_node1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(21, 21, 2000, 2000), leaf_node2->drawable_content_rect());
+
+ // Case 2: The parent clips. In this case, neither surface is unclipped, so
+ // all visible layer rects are clipped by the intersection of all ancestor
+ // clips, whether or not surfaces are disabled. However, drawable content
+ // rects are clipped only until the next render surface is reached, so
+ // descendants of parent have their drawable content rects clipped only when
+ // surfaces are disabled.
+ parent->SetMasksToBounds(true);
+ host_impl()->active_tree()->property_trees()->needs_rebuild = true;
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
+
+ EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(8, 8, 1500, 1500), grand_child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(7, 7, 1500, 1500), grand_child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(24, 24, 2000, 2000), leaf_node1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(16, 16, 2000, 2000), leaf_node2->drawable_content_rect());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
+
+ EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(6, 6, 396, 396), child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(5, 5, 397, 397), child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(14, 14, 388, 388), grand_child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(12, 12, 390, 390), grand_child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(30, 30, 372, 372), leaf_node1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(21, 21, 381, 381), leaf_node2->drawable_content_rect());
+
+ parent->SetMasksToBounds(false);
+
+ // Case 3: child1 and grand_child2 clip. In this case, descendants of these
+ // layers have their visible rects clipped by them; without surfaces, these
+ // rects are also clipped by the viewport. Similarly, descendants of these
+ // layers have their drawable content rects clipped by them.
+ child1->SetMasksToBounds(true);
+ grand_child2->SetMasksToBounds(true);
+ host_impl()->active_tree()->property_trees()->needs_rebuild = true;
+ ExecuteCalculateDrawProperties(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(792, 792), grand_child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(1500, 1500), grand_child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(776, 776), leaf_node1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(1491, 1491), leaf_node2->visible_layer_rect());
+
+ EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(800, 800), child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(8, 8, 792, 792), grand_child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(7, 7, 1500, 1500), grand_child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(24, 24, 776, 776), leaf_node1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(16, 16, 1491, 1491), leaf_node2->drawable_content_rect());
+
+ ExecuteCalculateDrawPropertiesWithoutSeparateSurfaces(root);
+ EXPECT_EQ(gfx::Rect(100, 100), root->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(98, 98), parent->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(94, 94), child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(95, 95), child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(86, 86), grand_child1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(88, 88), grand_child2->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(70, 70), leaf_node1->visible_layer_rect());
+ EXPECT_EQ(gfx::Rect(79, 79), leaf_node2->visible_layer_rect());
+
+ EXPECT_EQ(gfx::Rect(100, 100), root->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(2, 2, 400, 400), parent->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(6, 6, 800, 800), child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(5, 5, 800, 800), child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(14, 14, 792, 792), grand_child1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(12, 12, 1500, 1500),
+ grand_child2->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(30, 30, 776, 776), leaf_node1->drawable_content_rect());
+ EXPECT_EQ(gfx::Rect(21, 21, 1491, 1491), leaf_node2->drawable_content_rect());
+}
+
+TEST_F(LayerTreeHostCommonTest,
VisibleContentRectsForClippedSurfaceWithEmptyClip) {
LayerImpl* root = root_layer();
LayerImpl* child1 = AddChild<LayerImpl>(root);
« no previous file with comments | « cc/trees/layer_tree_host_common.cc ('k') | cc/trees/property_tree.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698