Flutter Engine
The Flutter Engine
BlurTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 Google Inc.
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
18#include "include/core/SkPath.h"
23#include "include/core/SkRect.h"
26#include "include/core/SkSize.h"
35#include "src/base/SkMathPriv.h"
36#include "src/core/SkBlurMask.h"
37#include "src/core/SkMask.h"
42#include "tests/Test.h"
43#include "tools/ToolUtils.h"
44
45#include <math.h>
46#include <string.h>
47#include <array>
48#include <cstddef>
49#include <cstdint>
50#include <initializer_list>
51
52struct GrContextOptions;
53
54#define WRITE_CSV 0
55
56///////////////////////////////////////////////////////////////////////////////
57
58static const int outset = 100;
60static const int strokeWidth = 4;
61
62static void create(SkBitmap* bm, const SkIRect& bound) {
63 bm->allocN32Pixels(bound.width(), bound.height());
64}
65
66static void drawBG(SkCanvas* canvas) {
67 canvas->drawColor(bgColor);
68}
69
70
71struct BlurTest {
72 void (*addPath)(SkPath*);
75};
76
77//Path Draw Procs
78//Beware that paths themselves my draw differently depending on the clip.
79static void draw50x50Rect(SkPath* path) {
80 path->addRect(0, 0, SkIntToScalar(50), SkIntToScalar(50));
81}
82
83//Tests
84static BlurTest tests[] = {
85 { draw50x50Rect, 3, {
86 //inner half of blur
87 { 0, 0, 50, 50 },
88 //blur, but no path.
89 { 50 + strokeWidth/2, 50 + strokeWidth/2, 100, 100 },
90 //just an edge
91 { 40, strokeWidth, 60, 50 - strokeWidth },
92 }},
93};
94
95/** Assumes that the ref draw was completely inside ref canvas --
96 implies that everything outside is "bgColor".
97 Checks that all overlap is the same and that all non-overlap on the
98 ref is "bgColor".
99 */
100static bool compare(const SkBitmap& ref, const SkIRect& iref,
101 const SkBitmap& test, const SkIRect& itest)
102{
103 const int xOff = itest.fLeft - iref.fLeft;
104 const int yOff = itest.fTop - iref.fTop;
105
106 for (int y = 0; y < test.height(); ++y) {
107 for (int x = 0; x < test.width(); ++x) {
108 SkColor testColor = test.getColor(x, y);
109 int refX = x + xOff;
110 int refY = y + yOff;
111 SkColor refColor;
112 if (refX >= 0 && refX < ref.width() &&
113 refY >= 0 && refY < ref.height())
114 {
115 refColor = ref.getColor(refX, refY);
116 } else {
117 refColor = bgColor;
118 }
119 if (refColor != testColor) {
120 return false;
121 }
122 }
123 }
124 return true;
125}
126
127DEF_TEST(BlurDrawing, reporter) {
129 paint.setColor(SK_ColorGRAY);
131 paint.setStrokeWidth(SkIntToScalar(strokeWidth));
132
134 for (int style = 0; style <= kLastEnum_SkBlurStyle; ++style) {
135 SkBlurStyle blurStyle = static_cast<SkBlurStyle>(style);
136
137 for (bool respectCTM : { false, true }) {
138 paint.setMaskFilter(SkMaskFilter::MakeBlur(blurStyle, sigma, respectCTM));
139
140 for (size_t test = 0; test < std::size(tests); ++test) {
141 SkPath path;
143 SkPath strokedPath;
145 SkRect refBound = strokedPath.getBounds();
146 SkIRect iref;
147 refBound.roundOut(&iref);
148 iref.inset(-outset, -outset);
149 SkBitmap refBitmap;
150 create(&refBitmap, iref);
151
152 SkCanvas refCanvas(refBitmap);
153 refCanvas.translate(SkIntToScalar(-iref.fLeft),
154 SkIntToScalar(-iref.fTop));
155 drawBG(&refCanvas);
156 refCanvas.drawPath(path, paint);
157
158 for (int view = 0; view < tests[test].viewLen; ++view) {
159 SkIRect itest = tests[test].views[view];
160 SkBitmap testBitmap;
161 create(&testBitmap, itest);
162
163 SkCanvas testCanvas(testBitmap);
164 testCanvas.translate(SkIntToScalar(-itest.fLeft),
165 SkIntToScalar(-itest.fTop));
166 drawBG(&testCanvas);
167 testCanvas.drawPath(path, paint);
168
170 compare(refBitmap, iref, testBitmap, itest));
171 }
172 }
173 }
174 }
175}
176
177///////////////////////////////////////////////////////////////////////////////
178
179// Use SkBlurMask::BlurGroundTruth to blur a 'width' x 'height' solid
180// white rect. Return the right half of the middle row in 'result'.
181static void ground_truth_2d(int width, int height,
182 SkScalar sigma,
183 int* result, int resultCount) {
185
186 src.bounds().setWH(width, height);
187 src.format() = SkMask::kA8_Format;
188 src.rowBytes() = src.fBounds.width();
189 src.image() = SkMaskBuilder::AllocImage(src.computeTotalImageSize());
190
191 memset(src.image(), 0xff, src.computeTotalImageSize());
192
194 return;
195 }
196
197 int midX = dst.fBounds.x() + dst.fBounds.width()/2;
198 int midY = dst.fBounds.y() + dst.fBounds.height()/2;
199 uint8_t* bytes = dst.getAddr8(midX, midY);
200 int i;
201 for (i = 0; i < dst.fBounds.width()-(midX-dst.fBounds.fLeft); ++i) {
202 if (i < resultCount) {
203 result[i] = bytes[i];
204 }
205 }
206 for ( ; i < resultCount; ++i) {
207 result[i] = 0;
208 }
209
212}
213
214// Implement a step function that is 255 between min and max; 0 elsewhere.
215static int step(int x, SkScalar min, SkScalar max) {
216 if (min < x && x < max) {
217 return 255;
218 }
219 return 0;
220}
221
222// Implement a Gaussian function with 0 mean and std.dev. of 'sigma'.
223static float gaussian(int x, SkScalar sigma) {
224 float k = SK_Scalar1/(sigma * sqrtf(2.0f*SK_ScalarPI));
225 float exponent = -(x * x) / (2 * sigma * sigma);
226 return k * expf(exponent);
227}
228
229// Perform a brute force convolution of a step function with a Gaussian.
230// Return the right half in 'result'
231static void brute_force_1d(SkScalar stepMin, SkScalar stepMax,
232 SkScalar gaussianSigma,
233 int* result, int resultCount) {
234
235 int gaussianRange = SkScalarCeilToInt(10 * gaussianSigma);
236
237 for (int i = 0; i < resultCount; ++i) {
238 SkScalar sum = 0.0f;
239 for (int j = -gaussianRange; j < gaussianRange; ++j) {
240 sum += gaussian(j, gaussianSigma) * step(i-j, stepMin, stepMax);
241 }
242
243 result[i] = SkTPin(SkClampPos(int(sum + 0.5f)), 0, 255);
244 }
245}
246
247static void blur_path(SkCanvas* canvas, const SkPath& path,
248 SkScalar gaussianSigma) {
249
250 SkScalar midX = path.getBounds().centerX();
251 SkScalar midY = path.getBounds().centerY();
252
253 canvas->translate(-midX, -midY);
254
255 SkPaint blurPaint;
256 blurPaint.setColor(SK_ColorWHITE);
258
259 canvas->drawColor(SK_ColorBLACK);
260 canvas->drawPath(path, blurPaint);
261}
262
263// Readback the blurred draw results from the canvas
264static void readback(const SkBitmap& src, int* result, int resultCount) {
266 readback.allocN32Pixels(resultCount, 30);
267 SkPixmap pm;
268 readback.peekPixels(&pm);
269 src.readPixels(pm, 0, 0);
270
271 const SkPMColor* pixels = pm.addr32(0, 15);
272
273 for (int i = 0; i < resultCount; ++i) {
274 result[i] = SkColorGetR(pixels[i]);
275 }
276}
277
278// Draw a blurred version of the provided path.
279// Return the right half of the middle row in 'result'.
280static void cpu_blur_path(const SkPath& path, SkScalar gaussianSigma,
281 int* result, int resultCount) {
282
284 bitmap.allocN32Pixels(resultCount, 30);
285 SkCanvas canvas(bitmap);
286
287 blur_path(&canvas, path, gaussianSigma);
288 readback(bitmap, result, resultCount);
289}
290
291#if WRITE_CSV
292static void write_as_csv(const char* label, SkScalar scale, int* data, int count) {
293 SkDebugf("%s_%.2f,", label, scale);
294 for (int i = 0; i < count-1; ++i) {
295 SkDebugf("%d,", data[i]);
296 }
297 SkDebugf("%d\n", data[count-1]);
298}
299#endif
300
301static bool match(int* first, int* second, int count, int tol) {
302 int delta;
303 for (int i = 0; i < count; ++i) {
304 delta = first[i] - second[i];
305 if (delta > tol || delta < -tol) {
306 return false;
307 }
308 }
309
310 return true;
311}
312
313// Test out the normal blur style with a wide range of sigmas
314DEF_TEST(BlurSigmaRange, reporter) {
315 static const int kSize = 100;
316
317 // The geometry is offset a smidge to trigger:
318 // https://code.google.com/p/chromium/issues/detail?id=282418
319 SkPath rectPath;
320 rectPath.addRect(0.3f, 0.3f, 100.3f, 100.3f);
321
322 SkPoint polyPts[] = {
323 { 0.3f, 0.3f },
324 { 100.3f, 0.3f },
325 { 100.3f, 100.3f },
326 { 0.3f, 100.3f },
327 { 2.3f, 50.3f } // a little divet to throw off the rect special case
328 };
329 SkPath polyPath;
330 polyPath.addPoly(polyPts, std::size(polyPts), true);
331
332 int rectSpecialCaseResult[kSize];
333 int generalCaseResult[kSize];
334 int groundTruthResult[kSize];
335 int bruteForce1DResult[kSize];
336
337 SkScalar sigma = 10.0f;
338
339 for (int i = 0; i < 4; ++i, sigma /= 10) {
340
341 cpu_blur_path(rectPath, sigma, rectSpecialCaseResult, kSize);
342 cpu_blur_path(polyPath, sigma, generalCaseResult, kSize);
343
344 ground_truth_2d(100, 100, sigma, groundTruthResult, kSize);
345 brute_force_1d(-50.0f, 50.0f, sigma, bruteForce1DResult, kSize);
346
347 REPORTER_ASSERT(reporter, match(rectSpecialCaseResult, bruteForce1DResult, kSize, 5));
348 REPORTER_ASSERT(reporter, match(generalCaseResult, bruteForce1DResult, kSize, 15));
349 REPORTER_ASSERT(reporter, match(groundTruthResult, bruteForce1DResult, kSize, 1));
350
351#if WRITE_CSV
352 write_as_csv("RectSpecialCase", sigma, rectSpecialCaseResult, kSize);
353 write_as_csv("GeneralCase", sigma, generalCaseResult, kSize);
354 write_as_csv("GPU", sigma, gpuResult, kSize);
355 write_as_csv("GroundTruth2D", sigma, groundTruthResult, kSize);
356 write_as_csv("BruteForce1D", sigma, bruteForce1DResult, kSize);
357#endif
358 }
359}
360
361///////////////////////////////////////////////////////////////////////////////////////////
362
363DEF_TEST(BlurAsABlur, reporter) {
364 const SkBlurStyle styles[] = {
366 };
367 const SkScalar sigmas[] = {
368 // values <= 0 should not success for a blur
369 -1, 0, 0.5f, 2
370 };
371
372 // Test asABlur for SkBlurMaskFilter
373 //
374 for (size_t i = 0; i < std::size(styles); ++i) {
375 const SkBlurStyle style = styles[i];
376 for (size_t j = 0; j < std::size(sigmas); ++j) {
377 const SkScalar sigma = sigmas[j];
378 for (bool respectCTM : { false, true }) {
379 sk_sp<SkMaskFilter> mf(SkMaskFilter::MakeBlur(style, sigma, respectCTM));
380 if (nullptr == mf.get()) {
381 REPORTER_ASSERT(reporter, sigma <= 0);
382 } else {
383 REPORTER_ASSERT(reporter, sigma > 0);
385 bool success = as_MFB(mf)->asABlur(&rec);
386 if (respectCTM) {
387 REPORTER_ASSERT(reporter, success);
388 REPORTER_ASSERT(reporter, rec.fSigma == sigma);
389 REPORTER_ASSERT(reporter, rec.fStyle == style);
390 } else {
391 REPORTER_ASSERT(reporter, !success);
392 }
393
394 const SkRect src = {0, 0, 100, 100};
395 const auto dst = mf->approximateFilteredBounds(src);
396
397 // This is a very conservative test. With more knowledge, we could
398 // consider more stringent tests.
399 REPORTER_ASSERT(reporter, dst.contains(src));
400 }
401 }
402 }
403 }
404
405 // Test asABlur for SkEmbossMaskFilter -- should never succeed
406 //
407 {
409 { 1, 1, 1 }, 0, 127, 127
410 };
411 for (size_t j = 0; j < std::size(sigmas); ++j) {
412 const SkScalar sigma = sigmas[j];
413 auto mf(SkEmbossMaskFilter::Make(sigma, light));
414 if (mf) {
416 bool success = as_MFB(mf)->asABlur(&rec);
417 REPORTER_ASSERT(reporter, !success);
418 }
419 }
420 }
421}
422
423// This exercises the problem discovered in crbug.com/570232. The return value from
424// SkBlurMask::BoxBlur wasn't being checked in SkBlurMaskFilter.cpp::GrRRectBlurEffect::Create
427 auto surface(SkSurfaces::RenderTarget(ctxInfo.directContext(), skgpu::Budgeted::kNo, info));
428 SkCanvas* canvas = surface->getCanvas();
429
430 SkRect r = SkRect::MakeXYWH(10, 10, 100, 100);
431 SkRRect rr = SkRRect::MakeRectXY(r, 10, 10);
432
433 SkPaint p;
434 p.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 0.01f));
435
436 canvas->drawRRect(rr, p);
437}
438
439DEF_TEST(BlurredRRectNinePatchComputation, reporter) {
440 const SkRect r = SkRect::MakeXYWH(10, 10, 100, 100);
441 static const SkScalar kBlurRad = 3.0f;
442
443 bool ninePatchable;
444 SkRRect rrectToDraw;
450
451 // not nine-patchable
452 {
453 SkVector radii[4] = { { 100, 100 }, { 0, 0 }, { 100, 100 }, { 0, 0 } };
454
455 SkRRect rr;
456 rr.setRectRadii(r, radii);
457
458 ninePatchable = GrBlurUtils::ComputeBlurredRRectParams(rr, rr, kBlurRad, kBlurRad,
459 &rrectToDraw, &size,
460 rectXs, rectYs, texXs, texYs);
461 REPORTER_ASSERT(reporter, !ninePatchable);
462 }
463
464 // simple circular
465 {
466 static const SkScalar kCornerRad = 10.0f;
467 SkRRect rr;
468 rr.setRectXY(r, kCornerRad, kCornerRad);
469
470 ninePatchable = GrBlurUtils::ComputeBlurredRRectParams(rr, rr, kBlurRad, kBlurRad,
471 &rrectToDraw, &size,
472 rectXs, rectYs, texXs, texYs);
473
474 static const SkScalar kAns = 12.0f * kBlurRad + 2.0f * kCornerRad + 1.0f;
475 REPORTER_ASSERT(reporter, ninePatchable);
478 }
479
480 // simple elliptical
481 {
482 static const SkScalar kXCornerRad = 2.0f;
483 static const SkScalar kYCornerRad = 10.0f;
484 SkRRect rr;
485 rr.setRectXY(r, kXCornerRad, kYCornerRad);
486
487 ninePatchable = GrBlurUtils::ComputeBlurredRRectParams(rr, rr, kBlurRad, kBlurRad,
488 &rrectToDraw, &size,
489 rectXs, rectYs, texXs, texYs);
490
491 static const SkScalar kXAns = 12.0f * kBlurRad + 2.0f * kXCornerRad + 1.0f;
492 static const SkScalar kYAns = 12.0f * kBlurRad + 2.0f * kYCornerRad + 1.0f;
493
494 REPORTER_ASSERT(reporter, ninePatchable);
497 }
498}
499
500// https://crbugs.com/787712
501DEF_TEST(EmbossPerlinCrash, reporter) {
502 SkPaint p;
503
504 static constexpr SkEmbossMaskFilter::Light light = {
505 { 1, 1, 1 }, 0, 127, 127
506 };
507 p.setMaskFilter(SkEmbossMaskFilter::Make(1, light));
508 p.setShader(SkShaders::MakeFractalNoise(1.0f, 1.0f, 2, 0.0f));
509
511 surface->getCanvas()->drawPaint(p);
512}
513
514///////////////////////////////////////////////////////////////////////////////////////////
515
516DEF_TEST(BlurZeroSigma, reporter) {
519 paint.setAntiAlias(true);
520
521 const SkIRect ir = { 5, 5, 15, 15 };
522 const SkRect r = SkRect::Make(ir);
523
524 const SkScalar sigmas[] = { 0, SkBits2Float(1) };
525 // if sigma is zero (or nearly so), we need to draw correctly (unblurred) and not crash
526 // or assert.
527 for (auto sigma : sigmas) {
528 paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma));
529 surf->getCanvas()->drawRect(r, paint);
530
531 ToolUtils::PixelIter iter(surf.get());
532 SkIPoint loc;
533 while (const SkPMColor* p = (const SkPMColor*)iter.next(&loc)) {
534 if (ir.contains(loc.fX, loc.fY)) {
535 // inside the rect we draw (opaque black)
536 REPORTER_ASSERT(reporter, *p == SkPackARGB32(0xFF, 0, 0, 0));
537 } else {
538 // outside the rect we didn't draw at all, no blurred edges
539 REPORTER_ASSERT(reporter, *p == 0);
540 }
541 }
542 }
543}
544
545
546///////////////////////////////////////////////////////////////////////////////////////////
547
549 reporter,
550 ctxInfo,
552 auto context = ctxInfo.directContext();
553
555
557 if (!dst) {
558 ERRORF(reporter, "Could not create surface for test.");
559 return;
560 }
561
562 SkPaint p;
563 p.setColor(SK_ColorRED);
565
566 SkCanvas* canvas = dst->getCanvas();
567
568 canvas->clear(SK_ColorBLACK);
569 canvas->drawCircle(SkPoint::Make(16, 16), 8, p);
570
572 SkAssertResult(readback.tryAllocPixels(ii));
573
574 canvas->readPixels(readback, 0, 0);
575 REPORTER_ASSERT(reporter, SkColorGetR(readback.getColor(15, 15)) > 128);
576 REPORTER_ASSERT(reporter, SkColorGetG(readback.getColor(15, 15)) == 0);
577 REPORTER_ASSERT(reporter, SkColorGetB(readback.getColor(15, 15)) == 0);
578 REPORTER_ASSERT(reporter, readback.getColor(31, 31) == SK_ColorBLACK);
579}
580
581DEF_TEST(zero_blur, reporter) {
582 SkBitmap alpha, bitmap;
583
587 bitmap.extractAlpha(&alpha, &paint, nullptr, &offset);
588}
static void draw50x50Rect(SkPath *path)
Definition: BlurTest.cpp:79
static int step(int x, SkScalar min, SkScalar max)
Definition: BlurTest.cpp:215
static bool compare(const SkBitmap &ref, const SkIRect &iref, const SkBitmap &test, const SkIRect &itest)
Definition: BlurTest.cpp:100
static void readback(const SkBitmap &src, int *result, int resultCount)
Definition: BlurTest.cpp:264
static const int outset
Definition: BlurTest.cpp:58
static void drawBG(SkCanvas *canvas)
Definition: BlurTest.cpp:66
static void ground_truth_2d(int width, int height, SkScalar sigma, int *result, int resultCount)
Definition: BlurTest.cpp:181
static bool match(int *first, int *second, int count, int tol)
Definition: BlurTest.cpp:301
static void brute_force_1d(SkScalar stepMin, SkScalar stepMax, SkScalar gaussianSigma, int *result, int resultCount)
Definition: BlurTest.cpp:231
static void cpu_blur_path(const SkPath &path, SkScalar gaussianSigma, int *result, int resultCount)
Definition: BlurTest.cpp:280
static void blur_path(SkCanvas *canvas, const SkPath &path, SkScalar gaussianSigma)
Definition: BlurTest.cpp:247
DEF_TEST(BlurDrawing, reporter)
Definition: BlurTest.cpp:127
static BlurTest tests[]
Definition: BlurTest.cpp:84
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SmallBoxBlurBug, reporter, ctxInfo, CtsEnforcement::kNever)
Definition: BlurTest.cpp:425
static void create(SkBitmap *bm, const SkIRect &bound)
Definition: BlurTest.cpp:62
static float gaussian(int x, SkScalar sigma)
Definition: BlurTest.cpp:223
static const SkColor bgColor
Definition: BlurTest.cpp:59
static const int strokeWidth
Definition: BlurTest.cpp:60
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define test(name)
reporter
Definition: FontMgrTest.cpp:39
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
int count
Definition: FontMgrTest.cpp:50
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
SkBlurStyle
Definition: SkBlurTypes.h:11
@ kOuter_SkBlurStyle
nothing inside, fuzzy outside
Definition: SkBlurTypes.h:14
@ kSolid_SkBlurStyle
solid inside, fuzzy outside
Definition: SkBlurTypes.h:13
@ kInner_SkBlurStyle
fuzzy inside, nothing outside
Definition: SkBlurTypes.h:15
@ kNormal_SkBlurStyle
fuzzy inside and outside
Definition: SkBlurTypes.h:12
@ kLastEnum_SkBlurStyle
Definition: SkBlurTypes.h:17
static SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColorPriv.h:106
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
#define SkColorGetR(color)
Definition: SkColor.h:65
#define SkColorGetG(color)
Definition: SkColor.h:69
uint32_t SkColor
Definition: SkColor.h:37
uint32_t SkPMColor
Definition: SkColor.h:205
constexpr SkColor SK_ColorGRAY
Definition: SkColor.h:113
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
#define SkColorGetB(color)
Definition: SkColor.h:73
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static float SkBits2Float(uint32_t bits)
Definition: SkFloatBits.h:48
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
static int SkClampPos(int value)
Definition: SkMathPriv.h:30
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
#define SK_Scalar1
Definition: SkScalar.h:18
#define SkScalarCeilToInt(x)
Definition: SkScalar.h:36
#define SkIntToScalar(x)
Definition: SkScalar.h:57
#define SK_ScalarPI
Definition: SkScalar.h:21
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition: SkTPin.h:19
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define ERRORF(r,...)
Definition: Test.h:293
SkColor getColor(int x, int y) const
Definition: SkBitmap.h:874
int width() const
Definition: SkBitmap.h:149
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition: SkBitmap.cpp:232
int height() const
Definition: SkBitmap.h:158
static SkScalar SK_SPI ConvertRadiusToSigma(SkScalar radius)
Definition: SkBlurMask.cpp:39
static bool BlurGroundTruth(SkScalar sigma, SkMaskBuilder *dst, const SkMask &src, SkBlurStyle, SkIPoint *margin=nullptr)
Definition: SkBlurMask.cpp:517
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
void clear(SkColor color)
Definition: SkCanvas.h:1199
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
Definition: SkCanvas.cpp:1705
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY)
Definition: SkCanvas.cpp:382
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
Definition: SkCanvas.cpp:2707
static sk_sp< SkMaskFilter > Make(SkScalar blurSigma, const Light &light)
virtual bool asABlur(BlurRec *) const
static sk_sp< SkMaskFilter > MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM=true)
SkRect approximateFilteredBounds(const SkRect &src) const
void setColor(SkColor color)
Definition: SkPaint.cpp:119
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
void setMaskFilter(sk_sp< SkMaskFilter > maskFilter)
Definition: SkPath.h:59
SkPath & addPoly(const SkPoint pts[], int count, bool close)
Definition: SkPath.cpp:890
const SkRect & getBounds() const
Definition: SkPath.cpp:430
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition: SkPath.cpp:864
const uint32_t * addr32() const
Definition: SkPixmap.h:352
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180
void setRectRadii(const SkRect &rect, const SkVector radii[4])
Definition: SkRRect.cpp:189
void setRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.cpp:52
void * next(SkIPoint *loc=nullptr)
Definition: ToolUtils.h:286
T * get() const
Definition: SkRefCnt.h:303
const Paint & paint
Definition: color_source.cc:38
VkSurfaceKHR surface
Definition: main.cc:49
float SkScalar
Definition: extension.cpp:12
GAsyncResult * result
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
constexpr int kSize
double y
double x
static constexpr int kBlurRRectMaxDivisions
Definition: GrBlurUtils.h:39
bool ComputeBlurredRRectParams(const SkRRect &srcRRect, const SkRRect &devRRect, SkScalar sigma, SkScalar xformedSigma, SkRRect *rrectToDraw, SkISize *widthHeight, SkScalar rectXs[kBlurRRectMaxDivisions], SkScalar rectYs[kBlurRRectMaxDivisions], SkScalar texXs[kBlurRRectMaxDivisions], SkScalar texYs[kBlurRRectMaxDivisions])
SK_API sk_sp< SkShader > MakeFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize=nullptr)
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
Definition: bitmap.py:1
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
Definition: SkPathUtils.cpp:23
int32_t height
int32_t width
const Scalar scale
SeparatedVector2 offset
void(* addPath)(SkPath *)
Definition: BlurTest.cpp:72
int viewLen
Definition: BlurTest.cpp:73
SkIRect views[9]
Definition: BlurTest.cpp:74
int32_t fX
x-axis value
Definition: SkPoint_impl.h:29
int32_t fY
y-axis value
Definition: SkPoint_impl.h:30
Definition: SkRect.h:32
void inset(int32_t dx, int32_t dy)
Definition: SkRect.h:411
constexpr int32_t height() const
Definition: SkRect.h:165
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
constexpr int32_t width() const
Definition: SkRect.h:158
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
bool contains(int32_t x, int32_t y) const
Definition: SkRect.h:463
Definition: SkSize.h:16
static SkImageInfo MakeN32Premul(int width, int height)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static void FreeImage(void *image)
Definition: SkMask.cpp:57
static uint8_t * AllocImage(size_t bytes, AllocType=kUninit_Alloc)
Definition: SkMask.cpp:45
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition: SkMask.h:28
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63