Flutter Engine
The Flutter Engine
Classes | Macros | Functions | Variables
BlurTest.cpp File Reference
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlurTypes.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathUtils.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkPerlinNoiseShader.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/private/base/SkTPin.h"
#include "src/base/SkFloatBits.h"
#include "src/base/SkMathPriv.h"
#include "src/core/SkBlurMask.h"
#include "src/core/SkMask.h"
#include "src/core/SkMaskFilterBase.h"
#include "src/effects/SkEmbossMaskFilter.h"
#include "src/gpu/ganesh/GrBlurUtils.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"
#include <math.h>
#include <string.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <initializer_list>

Go to the source code of this file.

Classes

struct  BlurTest
 

Macros

#define WRITE_CSV   0
 

Functions

static void create (SkBitmap *bm, const SkIRect &bound)
 
static void drawBG (SkCanvas *canvas)
 
static void draw50x50Rect (SkPath *path)
 
static bool compare (const SkBitmap &ref, const SkIRect &iref, const SkBitmap &test, const SkIRect &itest)
 
 DEF_TEST (BlurDrawing, reporter)
 
static void ground_truth_2d (int width, int height, SkScalar sigma, int *result, int resultCount)
 
static int step (int x, SkScalar min, SkScalar max)
 
static float gaussian (int x, SkScalar sigma)
 
static void brute_force_1d (SkScalar stepMin, SkScalar stepMax, SkScalar gaussianSigma, int *result, int resultCount)
 
static void blur_path (SkCanvas *canvas, const SkPath &path, SkScalar gaussianSigma)
 
static void readback (const SkBitmap &src, int *result, int resultCount)
 
static void cpu_blur_path (const SkPath &path, SkScalar gaussianSigma, int *result, int resultCount)
 
static bool match (int *first, int *second, int count, int tol)
 
 DEF_TEST (BlurSigmaRange, reporter)
 
 DEF_TEST (BlurAsABlur, reporter)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (SmallBoxBlurBug, reporter, ctxInfo, CtsEnforcement::kNever)
 
 DEF_TEST (BlurredRRectNinePatchComputation, reporter)
 
 DEF_TEST (EmbossPerlinCrash, reporter)
 
 DEF_TEST (BlurZeroSigma, reporter)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (BlurMaskBiggerThanDest, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_TEST (zero_blur, reporter)
 

Variables

static const int outset = 100
 
static const SkColor bgColor = SK_ColorWHITE
 
static const int strokeWidth = 4
 
static BlurTest tests []
 

Macro Definition Documentation

◆ WRITE_CSV

#define WRITE_CSV   0

Definition at line 54 of file BlurTest.cpp.

Function Documentation

◆ blur_path()

static void blur_path ( SkCanvas canvas,
const SkPath path,
SkScalar  gaussianSigma 
)
static

Definition at line 247 of file BlurTest.cpp.

248 {
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}
@ kNormal_SkBlurStyle
fuzzy inside and outside
Definition: SkBlurTypes.h:12
constexpr SkColor SK_ColorBLACK
Definition: SkColor.h:103
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
static sk_sp< SkMaskFilter > MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM=true)
void setColor(SkColor color)
Definition: SkPaint.cpp:119
void setMaskFilter(sk_sp< SkMaskFilter > maskFilter)
float SkScalar
Definition: extension.cpp:12
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

◆ brute_force_1d()

static void brute_force_1d ( SkScalar  stepMin,
SkScalar  stepMax,
SkScalar  gaussianSigma,
int result,
int  resultCount 
)
static

Definition at line 231 of file BlurTest.cpp.

233 {
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}
static int step(int x, SkScalar min, SkScalar max)
Definition: BlurTest.cpp:215
static float gaussian(int x, SkScalar sigma)
Definition: BlurTest.cpp:223
static int SkClampPos(int value)
Definition: SkMathPriv.h:30
#define SkScalarCeilToInt(x)
Definition: SkScalar.h:36
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition: SkTPin.h:19
GAsyncResult * result

◆ compare()

static bool compare ( const SkBitmap ref,
const SkIRect iref,
const SkBitmap test,
const SkIRect itest 
)
static

Assumes that the ref draw was completely inside ref canvas – implies that everything outside is "bgColor". Checks that all overlap is the same and that all non-overlap on the ref is "bgColor".

Definition at line 100 of file BlurTest.cpp.

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}
static const SkColor bgColor
Definition: BlurTest.cpp:59
uint32_t SkColor
Definition: SkColor.h:37
SkColor getColor(int x, int y) const
Definition: SkBitmap.h:874
int width() const
Definition: SkBitmap.h:149
int height() const
Definition: SkBitmap.h:158
double y
double x
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33

◆ cpu_blur_path()

static void cpu_blur_path ( const SkPath path,
SkScalar  gaussianSigma,
int result,
int  resultCount 
)
static

Definition at line 280 of file BlurTest.cpp.

281 {
282
284 bitmap.allocN32Pixels(resultCount, 30);
285 SkCanvas canvas(bitmap);
286
287 blur_path(&canvas, path, gaussianSigma);
288 readback(bitmap, result, resultCount);
289}
static void readback(const SkBitmap &src, int *result, int resultCount)
Definition: BlurTest.cpp:264
static void blur_path(SkCanvas *canvas, const SkPath &path, SkScalar gaussianSigma)
Definition: BlurTest.cpp:247
Definition: bitmap.py:1

◆ create()

static void create ( SkBitmap bm,
const SkIRect bound 
)
static

Definition at line 62 of file BlurTest.cpp.

62 {
63 bm->allocN32Pixels(bound.width(), bound.height());
64}
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition: SkBitmap.cpp:232
constexpr int32_t height() const
Definition: SkRect.h:165
constexpr int32_t width() const
Definition: SkRect.h:158

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [1/2]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( BlurMaskBiggerThanDest  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 548 of file BlurTest.cpp.

551 {
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}
reporter
Definition: FontMgrTest.cpp:39
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
@ 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
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
#define SkColorGetB(color)
Definition: SkColor.h:73
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
#define ERRORF(r,...)
Definition: Test.h:293
void clear(SkColor color)
Definition: SkCanvas.h:1199
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
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)
dst
Definition: cp.py:12
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [2/2]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( SmallBoxBlurBug  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kNever   
)

Definition at line 425 of file BlurTest.cpp.

425 {
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}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
Definition: SkCanvas.cpp:1705
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180
VkSurfaceKHR surface
Definition: main.cc:49
static SkImageInfo MakeN32Premul(int width, int height)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659

◆ DEF_TEST() [1/7]

DEF_TEST ( BlurAsABlur  ,
reporter   
)

Definition at line 363 of file BlurTest.cpp.

363 {
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}
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
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
static sk_sp< SkMaskFilter > Make(SkScalar blurSigma, const Light &light)
virtual bool asABlur(BlurRec *) const
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

◆ DEF_TEST() [2/7]

DEF_TEST ( BlurDrawing  ,
reporter   
)

Definition at line 127 of file BlurTest.cpp.

127 {
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}
static bool compare(const SkBitmap &ref, const SkIRect &iref, const SkBitmap &test, const SkIRect &itest)
Definition: BlurTest.cpp:100
static const int outset
Definition: BlurTest.cpp:58
static void drawBG(SkCanvas *canvas)
Definition: BlurTest.cpp:66
static BlurTest tests[]
Definition: BlurTest.cpp:84
static void create(SkBitmap *bm, const SkIRect &bound)
Definition: BlurTest.cpp:62
static const int strokeWidth
Definition: BlurTest.cpp:60
#define test(name)
@ kLastEnum_SkBlurStyle
Definition: SkBlurTypes.h:17
constexpr SkColor SK_ColorGRAY
Definition: SkColor.h:113
#define SkIntToScalar(x)
Definition: SkScalar.h:57
static SkScalar SK_SPI ConvertRadiusToSigma(SkScalar radius)
Definition: SkBlurMask.cpp:39
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
Definition: SkPath.h:59
const SkRect & getBounds() const
Definition: SkPath.cpp:430
const Paint & paint
Definition: color_source.cc:38
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
Definition: SkPathUtils.cpp:23
void(* addPath)(SkPath *)
Definition: BlurTest.cpp:72
int viewLen
Definition: BlurTest.cpp:73
SkIRect views[9]
Definition: BlurTest.cpp:74
Definition: SkRect.h:32
void inset(int32_t dx, int32_t dy)
Definition: SkRect.h:411
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241

◆ DEF_TEST() [3/7]

DEF_TEST ( BlurredRRectNinePatchComputation  ,
reporter   
)

Definition at line 439 of file BlurTest.cpp.

439 {
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}
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
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
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])
Definition: SkSize.h:16

◆ DEF_TEST() [4/7]

DEF_TEST ( BlurSigmaRange  ,
reporter   
)

Definition at line 314 of file BlurTest.cpp.

314 {
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}
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
SkPath & addPoly(const SkPoint pts[], int count, bool close)
Definition: SkPath.cpp:890
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition: SkPath.cpp:864
constexpr int kSize

◆ DEF_TEST() [5/7]

DEF_TEST ( BlurZeroSigma  ,
reporter   
)

Definition at line 516 of file BlurTest.cpp.

516 {
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}
static SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColorPriv.h:106
uint32_t SkPMColor
Definition: SkColor.h:205
static float SkBits2Float(uint32_t bits)
Definition: SkFloatBits.h:48
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
int32_t fX
x-axis value
Definition: SkPoint_impl.h:29
int32_t fY
y-axis value
Definition: SkPoint_impl.h:30
bool contains(int32_t x, int32_t y) const
Definition: SkRect.h:463
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669

◆ DEF_TEST() [6/7]

DEF_TEST ( EmbossPerlinCrash  ,
reporter   
)

Definition at line 501 of file BlurTest.cpp.

501 {
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}
SK_API sk_sp< SkShader > MakeFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize=nullptr)

◆ DEF_TEST() [7/7]

DEF_TEST ( zero_blur  ,
reporter   
)

Definition at line 581 of file BlurTest.cpp.

581 {
582 SkBitmap alpha, bitmap;
583
587 bitmap.extractAlpha(&alpha, &paint, nullptr, &offset);
588}
SeparatedVector2 offset

◆ draw50x50Rect()

static void draw50x50Rect ( SkPath path)
static

Definition at line 79 of file BlurTest.cpp.

79 {
80 path->addRect(0, 0, SkIntToScalar(50), SkIntToScalar(50));
81}

◆ drawBG()

static void drawBG ( SkCanvas canvas)
static

Definition at line 66 of file BlurTest.cpp.

66 {
67 canvas->drawColor(bgColor);
68}

◆ gaussian()

static float gaussian ( int  x,
SkScalar  sigma 
)
static

Definition at line 223 of file BlurTest.cpp.

223 {
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}
#define SK_Scalar1
Definition: SkScalar.h:18
#define SK_ScalarPI
Definition: SkScalar.h:21

◆ ground_truth_2d()

static void ground_truth_2d ( int  width,
int  height,
SkScalar  sigma,
int result,
int  resultCount 
)
static

Definition at line 181 of file BlurTest.cpp.

183 {
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}
static bool BlurGroundTruth(SkScalar sigma, SkMaskBuilder *dst, const SkMask &src, SkBlurStyle, SkIPoint *margin=nullptr)
Definition: SkBlurMask.cpp:517
int32_t height
int32_t width
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

◆ match()

static bool match ( int first,
int second,
int  count,
int  tol 
)
static

Definition at line 301 of file BlurTest.cpp.

301 {
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}
int count
Definition: FontMgrTest.cpp:50

◆ readback()

static void readback ( const SkBitmap src,
int result,
int  resultCount 
)
static

Definition at line 264 of file BlurTest.cpp.

264 {
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}
const uint32_t * addr32() const
Definition: SkPixmap.h:352

◆ step()

static int step ( int  x,
SkScalar  min,
SkScalar  max 
)
static

Definition at line 215 of file BlurTest.cpp.

215 {
216 if (min < x && x < max) {
217 return 255;
218 }
219 return 0;
220}
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

Variable Documentation

◆ bgColor

const SkColor bgColor = SK_ColorWHITE
static

Definition at line 59 of file BlurTest.cpp.

◆ outset

const int outset = 100
static

Definition at line 58 of file BlurTest.cpp.

◆ strokeWidth

const int strokeWidth = 4
static

Definition at line 60 of file BlurTest.cpp.

◆ tests

BlurTest tests[]
static
Initial value:
= {
{ draw50x50Rect, 3, {
{ 0, 0, 50, 50 },
{ 50 + strokeWidth/2, 50 + strokeWidth/2, 100, 100 },
{ 40, strokeWidth, 60, 50 - strokeWidth },
}},
}
static void draw50x50Rect(SkPath *path)
Definition: BlurTest.cpp:79

Definition at line 84 of file BlurTest.cpp.