50#include <initializer_list>
104 const int yOff = itest.
fTop - iref.
fTop;
106 for (
int y = 0;
y <
test.height(); ++
y) {
107 for (
int x = 0;
x <
test.width(); ++
x) {
112 if (refX >= 0 && refX < ref.
width() &&
113 refY >= 0 && refY < ref.
height())
115 refColor = ref.
getColor(refX, refY);
119 if (refColor != testColor) {
137 for (
bool respectCTM : {
false,
true }) {
161 create(&testBitmap, itest);
170 compare(refBitmap, iref, testBitmap, itest));
183 int*
result,
int resultCount) {
188 src.rowBytes() = src.fBounds.width();
191 memset(src.image(), 0xff, src.computeTotalImageSize());
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);
201 for (i = 0; i < dst.fBounds.width()-(midX-dst.fBounds.fLeft); ++i) {
202 if (i < resultCount) {
206 for ( ; i < resultCount; ++i) {
225 float exponent = -(
x *
x) / (2 * sigma * sigma);
226 return k * expf(exponent);
233 int*
result,
int resultCount) {
237 for (
int i = 0; i < resultCount; ++i) {
239 for (
int j = -gaussianRange; j < gaussianRange; ++j) {
240 sum +=
gaussian(j, gaussianSigma) *
step(i-j, stepMin, stepMax);
250 SkScalar midX = path.getBounds().centerX();
251 SkScalar midY = path.getBounds().centerY();
269 src.readPixels(pm, 0, 0);
273 for (
int i = 0; i < resultCount; ++i) {
281 int*
result,
int resultCount) {
284 bitmap.allocN32Pixels(resultCount, 30);
294 for (
int i = 0; i <
count-1; ++i) {
301static bool match(
int* first,
int* second,
int count,
int tol) {
303 for (
int i = 0; i <
count; ++i) {
304 delta = first[i] - second[i];
305 if (delta > tol || delta < -tol) {
315 static const int kSize = 100;
320 rectPath.
addRect(0.3f, 0.3f, 100.3f, 100.3f);
330 polyPath.
addPoly(polyPts, std::size(polyPts),
true);
332 int rectSpecialCaseResult[
kSize];
333 int generalCaseResult[
kSize];
334 int groundTruthResult[
kSize];
335 int bruteForce1DResult[
kSize];
339 for (
int i = 0; i < 4; ++i, sigma /= 10) {
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);
374 for (
size_t i = 0; i < std::size(styles); ++i) {
376 for (
size_t j = 0; j < std::size(sigmas); ++j) {
378 for (
bool respectCTM : {
false,
true }) {
380 if (
nullptr == mf.
get()) {
394 const SkRect src = {0, 0, 100, 100};
395 const auto dst = mf->approximateFilteredBounds(src);
409 { 1, 1, 1 }, 0, 127, 127
411 for (
size_t j = 0; j < std::size(sigmas); ++j) {
441 static const SkScalar kBlurRad = 3.0f;
453 SkVector radii[4] = { { 100, 100 }, { 0, 0 }, { 100, 100 }, { 0, 0 } };
460 rectXs, rectYs, texXs, texYs);
466 static const SkScalar kCornerRad = 10.0f;
472 rectXs, rectYs, texXs, texYs);
474 static const SkScalar kAns = 12.0f * kBlurRad + 2.0f * kCornerRad + 1.0f;
482 static const SkScalar kXCornerRad = 2.0f;
483 static const SkScalar kYCornerRad = 10.0f;
485 rr.
setRectXY(r, kXCornerRad, kYCornerRad);
489 rectXs, rectYs, texXs, texYs);
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;
505 { 1, 1, 1 }, 0, 127, 127
511 surface->getCanvas()->drawPaint(p);
519 paint.setAntiAlias(
true);
521 const SkIRect ir = { 5, 5, 15, 15 };
527 for (
auto sigma : sigmas) {
529 surf->getCanvas()->drawRect(r,
paint);
552 auto context = ctxInfo.directContext();
566 SkCanvas* canvas = dst->getCanvas();
static void draw50x50Rect(SkPath *path)
static int step(int x, SkScalar min, SkScalar max)
static bool compare(const SkBitmap &ref, const SkIRect &iref, const SkBitmap &test, const SkIRect &itest)
static void readback(const SkBitmap &src, int *result, int resultCount)
static void drawBG(SkCanvas *canvas)
static void ground_truth_2d(int width, int height, SkScalar sigma, int *result, int resultCount)
static bool match(int *first, int *second, int count, int tol)
static void brute_force_1d(SkScalar stepMin, SkScalar stepMax, SkScalar gaussianSigma, int *result, int resultCount)
static void cpu_blur_path(const SkPath &path, SkScalar gaussianSigma, int *result, int resultCount)
static void blur_path(SkCanvas *canvas, const SkPath &path, SkScalar gaussianSigma)
static float gaussian(int x, SkScalar sigma)
static const SkColor bgColor
static const int strokeWidth
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SkAssertResult(cond)
@ kOuter_SkBlurStyle
nothing inside, fuzzy outside
@ kSolid_SkBlurStyle
solid inside, fuzzy outside
@ kInner_SkBlurStyle
fuzzy inside, nothing outside
@ kNormal_SkBlurStyle
fuzzy inside and outside
static SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
#define SkColorGetR(color)
#define SkColorGetG(color)
constexpr SkColor SK_ColorGRAY
constexpr SkColor SK_ColorRED
constexpr SkColor SK_ColorBLACK
#define SkColorGetB(color)
constexpr SkColor SK_ColorWHITE
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static float SkBits2Float(uint32_t bits)
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
static int SkClampPos(int value)
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
#define SkScalarCeilToInt(x)
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
#define DEF_TEST(name, reporter)
#define REPORTER_ASSERT(r, cond,...)
#define DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(name, reporter, context_info, ctsEnforcement)
SkColor getColor(int x, int y) const
void allocN32Pixels(int width, int height, bool isOpaque=false)
static SkScalar SK_SPI ConvertRadiusToSigma(SkScalar radius)
static bool BlurGroundTruth(SkScalar sigma, SkMaskBuilder *dst, const SkMask &src, SkBlurStyle, SkIPoint *margin=nullptr)
void translate(SkScalar dx, SkScalar dy)
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
void clear(SkColor color)
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
void drawPath(const SkPath &path, const SkPaint &paint)
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY)
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
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)
void setColor(SkColor color)
@ kStroke_Style
set to stroke geometry
void setMaskFilter(sk_sp< SkMaskFilter > maskFilter)
SkPath & addPoly(const SkPoint pts[], int count, bool close)
const SkRect & getBounds() const
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
const uint32_t * addr32() const
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
void setRectRadii(const SkRect &rect, const SkVector radii[4])
void setRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
static constexpr int kSize
static float max(float r, float g, float b)
static float min(float r, float g, float b)
static constexpr int kBlurRRectMaxDivisions
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)
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
void(* addPath)(SkPath *)
void inset(int32_t dx, int32_t dy)
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
int32_t fLeft
smaller x-axis bounds
bool contains(int32_t x, int32_t y) const
static SkImageInfo MakeN32Premul(int width, int height)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static void FreeImage(void *image)
static uint8_t * AllocImage(size_t bytes, AllocType=kUninit_Alloc)
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
static constexpr SkPoint Make(float x, float y)
static SkRect Make(const SkISize &size)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
void roundOut(SkIRect *dst) const