12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "build/build_config.h"
6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "cc/layers/solid_color_layer.h"
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/layer_tree_pixel_test.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "cc/test/pixel_comparator.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass LayerTreeHostFiltersPixelTest : public LayerTreePixelTest {};
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlur) {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(200, 200), SK_ColorWHITE);
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The green box is entirely behind a layer with background blur, so it
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // should appear blurred on its edges.
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(50, 50, 100, 100), kCSSGreen);
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayer(
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::Rect(30, 30, 140, 140), SK_ColorTRANSPARENT);
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  background->AddChild(green);
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  background->AddChild(blur);
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FilterOperations filters;
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  filters.Append(FilterOperation::CreateBlurFilter(2.f));
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  blur->SetBackgroundFilters(filters);
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_WIN)
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Windows has 436 pixels off by 1: crbug.com/259915
367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  float percentage_pixels_large_error = 1.09f;  // 436px / (200*200)
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  float percentage_pixels_small_error = 0.0f;
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  float average_error_allowed_in_bad_pixels = 1.f;
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int large_error_allowed = 1;
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int small_error_allowed = 0;
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  pixel_comparator_.reset(new FuzzyPixelComparator(
427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      true,  // discard_alpha
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      percentage_pixels_large_error,
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      percentage_pixels_small_error,
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      average_error_allowed_in_bad_pixels,
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      large_error_allowed,
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      small_error_allowed));
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RunPixelTest(GL_WITH_BITMAP,
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch               background,
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch               base::FilePath(FILE_PATH_LITERAL("background_filter_blur.png")));
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
55bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(LayerTreeHostFiltersPixelTest, DISABLED_BackgroundFilterBlurOutsets) {
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(200, 200), SK_ColorWHITE);
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The green border is outside the layer with background blur, but the
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // background blur should use pixels from outside its layer borders, up to the
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // radius of the blur effect. So the border should be blurred underneath the
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // top layer causing the green to bleed under the transparent layer, but not
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // in the 1px region between the transparent layer and the green border.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<SolidColorLayer> green_border = CreateSolidColorLayerWithBorder(
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(1, 1, 198, 198), SK_ColorWHITE, 10, kCSSGreen);
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayer(
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(12, 12, 176, 176), SK_ColorTRANSPARENT);
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  background->AddChild(green_border);
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  background->AddChild(blur);
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FilterOperations filters;
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  filters.Append(FilterOperation::CreateBlurFilter(5.f));
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blur->SetBackgroundFilters(filters);
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_WIN)
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Windows has 2250 pixels off by at most 2: crbug.com/259922
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  float percentage_pixels_large_error = 5.625f;  // 2250px / (200*200)
787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  float percentage_pixels_small_error = 0.0f;
797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  float average_error_allowed_in_bad_pixels = 1.f;
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int large_error_allowed = 2;
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int small_error_allowed = 0;
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  pixel_comparator_.reset(new FuzzyPixelComparator(
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      true,  // discard_alpha
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      percentage_pixels_large_error,
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      percentage_pixels_small_error,
867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      average_error_allowed_in_bad_pixels,
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      large_error_allowed,
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      small_error_allowed));
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RunPixelTest(GL_WITH_BITMAP,
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch               background,
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               base::FilePath(FILE_PATH_LITERAL(
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   "background_filter_blur_outsets.png")));
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOffAxis) {
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(200, 200), SK_ColorWHITE);
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This verifies that the perspective of the clear layer (with black border)
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // does not influence the blending of the green box behind it. Also verifies
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // that the blur is correctly clipped inside the transformed clear layer.
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(50, 50, 100, 100), kCSSGreen);
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayerWithBorder(
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gfx::Rect(30, 30, 120, 120), SK_ColorTRANSPARENT, 1, SK_ColorBLACK);
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  background->AddChild(green);
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  background->AddChild(blur);
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  background->SetPreserves3d(true);
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Transform background_transform;
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  background_transform.ApplyPerspectiveDepth(200.0);
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  background->SetTransform(background_transform);
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blur->SetPreserves3d(true);
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Transform blur_transform;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blur_transform.Translate(55.0, 65.0);
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blur_transform.RotateAboutXAxis(85.0);
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blur_transform.RotateAboutYAxis(180.0);
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blur_transform.RotateAboutZAxis(20.0);
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blur_transform.Translate(-60.0, -60.0);
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blur->SetTransform(blur_transform);
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  FilterOperations filters;
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  filters.Append(FilterOperation::CreateBlurFilter(2.f));
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  blur->SetBackgroundFilters(filters);
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN)
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Windows has 151 pixels off by at most 2: crbug.com/225027
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  float percentage_pixels_large_error = 0.3775f;  // 151px / (200*200)
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  float percentage_pixels_small_error = 0.0f;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  float average_error_allowed_in_bad_pixels = 1.f;
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int large_error_allowed = 2;
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int small_error_allowed = 0;
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  pixel_comparator_.reset(new FuzzyPixelComparator(
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,  // discard_alpha
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      percentage_pixels_large_error,
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      percentage_pixels_small_error,
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      average_error_allowed_in_bad_pixels,
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      large_error_allowed,
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      small_error_allowed));
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RunPixelTest(GL_WITH_BITMAP,
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch               background,
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)               base::FilePath(FILE_PATH_LITERAL(
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   "background_filter_blur_off_axis.png")));
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // OS_ANDROID
155