blob: 8b137d665e6020a5afaf7df219fef1259f34f4fc [file] [log] [blame]
Brian Salomon702c5a32020-04-28 16:21:48 -04001/*
2 * Copyright 2020 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
10#include "include/effects/SkGradientShader.h"
Robert Phillips2f9dad42020-11-12 14:48:28 -050011#include "include/gpu/GrRecordingContext.h"
Brian Salomon702c5a32020-04-28 16:21:48 -040012#include "src/core/SkGpuBlurUtils.h"
Robert Phillips95c250c2020-06-29 15:36:12 -040013#include "src/gpu/GrRecordingContextPriv.h"
Brian Salomon702c5a32020-04-28 16:21:48 -040014#include "src/gpu/GrStyle.h"
15#include "src/gpu/SkGr.h"
John Stilesf743d4e2020-07-23 11:35:08 -040016#include "src/gpu/effects/GrBlendFragmentProcessor.h"
Robert Phillips550de7f2021-07-06 16:28:52 -040017#include "src/gpu/effects/GrTextureEffect.h"
Brian Salomon702c5a32020-04-28 16:21:48 -040018#include "src/image/SkImage_Base.h"
19
Robert Phillips95c250c2020-06-29 15:36:12 -040020static GrSurfaceProxyView blur(GrRecordingContext* ctx,
Brian Salomon11ad4cc2020-05-15 12:07:59 -040021 GrSurfaceProxyView src,
22 SkIRect dstB,
23 SkIRect srcB,
24 float sigmaX,
25 float sigmaY,
26 SkTileMode mode) {
Brian Salomonf9707462021-03-15 16:50:04 -040027 auto resultSDC = SkGpuBlurUtils::GaussianBlur(ctx,
28 src,
29 GrColorType::kRGBA_8888,
30 kPremul_SkAlphaType,
31 nullptr,
32 dstB,
33 srcB,
34 sigmaX,
35 sigmaY,
36 mode);
37 if (!resultSDC) {
Brian Salomon11ad4cc2020-05-15 12:07:59 -040038 return {};
39 }
Brian Salomonf9707462021-03-15 16:50:04 -040040 return resultSDC->readSurfaceView();
Brian Salomon11ad4cc2020-05-15 12:07:59 -040041};
42
Brian Salomonf9707462021-03-15 16:50:04 -040043// Performs tiling first of the src into dst bounds with a surrounding skirt so the blur can use
44// clamp. Does repeated blurs rather than invoking downsampling.
45static GrSurfaceProxyView slow_blur(GrRecordingContext* ctx,
46 GrSurfaceProxyView src,
47 SkIRect dstB,
48 SkIRect srcB,
49 float sigmaX,
50 float sigmaY,
51 SkTileMode mode) {
52 auto tileInto = [ctx](GrSurfaceProxyView src,
53 SkIRect srcTileRect,
54 SkISize resultSize,
55 SkIPoint offset,
56 SkTileMode mode) {
57 GrImageInfo info(GrColorType::kRGBA_8888, kPremul_SkAlphaType, nullptr, resultSize);
58 auto fc = GrSurfaceFillContext::Make(ctx, info);
59 if (!fc) {
60 return GrSurfaceProxyView{};
61 }
62 GrSamplerState sampler(SkTileModeToWrapMode(mode), SkFilterMode::kNearest);
63 auto fp = GrTextureEffect::MakeSubset(src,
64 kPremul_SkAlphaType,
65 SkMatrix::Translate(-offset.x(), -offset.y()),
66 sampler,
67 SkRect::Make(srcTileRect),
68 *ctx->priv().caps());
69 fc->fillWithFP(std::move(fp));
70 return fc->readSurfaceView();
71 };
Brian Salomon702c5a32020-04-28 16:21:48 -040072
Brian Salomonf9707462021-03-15 16:50:04 -040073 SkIPoint outset = {SkGpuBlurUtils::SigmaRadius(sigmaX), SkGpuBlurUtils::SigmaRadius(sigmaY)};
74 SkISize size = {dstB.width() + 2*outset.x(), dstB.height() + 2*outset.y()};
75 src = tileInto(std::move(src), srcB, size, outset - dstB.topLeft(), mode);
76 if (!src) {
77 return {};
Brian Salomon702c5a32020-04-28 16:21:48 -040078 }
Brian Salomonf9707462021-03-15 16:50:04 -040079 dstB = SkIRect::MakePtSize(outset, dstB.size());
80
81 while (sigmaX || sigmaY) {
82 float stepX = sigmaX;
83 if (stepX > SkGpuBlurUtils::kMaxSigma) {
84 stepX = SkGpuBlurUtils::kMaxSigma;
85 // A blur of sigma1 followed by a blur of sigma2 is equiv. to a single blur of
86 // sqrt(sigma1^2 + sigma2^2).
87 sigmaX = sqrt(sigmaX*sigmaX - SkGpuBlurUtils::kMaxSigma*SkGpuBlurUtils::kMaxSigma);
88 } else {
89 sigmaX = 0.f;
90 }
91 float stepY = sigmaY;
92 if (stepY > SkGpuBlurUtils::kMaxSigma) {
93 stepY = SkGpuBlurUtils::kMaxSigma;
94 sigmaY = sqrt(sigmaY*sigmaY- SkGpuBlurUtils::kMaxSigma*SkGpuBlurUtils::kMaxSigma);
95 } else {
96 sigmaY = 0.f;
97 }
98 auto bounds = SkIRect::MakeSize(src.dimensions());
99 auto sdc = SkGpuBlurUtils::GaussianBlur(ctx,
100 std::move(src),
101 GrColorType::kRGBA_8888,
102 kPremul_SkAlphaType,
103 nullptr,
104 bounds,
105 bounds,
106 stepX,
107 stepY,
108 SkTileMode::kClamp);
109 if (!sdc) {
110 return {};
111 }
112 src = sdc->readSurfaceView();
113 }
114 // We have o use the original mode here because we may have only blurred in X or Y and then
115 // the other dimension was not expanded.
116 auto srcRect = SkIRect::MakeSize(src.dimensions());
117 return tileInto(std::move(src), srcRect, dstB.size(), -outset, SkTileMode::kClamp);
118};
119
120// Makes a src texture for as a source for blurs. If 'contentArea' then the content will
121// be in that rect, the 1-pixel surrounding border will be transparent black, and red outside of
122// that. Otherwise, the content fills the dimensions.
123GrSurfaceProxyView make_src_image(GrRecordingContext* rContext,
124 SkISize dimensions,
125 const SkIRect* contentArea = nullptr) {
126 auto srcII = SkImageInfo::Make(dimensions, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
127 auto surf = SkSurface::MakeRenderTarget(rContext, SkBudgeted::kYes, srcII);
128 if (!surf) {
129 return {};
130 }
131
132 float w, h;
133 if (contentArea) {
134 surf->getCanvas()->clear(SK_ColorRED);
135 surf->getCanvas()->clipIRect(contentArea->makeOutset(1, 1));
136 surf->getCanvas()->clear(SK_ColorTRANSPARENT);
137 surf->getCanvas()->clipIRect(*contentArea);
138 surf->getCanvas()->translate(contentArea->top(), contentArea->left());
139 w = contentArea->width();
140 h = contentArea->height();
141 } else {
142 w = dimensions.width();
143 h = dimensions.height();
144 }
145
146 surf->getCanvas()->drawColor(SK_ColorDKGRAY);
147 SkPaint paint;
148 paint.setAntiAlias(true);
149 paint.setStyle(SkPaint::kStroke_Style);
150 // Draw four horizontal lines at 1/8, 1/4, 3/4, 7/8.
151 paint.setStrokeWidth(h/12.f);
152 paint.setColor(SK_ColorRED);
153 surf->getCanvas()->drawLine({0.f, 1.f*h/8.f}, {w, 1.f*h/8.f}, paint);
154 paint.setColor(/* sea foam */ 0xFF71EEB8);
155 surf->getCanvas()->drawLine({0.f, 1.f*h/4.f}, {w, 1.f*h/4.f}, paint);
156 paint.setColor(SK_ColorYELLOW);
157 surf->getCanvas()->drawLine({0.f, 3.f*h/4.f}, {w, 3.f*h/4.f}, paint);
158 paint.setColor(SK_ColorCYAN);
159 surf->getCanvas()->drawLine({0.f, 7.f*h/8.f}, {w, 7.f*h/8.f}, paint);
160
161 // Draw four vertical lines at 1/8, 1/4, 3/4, 7/8.
162 paint.setStrokeWidth(w/12.f);
163 paint.setColor(/* orange */ 0xFFFFA500);
164 surf->getCanvas()->drawLine({1.f*w/8.f, 0.f}, {1.f*h/8.f, h}, paint);
165 paint.setColor(SK_ColorBLUE);
166 surf->getCanvas()->drawLine({1.f*w/4.f, 0.f}, {1.f*h/4.f, h}, paint);
167 paint.setColor(SK_ColorMAGENTA);
168 surf->getCanvas()->drawLine({3.f*w/4.f, 0.f}, {3.f*h/4.f, h}, paint);
169 paint.setColor(SK_ColorGREEN);
170 surf->getCanvas()->drawLine({7.f*w/8.f, 0.f}, {7.f*h/8.f, h}, paint);
171
172 auto img = surf->makeImageSnapshot();
173 auto [src, ct] = as_IB(img)->asView(rContext, GrMipmapped::kNo);
174 return src;
175}
176
177static void run(GrRecordingContext* rContext, GrSurfaceDrawContext* sdc, bool subsetSrc, bool ref) {
178 GrSurfaceProxyView src = make_src_image(rContext, {60, 60});
Brian Salomon702c5a32020-04-28 16:21:48 -0400179 if (!src) {
180 return;
181 }
Brian Salomon702c5a32020-04-28 16:21:48 -0400182
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400183 SkIRect srcRect = SkIRect::MakeSize(src.dimensions());
184 if (subsetSrc) {
185 srcRect = SkIRect::MakeXYWH(2.f*srcRect.width() /8.f,
186 1.f*srcRect.height()/8.f,
187 5.f*srcRect.width() /8.f,
188 6.f*srcRect.height()/8.f);
189 }
190 int srcW = srcRect.width();
191 int srcH = srcRect.height();
192 // Each set of rects is drawn in one test area so they probably should not abut or overlap
193 // to visualize the blurs separately.
194 const std::vector<SkIRect> dstRectSets[] = {
Brian Salomon287d5982020-05-19 14:24:43 -0400195 // encloses source bounds.
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400196 {
197 srcRect.makeOutset(srcW/5, srcH/5)
198 },
Brian Salomon702c5a32020-04-28 16:21:48 -0400199
Brian Salomon287d5982020-05-19 14:24:43 -0400200 // partial overlap from above/below.
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400201 {
202 SkIRect::MakeXYWH(srcRect.x(), srcRect.y() + 3*srcH/4, srcW, srcH),
203 SkIRect::MakeXYWH(srcRect.x(), srcRect.y() - 3*srcH/4, srcW, srcH)
204 },
205
Brian Salomon287d5982020-05-19 14:24:43 -0400206 // adjacent to each side of src bounds.
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400207 {
208 srcRect.makeOffset( 0, srcH),
209 srcRect.makeOffset( srcW, 0),
210 srcRect.makeOffset( 0, -srcH),
211 srcRect.makeOffset(-srcW, 0),
212 },
213
Brian Salomon287d5982020-05-19 14:24:43 -0400214 // fully outside src bounds in one direction.
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400215 {
216 SkIRect::MakeXYWH(-6.f*srcW/8.f, -7.f*srcH/8.f, 4.f*srcW/8.f, 20.f*srcH/8.f)
217 .makeOffset(srcRect.topLeft()),
218 SkIRect::MakeXYWH(-1.f*srcW/8.f, -7.f*srcH/8.f, 16.f*srcW/8.f, 2.f*srcH/8.f)
219 .makeOffset(srcRect.topLeft()),
220 SkIRect::MakeXYWH(10.f*srcW/8.f, -3.f*srcH/8.f, 4.f*srcW/8.f, 16.f*srcH/8.f)
221 .makeOffset(srcRect.topLeft()),
222 SkIRect::MakeXYWH(-7.f*srcW/8.f, 14.f*srcH/8.f, 18.f*srcW/8.f, 1.f*srcH/8.f)
223 .makeOffset(srcRect.topLeft()),
224 },
Brian Salomon287d5982020-05-19 14:24:43 -0400225
226 // outside of src bounds in both directions.
227 {
228 SkIRect::MakeXYWH(-5.f*srcW/8.f, -5.f*srcH/8.f, 2.f*srcW/8.f, 2.f*srcH/8.f)
229 .makeOffset(srcRect.topLeft()),
230 SkIRect::MakeXYWH(-5.f*srcW/8.f, 12.f*srcH/8.f, 2.f*srcW/8.f, 2.f*srcH/8.f)
231 .makeOffset(srcRect.topLeft()),
232 SkIRect::MakeXYWH(12.f*srcW/8.f, -5.f*srcH/8.f, 2.f*srcW/8.f, 2.f*srcH/8.f)
233 .makeOffset(srcRect.topLeft()),
234 SkIRect::MakeXYWH(12.f*srcW/8.f, 12.f*srcH/8.f, 2.f*srcW/8.f, 2.f*srcH/8.f)
235 .makeOffset(srcRect.topLeft()),
236 },
Brian Salomon702c5a32020-04-28 16:21:48 -0400237 };
238
Robert Phillips2f9dad42020-11-12 14:48:28 -0500239 const auto& caps = *rContext->priv().caps();
Brian Salomon702c5a32020-04-28 16:21:48 -0400240
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400241 static constexpr SkScalar kPad = 10;
242 SkVector trans = {kPad, kPad};
243
Brian Salomonf9707462021-03-15 16:50:04 -0400244 sdc->clear(SK_PMColor4fWHITE);
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400245
246 SkIRect testArea = srcRect;
247 testArea.outset(testArea.width(), testArea.height());
248 for (const auto& dstRectSet : dstRectSets) {
249 for (int t = 0; t < kSkTileModeCount; ++t) {
250 auto mode = static_cast<SkTileMode>(t);
251 GrSamplerState sampler(SkTileModeToWrapMode(mode), GrSamplerState::Filter::kNearest);
Mike Reed1f607332020-05-21 12:11:27 -0400252 SkMatrix m = SkMatrix::Translate(trans.x() - testArea.x(), trans.y() - testArea.y());
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400253 // Draw the src subset in the tile mode faded as a reference before drawing the blur
254 // on top.
255 {
Brian Osmanf48f76e2020-07-15 16:04:17 -0400256 static constexpr float kAlpha = 0.2f;
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400257 auto fp = GrTextureEffect::MakeSubset(src, kPremul_SkAlphaType, SkMatrix::I(),
258 sampler, SkRect::Make(srcRect), caps);
Brian Osmanf48f76e2020-07-15 16:04:17 -0400259 fp = GrFragmentProcessor::ModulateRGBA(std::move(fp),
260 {kAlpha, kAlpha, kAlpha, kAlpha});
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400261 GrPaint paint;
John Stiles5933d7d2020-07-21 12:28:35 -0400262 paint.setColorFragmentProcessor(std::move(fp));
Brian Salomonf9707462021-03-15 16:50:04 -0400263 sdc->drawRect(nullptr, std::move(paint), GrAA::kNo, m, SkRect::Make(testArea));
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400264 }
265 // Do a blur for each dstRect in the set over our testArea-sized background.
266 for (const auto& dstRect : dstRectSet) {
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400267 const SkScalar sigmaX = src.width() / 10.f;
268 const SkScalar sigmaY = src.height() / 10.f;
Brian Salomonf9707462021-03-15 16:50:04 -0400269 auto blurFn = ref ? slow_blur : blur;
Brian Salomon702c5a32020-04-28 16:21:48 -0400270 // Blur using the rect and draw on top.
Brian Salomonf9707462021-03-15 16:50:04 -0400271 if (auto blurView = blurFn(rContext,
272 src,
273 dstRect,
274 srcRect,
275 sigmaX,
276 sigmaY,
277 mode)) {
278 auto fp = GrTextureEffect::Make(blurView,
279 kPremul_SkAlphaType,
280 SkMatrix::I(),
281 sampler,
282 caps);
283 // Compose against white (default paint color)
Brian Salomon4b6e2f02021-07-08 14:04:21 -0400284 fp = GrBlendFragmentProcessor::Make(std::move(fp),
285 /*dst=*/nullptr,
286 SkBlendMode::kSrcOver);
Brian Salomon702c5a32020-04-28 16:21:48 -0400287 GrPaint paint;
288 // Compose against white (default paint color) and then replace the dst
289 // (SkBlendMode::kSrc).
Brian Salomon4b6e2f02021-07-08 14:04:21 -0400290 fp = GrBlendFragmentProcessor::Make(std::move(fp),
291 /*dst=*/nullptr,
292 SkBlendMode::kSrcOver);
John Stiles5933d7d2020-07-21 12:28:35 -0400293 paint.setColorFragmentProcessor(std::move(fp));
Brian Salomon702c5a32020-04-28 16:21:48 -0400294 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
Brian Salomonf9707462021-03-15 16:50:04 -0400295 sdc->fillRectToRect(nullptr,
296 std::move(paint),
297 GrAA::kNo,
298 m,
299 SkRect::Make(dstRect),
300 SkRect::Make(blurView.dimensions()));
Brian Salomon702c5a32020-04-28 16:21:48 -0400301 }
Brian Salomon702c5a32020-04-28 16:21:48 -0400302 // Show the outline of the dst rect. Mostly for kDecal but also allows visual
303 // confirmation that the resulting blur is the right size and in the right place.
304 {
305 GrPaint paint;
306 static constexpr float kAlpha = 0.6f;
307 paint.setColor4f({0, kAlpha, 0, kAlpha});
308 SkPaint stroke;
309 stroke.setStyle(SkPaint::kStroke_Style);
310 stroke.setStrokeWidth(1.f);
311 GrStyle style(stroke);
312 auto dstR = SkRect::Make(dstRect).makeOutset(0.5f, 0.5f);
Brian Salomonf9707462021-03-15 16:50:04 -0400313 sdc->drawRect(nullptr, std::move(paint), GrAA::kNo, m, dstR, &style);
Brian Salomon702c5a32020-04-28 16:21:48 -0400314 }
Brian Salomon702c5a32020-04-28 16:21:48 -0400315 }
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400316 // Show the rect that's being blurred.
317 {
318 GrPaint paint;
319 static constexpr float kAlpha = 0.3f;
320 paint.setColor4f({0, 0, 0, kAlpha});
321 SkPaint stroke;
322 stroke.setStyle(SkPaint::kStroke_Style);
323 stroke.setStrokeWidth(1.f);
324 GrStyle style(stroke);
325 auto srcR = SkRect::Make(srcRect).makeOutset(0.5f, 0.5f);
Brian Salomonf9707462021-03-15 16:50:04 -0400326 sdc->drawRect(nullptr, std::move(paint), GrAA::kNo, m, srcR, &style);
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400327 }
328 trans.fX += testArea.width() + kPad;
Brian Salomon702c5a32020-04-28 16:21:48 -0400329 }
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400330 trans.fX = kPad;
331 trans.fY += testArea.height() + kPad;
Brian Salomon702c5a32020-04-28 16:21:48 -0400332 }
333}
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400334
Brian Salomonf9707462021-03-15 16:50:04 -0400335DEF_SIMPLE_GPU_GM(gpu_blur_utils, ctx, sdc, canvas, 765, 955) { run(ctx, sdc, false, false); }
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400336
Brian Salomonf9707462021-03-15 16:50:04 -0400337DEF_SIMPLE_GPU_GM(gpu_blur_utils_ref, ctx, sdc, canvas, 765, 955) { run(ctx, sdc, false, true); }
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400338
Brian Salomonf9707462021-03-15 16:50:04 -0400339DEF_SIMPLE_GPU_GM(gpu_blur_utils_subset_rect, ctx, sdc, canvas, 485, 730) {
340 run(ctx, sdc, true, false);
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400341}
342
Brian Salomonf9707462021-03-15 16:50:04 -0400343DEF_SIMPLE_GPU_GM(gpu_blur_utils_subset_ref, ctx, sdc, canvas, 485, 730) {
344 run(ctx, sdc, true, true);
345}
346
347// Because of the way blur sigmas concat (sigTotal = sqrt(sig1^2 + sig2^2) generating these images
348// for very large sigmas is incredibly slow. This can be enabled while working on the blur code to
Brian Salomoned3c75b2021-03-23 09:22:00 -0400349// check results.
Brian Salomonf9707462021-03-15 16:50:04 -0400350static bool constexpr kShowSlowRefImages = false;
351
352static void do_very_large_blur_gm(GrSurfaceDrawContext* sdc,
353 GrRecordingContext* rContext,
354 GrSurfaceProxyView src,
355 SkIRect srcB) {
356 // Clear to a color other than gray to contrast with test image.
357 sdc->clear(SkColor4f{0.3f, 0.4f, 0.2f, 1});
358
359 int x = 10;
360 int y = 10;
361 for (auto blurDirs : {0b01, 0b10, 0b11}) {
362 for (int t = 0; t <= static_cast<int>(SkTileMode::kLastTileMode); ++t) {
363 auto tm = static_cast<SkTileMode>(t);
364 auto dstB = srcB.makeOutset(30, 30);
Brian Salomoned3c75b2021-03-23 09:22:00 -0400365 for (float sigma : {0.f, 5.f, 25.f, 80.f}) {
Brian Salomonf9707462021-03-15 16:50:04 -0400366 std::vector<decltype(blur)*> blurs;
367 blurs.push_back(blur);
368 if (kShowSlowRefImages) {
369 blurs.push_back(slow_blur);
370 }
371 for (auto b : blurs) {
372 float sigX = sigma*((blurDirs & 0b01) >> 0);
373 float sigY = sigma*((blurDirs & 0b10) >> 1);
374 GrSurfaceProxyView result = b(rContext, src, dstB, srcB, sigX, sigY, tm);
375 auto dstRect = SkIRect::MakeSize(dstB.size()).makeOffset(x, y);
376 // Draw a rect to show where the result should be so it's obvious if it's
377 // missing.
378 GrPaint paint;
379 paint.setColor4f(b == blur ? SkPMColor4f{0, 0, 1, 1} : SkPMColor4f{1, 0, 0, 1});
380 sdc->drawRect(nullptr,
381 std::move(paint),
382 GrAA::kNo,
383 SkMatrix::I(),
384 SkRect::Make(dstRect).makeOutset(0.5, 0.5),
385 &GrStyle::SimpleHairline());
386 if (result) {
387 std::unique_ptr<GrFragmentProcessor> fp =
388 GrTextureEffect::Make(std::move(result), kPremul_SkAlphaType);
Brian Salomon4b6e2f02021-07-08 14:04:21 -0400389 fp = GrBlendFragmentProcessor::Make(std::move(fp),
390 /*dst=*/nullptr,
391 SkBlendMode::kSrcOver);
Brian Salomonf9707462021-03-15 16:50:04 -0400392 sdc->fillRectToRectWithFP(SkIRect::MakeSize(dstB.size()),
393 dstRect,
394 std::move(fp));
395 }
396 x += dstB.width() + 10;
397 }
398 }
399 x = 10;
400 y += dstB.height() + 10;
401 }
402 }
403}
404
Brian Salomoned3c75b2021-03-23 09:22:00 -0400405DEF_SIMPLE_GPU_GM(very_large_sigma_gpu_blur, ctx, sdc, canvas, 350, 1030) {
406 auto src = make_src_image(ctx, {15, 15});
Brian Salomonf9707462021-03-15 16:50:04 -0400407 auto srcB = SkIRect::MakeSize(src.dimensions());
408 do_very_large_blur_gm(sdc, ctx, std::move(src), srcB);
409}
410
Brian Salomoned3c75b2021-03-23 09:22:00 -0400411DEF_SIMPLE_GPU_GM(very_large_sigma_gpu_blur_subset, ctx, sdc, canvas, 350, 1030) {
412 auto srcB = SkIRect::MakeXYWH(2, 2, 15, 15);
Brian Salomonf9707462021-03-15 16:50:04 -0400413 SkISize imageSize = SkISize{srcB.width() + 4, srcB.height() + 4};
414 auto src = make_src_image(ctx, imageSize, &srcB);
415 do_very_large_blur_gm(sdc, ctx, std::move(src), srcB);
416}
417
418DEF_SIMPLE_GPU_GM(very_large_sigma_gpu_blur_subset_transparent_border,
419 ctx,
420 sdc,
421 canvas,
Brian Salomoned3c75b2021-03-23 09:22:00 -0400422 355, 1055) {
423 auto srcB = SkIRect::MakeXYWH(3, 3, 15, 15);
Brian Salomonf9707462021-03-15 16:50:04 -0400424 SkISize imageSize = SkISize{srcB.width() + 4, srcB.height() + 4};
425 auto src = make_src_image(ctx, imageSize, &srcB);
426 do_very_large_blur_gm(sdc, ctx, std::move(src), srcB.makeOutset(1, 1));
Brian Salomon11ad4cc2020-05-15 12:07:59 -0400427}