3d52efaedbb518b9cf4065800ac78313bc56e11f
[platform/framework/web/crosswalk.git] / src / cc / trees / layer_tree_host_pixeltest_filters.cc
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.
4
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"
11
12 #if !defined(OS_ANDROID)
13
14 namespace cc {
15 namespace {
16
17 class LayerTreeHostFiltersPixelTest : public LayerTreePixelTest {};
18
19 TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) {
20   scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
21       gfx::Rect(200, 200), SK_ColorWHITE);
22
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);
31
32   FilterOperations filters;
33   filters.Append(FilterOperation::CreateBlurFilter(2.f));
34   blur->SetBackgroundFilters(filters);
35
36 #if defined(OS_WIN)
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,
48       large_error_allowed,
49       small_error_allowed));
50 #endif
51
52   RunPixelTest(GL_WITH_BITMAP,
53                background,
54                base::FilePath(FILE_PATH_LITERAL("background_filter_blur.png")));
55 }
56
57 TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) {
58   scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
59       gfx::Rect(200, 200), SK_ColorWHITE);
60
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);
72
73   FilterOperations filters;
74   filters.Append(FilterOperation::CreateBlurFilter(5.f));
75   blur->SetBackgroundFilters(filters);
76
77 #if defined(OS_WIN)
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,
89       large_error_allowed,
90       small_error_allowed));
91 #endif
92
93   RunPixelTest(GL_WITH_BITMAP,
94                background,
95                base::FilePath(FILE_PATH_LITERAL(
96                    "background_filter_blur_outsets.png")));
97 }
98
99 TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
100   scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
101       gfx::Rect(200, 200), SK_ColorWHITE);
102
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);
112
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);
120
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);
125
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);
133
134   FilterOperations filters;
135   filters.Append(FilterOperation::CreateBlurFilter(2.f));
136   blur->SetBackgroundFilters(filters);
137
138 #if defined(OS_WIN)
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,
150       large_error_allowed,
151       small_error_allowed));
152 #endif
153
154   RunPixelTest(GL_WITH_BITMAP,
155                background,
156                base::FilePath(FILE_PATH_LITERAL(
157                    "background_filter_blur_off_axis.png")));
158 }
159
160 class ImageFilterClippedPixelTest : public LayerTreeHostFiltersPixelTest {
161  protected:
162   void RunPixelTestType(PixelTestType test_type) {
163     scoped_refptr<SolidColorLayer> root =
164         CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorBLACK);
165
166     scoped_refptr<SolidColorLayer> background =
167         CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorYELLOW);
168     root->AddChild(background);
169
170     scoped_refptr<SolidColorLayer> foreground =
171         CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorRED);
172     background->AddChild(foreground);
173
174     SkScalar matrix[20];
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));
186
187     // Make the foreground layer's render surface be clipped by the background
188     // layer.
189     background->SetMasksToBounds(true);
190     foreground->SetFilters(filters);
191
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);
199
200     RunPixelTest(test_type,
201                  background,
202                  base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")));
203   }
204 };
205
206 TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_GL) {
207   RunPixelTestType(GL_WITH_BITMAP);
208 }
209
210 TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_Software) {
211   RunPixelTestType(SOFTWARE_WITH_BITMAP);
212 }
213
214 }  // namespace
215 }  // namespace cc
216
217 #endif  // OS_ANDROID