1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "build/build_config.h"
6 #include "cc/layers/solid_color_layer.h"
7 #include "cc/test/layer_tree_pixel_test.h"
8 #include "cc/test/pixel_comparator.h"
9 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
10 #include "third_party/skia/include/effects/SkColorMatrixFilter.h"
12 #if !defined(OS_ANDROID)
17 class LayerTreeHostFiltersPixelTest : public LayerTreePixelTest {};
19 TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) {
20 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
21 gfx::Rect(200, 200), SK_ColorWHITE);
23 // The green box is entirely behind a layer with background blur, so it
24 // should appear blurred on its edges.
25 scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
26 gfx::Rect(50, 50, 100, 100), kCSSGreen);
27 scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayer(
28 gfx::Rect(30, 30, 140, 140), SK_ColorTRANSPARENT);
29 background->AddChild(green);
30 background->AddChild(blur);
32 FilterOperations filters;
33 filters.Append(FilterOperation::CreateBlurFilter(2.f));
34 blur->SetBackgroundFilters(filters);
37 // Windows has 436 pixels off by 1: crbug.com/259915
38 float percentage_pixels_large_error = 1.09f; // 436px / (200*200)
39 float percentage_pixels_small_error = 0.0f;
40 float average_error_allowed_in_bad_pixels = 1.f;
41 int large_error_allowed = 1;
42 int small_error_allowed = 0;
43 pixel_comparator_.reset(new FuzzyPixelComparator(
44 true, // discard_alpha
45 percentage_pixels_large_error,
46 percentage_pixels_small_error,
47 average_error_allowed_in_bad_pixels,
49 small_error_allowed));
52 RunPixelTest(GL_WITH_BITMAP,
54 base::FilePath(FILE_PATH_LITERAL("background_filter_blur.png")));
57 TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) {
58 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
59 gfx::Rect(200, 200), SK_ColorWHITE);
61 // The green border is outside the layer with background blur, but the
62 // background blur should use pixels from outside its layer borders, up to the
63 // radius of the blur effect. So the border should be blurred underneath the
64 // top layer causing the green to bleed under the transparent layer, but not
65 // in the 1px region between the transparent layer and the green border.
66 scoped_refptr<SolidColorLayer> green_border = CreateSolidColorLayerWithBorder(
67 gfx::Rect(1, 1, 198, 198), SK_ColorWHITE, 10, kCSSGreen);
68 scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayer(
69 gfx::Rect(12, 12, 176, 176), SK_ColorTRANSPARENT);
70 background->AddChild(green_border);
71 background->AddChild(blur);
73 FilterOperations filters;
74 filters.Append(FilterOperation::CreateBlurFilter(5.f));
75 blur->SetBackgroundFilters(filters);
78 // Windows has 2596 pixels off by at most 2: crbug.com/259922
79 float percentage_pixels_large_error = 6.5f; // 2596px / (200*200), rounded up
80 float percentage_pixels_small_error = 0.0f;
81 float average_error_allowed_in_bad_pixels = 1.f;
82 int large_error_allowed = 2;
83 int small_error_allowed = 0;
84 pixel_comparator_.reset(new FuzzyPixelComparator(
85 true, // discard_alpha
86 percentage_pixels_large_error,
87 percentage_pixels_small_error,
88 average_error_allowed_in_bad_pixels,
90 small_error_allowed));
93 RunPixelTest(GL_WITH_BITMAP,
95 base::FilePath(FILE_PATH_LITERAL(
96 "background_filter_blur_outsets.png")));
99 TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
100 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
101 gfx::Rect(200, 200), SK_ColorWHITE);
103 // This verifies that the perspective of the clear layer (with black border)
104 // does not influence the blending of the green box behind it. Also verifies
105 // that the blur is correctly clipped inside the transformed clear layer.
106 scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
107 gfx::Rect(50, 50, 100, 100), kCSSGreen);
108 scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayerWithBorder(
109 gfx::Rect(30, 30, 120, 120), SK_ColorTRANSPARENT, 1, SK_ColorBLACK);
110 background->AddChild(green);
111 background->AddChild(blur);
113 background->SetShouldFlattenTransform(false);
114 background->SetIs3dSorted(true);
115 green->SetShouldFlattenTransform(false);
116 green->SetIs3dSorted(true);
117 gfx::Transform background_transform;
118 background_transform.ApplyPerspectiveDepth(200.0);
119 background->SetTransform(background_transform);
121 blur->SetShouldFlattenTransform(false);
122 blur->SetIs3dSorted(true);
123 for (size_t i = 0; i < blur->children().size(); ++i)
124 blur->children()[i]->SetIs3dSorted(true);
126 gfx::Transform blur_transform;
127 blur_transform.Translate(55.0, 65.0);
128 blur_transform.RotateAboutXAxis(85.0);
129 blur_transform.RotateAboutYAxis(180.0);
130 blur_transform.RotateAboutZAxis(20.0);
131 blur_transform.Translate(-60.0, -60.0);
132 blur->SetTransform(blur_transform);
134 FilterOperations filters;
135 filters.Append(FilterOperation::CreateBlurFilter(2.f));
136 blur->SetBackgroundFilters(filters);
139 // Windows has 153 pixels off by at most 2: crbug.com/225027
140 float percentage_pixels_large_error = 0.3825f; // 153px / (200*200)
141 float percentage_pixels_small_error = 0.0f;
142 float average_error_allowed_in_bad_pixels = 1.f;
143 int large_error_allowed = 2;
144 int small_error_allowed = 0;
145 pixel_comparator_.reset(new FuzzyPixelComparator(
146 true, // discard_alpha
147 percentage_pixels_large_error,
148 percentage_pixels_small_error,
149 average_error_allowed_in_bad_pixels,
151 small_error_allowed));
154 RunPixelTest(GL_WITH_BITMAP,
156 base::FilePath(FILE_PATH_LITERAL(
157 "background_filter_blur_off_axis.png")));
160 class ImageFilterClippedPixelTest : public LayerTreeHostFiltersPixelTest {
162 void RunPixelTestType(PixelTestType test_type) {
163 scoped_refptr<SolidColorLayer> root =
164 CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorBLACK);
166 scoped_refptr<SolidColorLayer> background =
167 CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorYELLOW);
168 root->AddChild(background);
170 scoped_refptr<SolidColorLayer> foreground =
171 CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorRED);
172 background->AddChild(foreground);
175 memset(matrix, 0, 20 * sizeof(matrix[0]));
176 // This filter does a red-blue swap, so the foreground becomes blue.
177 matrix[2] = matrix[6] = matrix[10] = matrix[18] = SK_Scalar1;
178 skia::RefPtr<SkColorFilter> colorFilter(
179 skia::AdoptRef(new SkColorMatrixFilter(matrix)));
180 // We filter only the bottom 200x100 pixels of the foreground.
181 SkImageFilter::CropRect crop_rect(SkRect::MakeXYWH(0, 100, 200, 100));
182 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
183 SkColorFilterImageFilter::Create(colorFilter.get(), NULL, &crop_rect));
184 FilterOperations filters;
185 filters.Append(FilterOperation::CreateReferenceFilter(filter));
187 // Make the foreground layer's render surface be clipped by the background
189 background->SetMasksToBounds(true);
190 foreground->SetFilters(filters);
192 // Then we translate the foreground up by 100 pixels in Y, so the cropped
193 // region is moved to to the top. This ensures that the crop rect is being
194 // correctly transformed in skia by the amount of clipping that the
195 // compositor performs.
196 gfx::Transform transform;
197 transform.Translate(0.0, -100.0);
198 foreground->SetTransform(transform);
200 RunPixelTest(test_type,
202 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")));
206 TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_GL) {
207 RunPixelTestType(GL_WITH_BITMAP);
210 TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_Software) {
211 RunPixelTestType(SOFTWARE_WITH_BITMAP);