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