diff options
-rw-r--r-- | cc/layers/delegated_renderer_layer_impl_unittest.cc | 22 | ||||
-rw-r--r-- | cc/test/data/scaled_render_surface_layer_gl.png | bin | 0 -> 4767 bytes | |||
-rw-r--r-- | cc/test/data/scaled_render_surface_layer_sw.png | bin | 0 -> 3414 bytes | |||
-rw-r--r-- | cc/trees/layer_tree_host_common.cc | 36 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_common_unittest.cc | 62 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_pixeltest_filters.cc | 63 |
6 files changed, 123 insertions, 60 deletions
diff --git a/cc/layers/delegated_renderer_layer_impl_unittest.cc b/cc/layers/delegated_renderer_layer_impl_unittest.cc index 395d361..aaef9f2 100644 --- a/cc/layers/delegated_renderer_layer_impl_unittest.cc +++ b/cc/layers/delegated_renderer_layer_impl_unittest.cc @@ -769,9 +769,9 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) { &root_delegated_shared_quad_state, &contrib_delegated_shared_quad_state); - // When the layer owns a surface, then its position and translation are not - // a part of its draw transform. - EXPECT_EQ(gfx::Rect(10, 10, 35, 35).ToString(), + // When the layer owns a surface, then its translation is not part of its + // draw transform, but its scale is. + EXPECT_EQ(gfx::Rect(20, 20, 70, 70).ToString(), root_delegated_shared_quad_state->clip_rect.ToString()); // Since the layer owns a surface it doesn't need to clip its quads, so @@ -779,8 +779,9 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsUnclipped_Surface) { EXPECT_FALSE(root_delegated_shared_quad_state->is_clipped); gfx::Transform expected; - // This is the transform within the source frame. - expected.Scale(1.5, 1.5); + // This is the transform within the source frame scaled by the delegated + // render layer transform. + expected.Scale(3.0, 3.0); expected.Translate(7.0, 7.0); EXPECT_TRANSFORMATION_MATRIX_EQ( expected, root_delegated_shared_quad_state->content_to_target_transform); @@ -817,17 +818,18 @@ TEST_F(DelegatedRendererLayerImplTestTransform, QuadsClipped_Surface) { &root_delegated_shared_quad_state, &contrib_delegated_shared_quad_state); - // When the layer owns a surface, then its position and translation are not - // a part of its draw transform. The clip_rect should be preserved. - EXPECT_EQ(gfx::Rect(10, 10, 35, 35).ToString(), + // When the layer owns a surface, then its translation is not part of its + // draw transform, but its scale is. + EXPECT_EQ(gfx::Rect(20, 20, 70, 70).ToString(), root_delegated_shared_quad_state->clip_rect.ToString()); // The quads had a clip and it should be preserved. EXPECT_TRUE(root_delegated_shared_quad_state->is_clipped); gfx::Transform expected; - // This is the transform within the source frame. - expected.Scale(1.5, 1.5); + // This is the transform within the source frame scaled by the delegated + // render layer transform. + expected.Scale(3.0, 3.0); expected.Translate(7.0, 7.0); EXPECT_TRANSFORMATION_MATRIX_EQ( expected, root_delegated_shared_quad_state->content_to_target_transform); diff --git a/cc/test/data/scaled_render_surface_layer_gl.png b/cc/test/data/scaled_render_surface_layer_gl.png Binary files differnew file mode 100644 index 0000000..e5802f7a --- /dev/null +++ b/cc/test/data/scaled_render_surface_layer_gl.png diff --git a/cc/test/data/scaled_render_surface_layer_sw.png b/cc/test/data/scaled_render_surface_layer_sw.png Binary files differnew file mode 100644 index 0000000..2a0ee21 --- /dev/null +++ b/cc/test/data/scaled_render_surface_layer_sw.png diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index 3e70aeb..e12e272 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc @@ -1831,14 +1831,6 @@ static void CalculateDrawPropertiesInternal( data_for_children.full_hierarchy_matrix = data_from_ancestor.full_hierarchy_matrix; - // If the subtree will scale layer contents by the transform hierarchy, then - // we should scale things into the render surface by the transform hierarchy - // to take advantage of that. - gfx::Vector2dF render_surface_sublayer_scale = - globals.can_adjust_raster_scales - ? combined_transform_scales - : gfx::Vector2dF(layer_scale_factors, layer_scale_factors); - bool render_to_separate_surface = IsRootLayer(layer) || (globals.can_render_to_separate_surface && layer->render_surface()); @@ -1873,17 +1865,19 @@ static void CalculateDrawPropertiesInternal( // space which we do not want; so here we use the combined_transform // instead of the draw_transform. However, we do need to add a different // scale factor that accounts for the surface's pixel dimensions. - combined_transform.Scale(1.0 / render_surface_sublayer_scale.x(), - 1.0 / render_surface_sublayer_scale.y()); - render_surface->SetDrawTransform(combined_transform); + // Remove the combined_transform scale from the draw transform. + gfx::Transform draw_transform = combined_transform; + draw_transform.Scale(1.0 / combined_transform_scales.x(), + 1.0 / combined_transform_scales.y()); + render_surface->SetDrawTransform(draw_transform); // The owning layer's transform was re-parented by the surface, so the // layer's new draw_transform only needs to scale the layer to surface // space. layer_draw_properties.target_space_transform.MakeIdentity(); - layer_draw_properties.target_space_transform. - Scale(render_surface_sublayer_scale.x() / layer->contents_scale_x(), - render_surface_sublayer_scale.y() / layer->contents_scale_y()); + layer_draw_properties.target_space_transform.Scale( + combined_transform_scales.x() / layer->contents_scale_x(), + combined_transform_scales.y() / layer->contents_scale_y()); // Inside the surface's subtree, we scale everything to the owning layer's // scale. The sublayer matrix transforms layer rects into target surface @@ -1892,8 +1886,8 @@ static void CalculateDrawPropertiesInternal( // but we apply it explicitly to the owning layer and the remainder of the // subtree independently. DCHECK(data_for_children.parent_matrix.IsIdentity()); - data_for_children.parent_matrix.Scale(render_surface_sublayer_scale.x(), - render_surface_sublayer_scale.y()); + data_for_children.parent_matrix.Scale(combined_transform_scales.x(), + combined_transform_scales.y()); // Even if the |layer_is_drawn|, it only contributes to a drawn surface // when the |layer_is_visible|. @@ -2311,14 +2305,14 @@ static void CalculateDrawPropertiesInternal( // surface's subtree into layer space. gfx::Transform screen_space_transform = layer->screen_space_transform(); screen_space_transform.Scale( - layer->contents_scale_x() / render_surface_sublayer_scale.x(), - layer->contents_scale_y() / render_surface_sublayer_scale.y()); + layer->contents_scale_x() / combined_transform_scales.x(), + layer->contents_scale_y() / combined_transform_scales.y()); render_surface->SetScreenSpaceTransform(screen_space_transform); if (layer->replica_layer()) { gfx::Transform surface_origin_to_replica_origin_transform; surface_origin_to_replica_origin_transform.Scale( - render_surface_sublayer_scale.x(), render_surface_sublayer_scale.y()); + combined_transform_scales.x(), combined_transform_scales.y()); surface_origin_to_replica_origin_transform.Translate( layer->replica_layer()->position().x() + layer->replica_layer()->transform_origin().x(), @@ -2330,8 +2324,8 @@ static void CalculateDrawPropertiesInternal( -layer->replica_layer()->transform_origin().x(), -layer->replica_layer()->transform_origin().y()); surface_origin_to_replica_origin_transform.Scale( - 1.0 / render_surface_sublayer_scale.x(), - 1.0 / render_surface_sublayer_scale.y()); + 1.0 / combined_transform_scales.x(), + 1.0 / combined_transform_scales.y()); // Compute the replica's "originTransform" that maps from the replica's // origin space to the target surface origin space. diff --git a/cc/trees/layer_tree_host_common_unittest.cc b/cc/trees/layer_tree_host_common_unittest.cc index 01941c1..238c3cb 100644 --- a/cc/trees/layer_tree_host_common_unittest.cc +++ b/cc/trees/layer_tree_host_common_unittest.cc @@ -5157,75 +5157,81 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_FLOAT_EQ(initial_parent_scale, parent->draw_transform().matrix().get(1, 1)); - // The child surface is scaled up during draw since its subtree is not scaled + // The child surface is not scaled up during draw since its subtree is scaled // by the transform hierarchy. EXPECT_FLOAT_EQ( - initial_parent_scale * initial_child_scale, + 1.f, surface_scale->render_surface()->draw_transform().matrix().get(0, 0)); EXPECT_FLOAT_EQ( - initial_parent_scale * initial_child_scale, + 1.f, surface_scale->render_surface()->draw_transform().matrix().get(1, 1)); - // The surface_scale's RenderSurface is scaled during draw, so the layer does - // not need to be scaled when drawing into its surface. - EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(0, 0)); - EXPECT_FLOAT_EQ(1.0, surface_scale->draw_transform().matrix().get(1, 1)); + // The surface_scale's RenderSurface is not scaled during draw, so the layer + // needs to be scaled when drawing into its surface. + EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale, + surface_scale->draw_transform().matrix().get(0, 0)); + EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale, + surface_scale->draw_transform().matrix().get(1, 1)); - // The surface_scale_child_scale is scaled when drawing into its surface, - // since its content bounds are not scaled by the transform hierarchy. + // The surface_scale_child_scale is not scaled when drawing into its surface, + // since its content bounds are scaled by the transform hierarchy. EXPECT_FLOAT_EQ( - initial_child_scale, + initial_child_scale * initial_child_scale * initial_parent_scale, surface_scale_child_scale->draw_transform().matrix().get(0, 0)); EXPECT_FLOAT_EQ( - initial_child_scale, + initial_child_scale * initial_child_scale * initial_parent_scale, surface_scale_child_scale->draw_transform().matrix().get(1, 1)); - // The surface_scale_child_no_scale has a fixed contents scale of 1, so it - // needs to be scaled by the device and page scale factors, along with the - // transform hierarchy. + // The surface_scale_child_no_scale is scaled by the device scale, page scale + // and transform hierarchy. EXPECT_FLOAT_EQ( - device_scale_factor * page_scale_factor * initial_child_scale, + device_scale_factor * page_scale_factor * initial_parent_scale * + initial_child_scale * initial_child_scale, surface_scale_child_no_scale->draw_transform().matrix().get(0, 0)); EXPECT_FLOAT_EQ( - device_scale_factor * page_scale_factor * initial_child_scale, + device_scale_factor * page_scale_factor * initial_parent_scale * + initial_child_scale * initial_child_scale, surface_scale_child_no_scale->draw_transform().matrix().get(1, 1)); - // The child surface is scaled up during draw since its subtree is not scaled + // The child surface is not scaled up during draw since its subtree is scaled // by the transform hierarchy. EXPECT_FLOAT_EQ( - initial_parent_scale * initial_child_scale, + 1.f, surface_no_scale->render_surface()->draw_transform().matrix().get(0, 0)); EXPECT_FLOAT_EQ( - initial_parent_scale * initial_child_scale, + 1.f, surface_no_scale->render_surface()->draw_transform().matrix().get(1, 1)); // The surface_no_scale layer has a fixed contents scale of 1, so it needs to // be scaled by the device and page scale factors. Its surface is already // scaled by the transform hierarchy so those don't need to scale the layer's // drawing. - EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor, + EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale * + device_scale_factor * page_scale_factor, surface_no_scale->draw_transform().matrix().get(0, 0)); - EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor, + EXPECT_FLOAT_EQ(initial_parent_scale * initial_child_scale * + device_scale_factor * page_scale_factor, surface_no_scale->draw_transform().matrix().get(1, 1)); // The surface_no_scale_child_scale has its contents scaled by the page and // device scale factors, but needs to be scaled by the transform hierarchy // when drawing. EXPECT_FLOAT_EQ( - initial_child_scale, + initial_parent_scale * initial_child_scale * initial_child_scale, surface_no_scale_child_scale->draw_transform().matrix().get(0, 0)); EXPECT_FLOAT_EQ( - initial_child_scale, + initial_parent_scale * initial_child_scale * initial_child_scale, surface_no_scale_child_scale->draw_transform().matrix().get(1, 1)); - // The surface_no_scale_child_no_scale has a fixed contents scale of 1, so it - // needs to be scaled by the device and page scale factors. It also needs to - // be scaled by any transform heirarchy below its target surface. + // The surface_no_scale_child_no_scale needs to be scaled by the device and + // page scale factors and by any transform heirarchy below its target surface. EXPECT_FLOAT_EQ( - device_scale_factor * page_scale_factor * initial_child_scale, + device_scale_factor * page_scale_factor * initial_parent_scale * + initial_child_scale * initial_child_scale, surface_no_scale_child_no_scale->draw_transform().matrix().get(0, 0)); EXPECT_FLOAT_EQ( - device_scale_factor * page_scale_factor * initial_child_scale, + device_scale_factor * page_scale_factor * initial_parent_scale * + initial_child_scale * initial_child_scale, surface_no_scale_child_no_scale->draw_transform().matrix().get(1, 1)); } diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc index dc8cc4a..bf8e3e2 100644 --- a/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -283,7 +283,7 @@ TEST_F(LayerTreeHostFiltersPixelTest, ImageFilterScaled_GL) { gfx::Rect rect(50, 50, 100, 100); - static const int kInset = 3; + const int kInset = 3; for (int i = 0; !rect.IsEmpty(); ++i) { scoped_refptr<SolidColorLayer> layer = CreateSolidColorLayer(rect, (i & 1) ? SK_ColorWHITE : SK_ColorRED); @@ -334,6 +334,67 @@ TEST_F(LayerTreeHostFiltersPixelTest, ImageFilterScaled_GL) { base::FilePath(FILE_PATH_LITERAL("filter_on_scaled_layer.png"))); } +class ImageScaledRenderSurface : public LayerTreeHostFiltersPixelTest { + protected: + void RunPixelTestType(PixelTestType test_type, base::FilePath image_name) { + // A filter will cause a render surface to be used. Here we force the + // render surface on, and scale the result to make sure that we rasterize at + // the correct resolution. + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(300, 300), SK_ColorBLUE); + + scoped_refptr<SolidColorLayer> render_surface_layer = + CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE); + + gfx::Rect rect(50, 50, 100, 100); + + scoped_refptr<SolidColorLayer> child = + CreateSolidColorLayer(rect, SK_ColorRED); + + gfx::Transform transform; + transform.Translate(rect.width() / 2.0, rect.height() / 2.0); + transform.RotateAboutZAxis(30.0); + transform.Translate(-rect.width() / 2.0, -rect.height() / 2.0); + child->SetTransform(transform); + + render_surface_layer->AddChild(child); + + gfx::Transform render_surface_transform; + render_surface_transform.Scale(1.5f, 1.5f); + render_surface_layer->SetTransform(render_surface_transform); + render_surface_layer->SetForceRenderSurface(true); + + background->AddChild(render_surface_layer); + + // Software has some huge differences in the AA'd pixels on the different + // trybots. See crbug.com/452198. + float percentage_pixels_large_error = 0.686f; + float percentage_pixels_small_error = 0.0f; + float average_error_allowed_in_bad_pixels = 16.f; + int large_error_allowed = 17; + int small_error_allowed = 0; + pixel_comparator_.reset(new FuzzyPixelComparator( + true, // discard_alpha + percentage_pixels_large_error, percentage_pixels_small_error, + average_error_allowed_in_bad_pixels, large_error_allowed, + small_error_allowed)); + + RunPixelTest(test_type, background, image_name); + } +}; + +TEST_F(ImageScaledRenderSurface, ImageRenderSurfaceScaled_GL) { + RunPixelTestType( + PIXEL_TEST_GL, + base::FilePath(FILE_PATH_LITERAL("scaled_render_surface_layer_gl.png"))); +} + +TEST_F(ImageScaledRenderSurface, ImageRenderSurfaceScaled_Software) { + RunPixelTestType( + PIXEL_TEST_SOFTWARE, + base::FilePath(FILE_PATH_LITERAL("scaled_render_surface_layer_sw.png"))); +} + } // namespace } // namespace cc |