1 /*
2  * Copyright 2021 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "gm/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkPaint.h"
11 #include "include/core/SkRect.h"
12 #include "include/effects/SkGradientShader.h"
13 #include "include/effects/SkImageFilters.h"
14 
draw_bg_blur(SkCanvas * canvas,SkIRect rect,float sigma)15 static void draw_bg_blur(SkCanvas* canvas, SkIRect rect, float sigma) {
16     // First create an intermediate layer that has an opaque area that we blur with transparency
17     // all around it. We want to make sure the transparency doesn't affect the blur of the opaque
18     // content.
19     auto outsetRect = SkRect::Make(rect).makeOutset(10, 10);
20     canvas->saveLayer(outsetRect, nullptr);
21     SkColor colors[] = {SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN};
22     float cx = (rect.left() + rect.right() )/2.f;
23     float cy = (rect.top()  + rect.bottom())/2.f;
24     auto g = SkGradientShader::MakeSweep(cx,
25                                          cy,
26                                          colors,
27                                          nullptr,
28                                          3,
29                                          SkTileMode::kMirror,
30                                          0,
31                                          45,
32                                          0,
33                                          nullptr);
34     SkPaint paint;
35     paint.setShader(std::move(g));
36     canvas->drawRect(SkRect::Make(rect), paint);
37     // Now do the bg-blur into another save-layer that should only read the opaque region.
38     SkCanvas::SaveLayerRec rec;
39     auto blur = SkImageFilters::Blur(sigma, sigma, SkTileMode::kClamp, nullptr, rect);
40     rec.fBounds = &outsetRect;
41     rec.fBackdrop = blur.get();
42     canvas->saveLayer(rec);
43     canvas->restore();
44     canvas->restore();
45 }
46 
47 DEF_SIMPLE_GM(crbug_1174354, canvas, 70, 250) {
48     // The initial fix for crbug.com/1156805 had an issue where the border added to the downsampled
49     // texture that was used as input to the blur could actually bring in transparency when there
50     // wasn't any within the original src bounds. It was populated the border using a filtering draw
51     // from the full res source that could read from outside the pixels surrounding the original src
52     // bounds.
53     draw_bg_blur(canvas, SkIRect::MakeXYWH(10,  10,  50, 50),  5);
54     draw_bg_blur(canvas, SkIRect::MakeXYWH(10,  70,  50, 50), 15);
55     draw_bg_blur(canvas, SkIRect::MakeXYWH(10, 130,  50, 50), 30);
56     draw_bg_blur(canvas, SkIRect::MakeXYWH(10, 190, 50, 50),  70);
57 }
58