Update mojo sdk to rev cb6c5abfadfea0ca73dca466e2894554ac1ae144
[chromium-blink-merge.git] / cc / trees / layer_tree_host_pixeltest_filters.cc
blobdd3cf733144bbb033e56a8670b33d552c61dec02
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)
14 namespace cc {
15 namespace {
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);
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
52 RunPixelTest(PIXEL_TEST_GL,
53 background,
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);
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
93 RunPixelTest(
94 PIXEL_TEST_GL,
95 background,
96 base::FilePath(FILE_PATH_LITERAL("background_filter_blur_outsets.png")));
99 TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
100 scoped_refptr<SolidColorLayer> background =
101 CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorTRANSPARENT);
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->Set3dSortingContextId(1);
115 green->SetShouldFlattenTransform(false);
116 green->Set3dSortingContextId(1);
117 gfx::Transform background_transform;
118 background_transform.ApplyPerspectiveDepth(200.0);
119 background->SetTransform(background_transform);
121 blur->SetShouldFlattenTransform(false);
122 blur->Set3dSortingContextId(1);
123 for (size_t i = 0; i < blur->children().size(); ++i)
124 blur->children()[i]->Set3dSortingContextId(1);
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);
138 #if defined(OS_WIN)
139 // Windows has 116 pixels off by at most 2: crbug.com/225027
140 float percentage_pixels_large_error = 0.3f; // 116px / (200*200), rounded up
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
154 RunPixelTest(
155 PIXEL_TEST_GL,
156 background,
157 base::FilePath(FILE_PATH_LITERAL("background_filter_blur_off_axis.png")));
160 class LayerTreeHostFiltersScaledPixelTest
161 : public LayerTreeHostFiltersPixelTest {
162 void InitializeSettings(LayerTreeSettings* settings) override {
163 // Required so that device scale is inherited by content scale.
164 settings->layer_transforms_should_scale_layer_contents = true;
167 void SetupTree() override {
168 layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
169 LayerTreePixelTest::SetupTree();
172 protected:
173 void RunPixelTestType(int content_size,
174 float device_scale_factor,
175 PixelTestType test_type) {
176 int half_content = content_size / 2;
178 scoped_refptr<SolidColorLayer> root = CreateSolidColorLayer(
179 gfx::Rect(0, 0, content_size, content_size), SK_ColorWHITE);
181 scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
182 gfx::Rect(0, 0, content_size, content_size), SK_ColorGREEN);
183 root->AddChild(background);
185 // Add a blue layer that completely covers the green layer.
186 scoped_refptr<SolidColorLayer> foreground = CreateSolidColorLayer(
187 gfx::Rect(0, 0, content_size, content_size), SK_ColorBLUE);
188 background->AddChild(foreground);
190 // Add an alpha threshold filter to the blue layer which will filter out
191 // everything except the lower right corner.
192 FilterOperations filters;
193 SkRegion alpha_region;
194 alpha_region.setRect(
195 half_content, half_content, content_size, content_size);
196 filters.Append(
197 FilterOperation::CreateAlphaThresholdFilter(alpha_region, 1.f, 0.f));
198 foreground->SetFilters(filters);
200 device_scale_factor_ = device_scale_factor;
201 RunPixelTest(
202 test_type,
203 background,
204 base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
207 float device_scale_factor_;
210 TEST_F(LayerTreeHostFiltersScaledPixelTest, StandardDpi_GL) {
211 RunPixelTestType(100, 1.f, PIXEL_TEST_GL);
214 TEST_F(LayerTreeHostFiltersScaledPixelTest, StandardDpi_Software) {
215 RunPixelTestType(100, 1.f, PIXEL_TEST_SOFTWARE);
218 TEST_F(LayerTreeHostFiltersScaledPixelTest, HiDpi_GL) {
219 RunPixelTestType(50, 2.f, PIXEL_TEST_GL);
222 TEST_F(LayerTreeHostFiltersScaledPixelTest, HiDpi_Software) {
223 RunPixelTestType(50, 2.f, PIXEL_TEST_SOFTWARE);
226 class ImageFilterClippedPixelTest : public LayerTreeHostFiltersPixelTest {
227 protected:
228 void RunPixelTestType(PixelTestType test_type) {
229 scoped_refptr<SolidColorLayer> root =
230 CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorBLACK);
232 scoped_refptr<SolidColorLayer> background =
233 CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorYELLOW);
234 root->AddChild(background);
236 scoped_refptr<SolidColorLayer> foreground =
237 CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorRED);
238 background->AddChild(foreground);
240 SkScalar matrix[20];
241 memset(matrix, 0, 20 * sizeof(matrix[0]));
242 // This filter does a red-blue swap, so the foreground becomes blue.
243 matrix[2] = matrix[6] = matrix[10] = matrix[18] = SK_Scalar1;
244 skia::RefPtr<SkColorFilter> colorFilter(
245 skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
246 // We filter only the bottom 200x100 pixels of the foreground.
247 SkImageFilter::CropRect crop_rect(SkRect::MakeXYWH(0, 100, 200, 100));
248 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
249 SkColorFilterImageFilter::Create(colorFilter.get(), NULL, &crop_rect));
250 FilterOperations filters;
251 filters.Append(FilterOperation::CreateReferenceFilter(filter));
253 // Make the foreground layer's render surface be clipped by the background
254 // layer.
255 background->SetMasksToBounds(true);
256 foreground->SetFilters(filters);
258 // Then we translate the foreground up by 100 pixels in Y, so the cropped
259 // region is moved to to the top. This ensures that the crop rect is being
260 // correctly transformed in skia by the amount of clipping that the
261 // compositor performs.
262 gfx::Transform transform;
263 transform.Translate(0.0, -100.0);
264 foreground->SetTransform(transform);
266 RunPixelTest(test_type,
267 background,
268 base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")));
272 TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_GL) {
273 RunPixelTestType(PIXEL_TEST_GL);
276 TEST_F(ImageFilterClippedPixelTest, ImageFilterClipped_Software) {
277 RunPixelTestType(PIXEL_TEST_SOFTWARE);
280 TEST_F(LayerTreeHostFiltersPixelTest, ImageFilterScaled_GL) {
281 scoped_refptr<SolidColorLayer> background =
282 CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
284 gfx::Rect rect(50, 50, 100, 100);
286 const int kInset = 3;
287 for (int i = 0; !rect.IsEmpty(); ++i) {
288 scoped_refptr<SolidColorLayer> layer =
289 CreateSolidColorLayer(rect, (i & 1) ? SK_ColorWHITE : SK_ColorRED);
291 gfx::Transform transform;
292 transform.Translate(rect.width() / 2.0, rect.height() / 2.0);
293 transform.RotateAboutZAxis(30.0);
294 transform.Translate(-rect.width() / 2.0, -rect.height() / 2.0);
295 layer->SetTransform(transform);
297 background->AddChild(layer);
299 rect.Inset(kInset, kInset);
302 scoped_refptr<SolidColorLayer> filter =
303 CreateSolidColorLayer(gfx::Rect(100, 0, 100, 200), SK_ColorTRANSPARENT);
305 background->AddChild(filter);
307 // Apply a scale to |background| so that we can see any scaling artifacts that
308 // may appear.
309 gfx::Transform background_transform;
310 static float scale = 1.1f;
311 background_transform.Scale(scale, scale);
312 background->SetTransform(background_transform);
314 FilterOperations filters;
315 filters.Append(FilterOperation::CreateGrayscaleFilter(1.0f));
316 filter->SetBackgroundFilters(filters);
318 #if defined(OS_WIN)
319 // Windows has 153 pixels off by at most 2: crbug.com/225027
320 float percentage_pixels_large_error = 0.3825f; // 153px / (200*200)
321 float percentage_pixels_small_error = 0.0f;
322 float average_error_allowed_in_bad_pixels = 1.f;
323 int large_error_allowed = 2;
324 int small_error_allowed = 0;
325 pixel_comparator_.reset(new FuzzyPixelComparator(
326 true, // discard_alpha
327 percentage_pixels_large_error, percentage_pixels_small_error,
328 average_error_allowed_in_bad_pixels, large_error_allowed,
329 small_error_allowed));
330 #endif
332 // TODO(hendrikw): Enable test in software as well: crbug.com/432157
333 RunPixelTest(PIXEL_TEST_GL, background,
334 base::FilePath(FILE_PATH_LITERAL("filter_on_scaled_layer.png")));
337 class ImageScaledRenderSurface : public LayerTreeHostFiltersPixelTest {
338 protected:
339 void RunPixelTestType(PixelTestType test_type, base::FilePath image_name) {
340 // A filter will cause a render surface to be used. Here we force the
341 // render surface on, and scale the result to make sure that we rasterize at
342 // the correct resolution.
343 scoped_refptr<SolidColorLayer> background =
344 CreateSolidColorLayer(gfx::Rect(300, 300), SK_ColorBLUE);
346 scoped_refptr<SolidColorLayer> render_surface_layer =
347 CreateSolidColorLayer(gfx::Rect(0, 0, 200, 200), SK_ColorWHITE);
349 gfx::Rect rect(50, 50, 100, 100);
351 scoped_refptr<SolidColorLayer> child =
352 CreateSolidColorLayer(rect, SK_ColorRED);
354 gfx::Transform transform;
355 transform.Translate(rect.width() / 2.0, rect.height() / 2.0);
356 transform.RotateAboutZAxis(30.0);
357 transform.Translate(-rect.width() / 2.0, -rect.height() / 2.0);
358 child->SetTransform(transform);
360 render_surface_layer->AddChild(child);
362 gfx::Transform render_surface_transform;
363 render_surface_transform.Scale(1.5f, 1.5f);
364 render_surface_layer->SetTransform(render_surface_transform);
365 render_surface_layer->SetForceRenderSurface(true);
367 background->AddChild(render_surface_layer);
369 // Software has some huge differences in the AA'd pixels on the different
370 // trybots. See crbug.com/452198.
371 float percentage_pixels_large_error = 0.686f;
372 float percentage_pixels_small_error = 0.0f;
373 float average_error_allowed_in_bad_pixels = 16.f;
374 int large_error_allowed = 17;
375 int small_error_allowed = 0;
376 pixel_comparator_.reset(new FuzzyPixelComparator(
377 true, // discard_alpha
378 percentage_pixels_large_error, percentage_pixels_small_error,
379 average_error_allowed_in_bad_pixels, large_error_allowed,
380 small_error_allowed));
382 RunPixelTest(test_type, background, image_name);
386 TEST_F(ImageScaledRenderSurface, ImageRenderSurfaceScaled_GL) {
387 RunPixelTestType(
388 PIXEL_TEST_GL,
389 base::FilePath(FILE_PATH_LITERAL("scaled_render_surface_layer_gl.png")));
392 TEST_F(ImageScaledRenderSurface, ImageRenderSurfaceScaled_Software) {
393 RunPixelTestType(
394 PIXEL_TEST_SOFTWARE,
395 base::FilePath(FILE_PATH_LITERAL("scaled_render_surface_layer_sw.png")));
398 class EnlargedTextureWithAlphaThresholdFilter
399 : public LayerTreeHostFiltersPixelTest {
400 protected:
401 void RunPixelTestType(PixelTestType test_type, base::FilePath image_name) {
402 // Rectangles choosen so that if flipped, the test will fail.
403 gfx::Rect rect1(10, 10, 10, 15);
404 gfx::Rect rect2(20, 25, 70, 65);
406 scoped_refptr<SolidColorLayer> child1 =
407 CreateSolidColorLayer(rect1, SK_ColorRED);
408 scoped_refptr<SolidColorLayer> child2 =
409 CreateSolidColorLayer(rect2, SK_ColorGREEN);
410 scoped_refptr<SolidColorLayer> background =
411 CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorBLUE);
412 scoped_refptr<SolidColorLayer> filter_layer =
413 CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);
415 // Make sure a transformation does not cause misregistration of the filter
416 // and source texture.
417 gfx::Transform filter_transform;
418 filter_transform.Scale(2.f, 2.f);
419 filter_layer->SetTransform(filter_transform);
420 filter_layer->AddChild(child1);
421 filter_layer->AddChild(child2);
423 rect1.Inset(-5, -5);
424 rect2.Inset(-5, -5);
425 SkRegion alpha_region;
426 SkIRect rects[2] = {gfx::RectToSkIRect(rect1), gfx::RectToSkIRect(rect2)};
427 alpha_region.setRects(rects, 2);
428 FilterOperations filters;
429 filters.Append(
430 FilterOperation::CreateAlphaThresholdFilter(alpha_region, 0.f, 0.f));
431 filter_layer->SetFilters(filters);
433 background->AddChild(filter_layer);
435 // Force the allocation a larger textures.
436 set_enlarge_texture_amount(gfx::Vector2d(50, 50));
438 RunPixelTest(test_type, background, image_name);
442 TEST_F(EnlargedTextureWithAlphaThresholdFilter, GL) {
443 RunPixelTestType(
444 PIXEL_TEST_GL,
445 base::FilePath(FILE_PATH_LITERAL("enlarged_texture_on_threshold.png")));
448 TEST_F(EnlargedTextureWithAlphaThresholdFilter, Software) {
449 RunPixelTestType(
450 PIXEL_TEST_SOFTWARE,
451 base::FilePath(FILE_PATH_LITERAL("enlarged_texture_on_threshold.png")));
454 } // namespace
455 } // namespace cc
457 #endif // OS_ANDROID