/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#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/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/ganesh/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/SkColorPriv.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>

#if defined(SK_GRAPHITE)
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Surface.h"
#endif

struct GrContextOptions;

#define WRITE_CSV 0

///////////////////////////////////////////////////////////////////////////////

static const int outset = 100;
static const SkColor bgColor = SK_ColorWHITE;
static const int strokeWidth = 4;

static void create(SkBitmap* bm, const SkIRect& bound) {
    bm->allocN32Pixels(bound.width(), bound.height());
}

static void drawBG(SkCanvas* canvas) {
    canvas->drawColor(bgColor);
}


struct BlurTest {
    SkPath (*addPath)();
    int viewLen;
    SkIRect views[9];
};

//Path Draw Procs
//Beware that paths themselves my draw differently depending on the clip.
static SkPath draw50x50Rect() {
    return SkPath::Rect({0, 0, 50, 50});
}

//Tests
static BlurTest tests[] = {
    { draw50x50Rect, 3, {
        //inner half of blur
        { 0, 0, 50, 50 },
        //blur, but no path.
        { 50 + strokeWidth/2, 50 + strokeWidth/2, 100, 100 },
        //just an edge
        { 40, strokeWidth, 60, 50 - strokeWidth },
    }},
};

/** 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".
 */
static bool compare(const SkBitmap& ref, const SkIRect& iref,
                    const SkBitmap& test, const SkIRect& itest)
{
    const int xOff = itest.fLeft - iref.fLeft;
    const int yOff = itest.fTop - iref.fTop;

    for (int y = 0; y < test.height(); ++y) {
        for (int x = 0; x < test.width(); ++x) {
            SkColor testColor = test.getColor(x, y);
            int refX = x + xOff;
            int refY = y + yOff;
            SkColor refColor;
            if (refX >= 0 && refX < ref.width() &&
                refY >= 0 && refY < ref.height())
            {
                refColor = ref.getColor(refX, refY);
            } else {
                refColor = bgColor;
            }
            if (refColor != testColor) {
                return false;
            }
        }
    }
    return true;
}

DEF_TEST(BlurDrawing, reporter) {
    SkPaint paint;
    paint.setColor(SK_ColorGRAY);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(SkIntToScalar(strokeWidth));

    SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5));
    for (int style = 0; style <= kLastEnum_SkBlurStyle; ++style) {
        SkBlurStyle blurStyle = static_cast<SkBlurStyle>(style);

        for (bool respectCTM : { false, true }) {
            paint.setMaskFilter(SkMaskFilter::MakeBlur(blurStyle, sigma, respectCTM));

            for (size_t test = 0; test < std::size(tests); ++test) {
                SkPath path = tests[test].addPath();
                SkPath strokedPath = skpathutils::FillPathWithPaint(path, paint);
                SkRect refBound = strokedPath.getBounds();
                SkIRect iref;
                refBound.roundOut(&iref);
                iref.inset(-outset, -outset);
                SkBitmap refBitmap;
                create(&refBitmap, iref);

                SkCanvas refCanvas(refBitmap);
                refCanvas.translate(SkIntToScalar(-iref.fLeft),
                                    SkIntToScalar(-iref.fTop));
                drawBG(&refCanvas);
                refCanvas.drawPath(path, paint);

                for (int view = 0; view < tests[test].viewLen; ++view) {
                    SkIRect itest = tests[test].views[view];
                    SkBitmap testBitmap;
                    create(&testBitmap, itest);

                    SkCanvas testCanvas(testBitmap);
                    testCanvas.translate(SkIntToScalar(-itest.fLeft),
                                         SkIntToScalar(-itest.fTop));
                    drawBG(&testCanvas);
                    testCanvas.drawPath(path, paint);

                    REPORTER_ASSERT(reporter,
                        compare(refBitmap, iref, testBitmap, itest));
                }
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

// Use SkBlurMask::BlurGroundTruth to blur a 'width' x 'height' solid
// white rect. Return the right half of the middle row in 'result'.
static void ground_truth_2d(int width, int height,
                            SkScalar sigma,
                            int* result, int resultCount) {
    SkMaskBuilder src, dst;

    src.bounds().setWH(width, height);
    src.format() = SkMask::kA8_Format;
    src.rowBytes() = src.fBounds.width();
    src.image() = SkMaskBuilder::AllocImage(src.computeTotalImageSize());

    memset(src.image(), 0xff, src.computeTotalImageSize());

    if (!SkBlurMask::BlurGroundTruth(sigma, &dst, src, kNormal_SkBlurStyle)) {
        return;
    }

    int midX = dst.fBounds.x() + dst.fBounds.width()/2;
    int midY = dst.fBounds.y() + dst.fBounds.height()/2;
    uint8_t* bytes = dst.getAddr8(midX, midY);
    int i;
    for (i = 0; i < dst.fBounds.width()-(midX-dst.fBounds.fLeft); ++i) {
        if (i < resultCount) {
            result[i] = bytes[i];
        }
    }
    for ( ; i < resultCount; ++i) {
        result[i] = 0;
    }

    SkMaskBuilder::FreeImage(src.image());
    SkMaskBuilder::FreeImage(dst.image());
}

// Implement a step function that is 255 between min and max; 0 elsewhere.
static int step(int x, SkScalar min, SkScalar max) {
    if (min < x && x < max) {
        return 255;
    }
    return 0;
}

// Implement a Gaussian function with 0 mean and std.dev. of 'sigma'.
static float gaussian(int x, SkScalar sigma) {
    float k = SK_Scalar1/(sigma * sqrtf(2.0f*SK_ScalarPI));
    float exponent = -(x * x) / (2 * sigma * sigma);
    return k * expf(exponent);
}

// Perform a brute force convolution of a step function with a Gaussian.
// Return the right half in 'result'
static void brute_force_1d(SkScalar stepMin, SkScalar stepMax,
                           SkScalar gaussianSigma,
                           int* result, int resultCount) {

    int gaussianRange = SkScalarCeilToInt(10 * gaussianSigma);

    for (int i = 0; i < resultCount; ++i) {
        SkScalar sum = 0.0f;
        for (int j = -gaussianRange; j < gaussianRange; ++j) {
            sum += gaussian(j, gaussianSigma) * step(i-j, stepMin, stepMax);
        }

        result[i] = SkTPin(SkClampPos(int(sum + 0.5f)), 0, 255);
    }
}

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

    SkScalar midX = path.getBounds().centerX();
    SkScalar midY = path.getBounds().centerY();

    canvas->translate(-midX, -midY);

    SkPaint blurPaint;
    blurPaint.setColor(SK_ColorWHITE);
    blurPaint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, gaussianSigma));

    canvas->drawColor(SK_ColorBLACK);
    canvas->drawPath(path, blurPaint);
}

// Readback the blurred draw results from the canvas
static void readback(const SkBitmap& src, int* result, int resultCount) {
    SkBitmap readback;
    readback.allocN32Pixels(resultCount, 30);
    SkPixmap pm;
    readback.peekPixels(&pm);
    src.readPixels(pm, 0, 0);

    const SkPMColor* pixels = pm.addr32(0, 15);

    for (int i = 0; i < resultCount; ++i) {
        result[i] = SkColorGetR(pixels[i]);
    }
}

// Draw a blurred version of the provided path.
// Return the right half of the middle row in 'result'.
static void cpu_blur_path(const SkPath& path, SkScalar gaussianSigma,
                          int* result, int resultCount) {

    SkBitmap bitmap;
    bitmap.allocN32Pixels(resultCount, 30);
    SkCanvas canvas(bitmap);

    blur_path(&canvas, path, gaussianSigma);
    readback(bitmap, result, resultCount);
}

#if WRITE_CSV
static void write_as_csv(const char* label, SkScalar scale, int* data, int count) {
    SkDebugf("%s_%.2f,", label, scale);
    for (int i = 0; i < count-1; ++i) {
        SkDebugf("%d,", data[i]);
    }
    SkDebugf("%d\n", data[count-1]);
}
#endif

static bool match(int* first, int* second, int count, int tol) {
    int delta;
    for (int i = 0; i < count; ++i) {
        delta = first[i] - second[i];
        if (delta > tol || delta < -tol) {
            return false;
        }
    }

    return true;
}

// Test out the normal blur style with a wide range of sigmas
DEF_TEST(BlurSigmaRange, reporter) {
    static const int kSize = 100;

    // The geometry is offset a smidge to trigger:
    // https://code.google.com/p/chromium/issues/detail?id=282418
    SkPath rectPath = SkPath::Rect({0.3f, 0.3f, 100.3f, 100.3f});

    SkPoint polyPts[] = {
        { 0.3f, 0.3f },
        { 100.3f, 0.3f },
        { 100.3f, 100.3f },
        { 0.3f, 100.3f },
        { 2.3f, 50.3f }     // a little divet to throw off the rect special case
    };
    auto polyPath = SkPath::Polygon(polyPts, true);

    int rectSpecialCaseResult[kSize];
    int generalCaseResult[kSize];
    int groundTruthResult[kSize];
    int bruteForce1DResult[kSize];

    SkScalar sigma = 10.0f;

    for (int i = 0; i < 4; ++i, sigma /= 10) {

        cpu_blur_path(rectPath, sigma, rectSpecialCaseResult, kSize);
        cpu_blur_path(polyPath, sigma, generalCaseResult, kSize);

        ground_truth_2d(100, 100, sigma, groundTruthResult, kSize);
        brute_force_1d(-50.0f, 50.0f, sigma, bruteForce1DResult, kSize);

        REPORTER_ASSERT(reporter, match(rectSpecialCaseResult, bruteForce1DResult, kSize, 5));
        REPORTER_ASSERT(reporter, match(generalCaseResult, bruteForce1DResult, kSize, 15));
        REPORTER_ASSERT(reporter, match(groundTruthResult, bruteForce1DResult, kSize, 1));

#if WRITE_CSV
        write_as_csv("RectSpecialCase", sigma, rectSpecialCaseResult, kSize);
        write_as_csv("GeneralCase", sigma, generalCaseResult, kSize);
        write_as_csv("GPU", sigma, gpuResult, kSize);
        write_as_csv("GroundTruth2D", sigma, groundTruthResult, kSize);
        write_as_csv("BruteForce1D", sigma, bruteForce1DResult, kSize);
#endif
    }
}

///////////////////////////////////////////////////////////////////////////////////////////

DEF_TEST(BlurAsABlur, reporter) {
    const SkBlurStyle styles[] = {
        kNormal_SkBlurStyle, kSolid_SkBlurStyle, kOuter_SkBlurStyle, kInner_SkBlurStyle
    };
    const SkScalar sigmas[] = {
        // values <= 0 should not success for a blur
        -1, 0, 0.5f, 2
    };

    // Test asABlur for SkBlurMaskFilter
    //
    for (size_t i = 0; i < std::size(styles); ++i) {
        const SkBlurStyle style = styles[i];
        for (size_t j = 0; j < std::size(sigmas); ++j) {
            const SkScalar sigma = sigmas[j];
            for (bool respectCTM : { false, true }) {
                sk_sp<SkMaskFilter> mf(SkMaskFilter::MakeBlur(style, sigma, respectCTM));
                if (nullptr == mf.get()) {
                    REPORTER_ASSERT(reporter, sigma <= 0);
                } else {
                    REPORTER_ASSERT(reporter, sigma > 0);
                    SkMaskFilterBase::BlurRec rec;
                    bool success = as_MFB(mf)->asABlur(&rec);
                    if (respectCTM) {
                        REPORTER_ASSERT(reporter, success);
                        REPORTER_ASSERT(reporter, rec.fSigma == sigma);
                        REPORTER_ASSERT(reporter, rec.fStyle == style);
                    } else {
                        REPORTER_ASSERT(reporter, !success);
                    }

                    const SkRect src = {0, 0, 100, 100};
                    SkRect dst;
                    as_MFB(mf)->computeFastBounds(src, &dst);

                    // This is a very conservative test. With more knowledge, we could
                    // consider more stringent tests.
                    REPORTER_ASSERT(reporter, dst.contains(src));
                }
            }
        }
    }

    // Test asABlur for SkEmbossMaskFilter -- should never succeed
    //
    {
        SkEmbossMaskFilter::Light light = {
            { 1, 1, 1 }, 0, 127, 127
        };
        for (size_t j = 0; j < std::size(sigmas); ++j) {
            const SkScalar sigma = sigmas[j];
            auto mf(SkEmbossMaskFilter::Make(sigma, light));
            if (mf) {
                SkMaskFilterBase::BlurRec rec;
                bool success = as_MFB(mf)->asABlur(&rec);
                REPORTER_ASSERT(reporter, !success);
            }
        }
    }
}

// This exercises the problem discovered in crbug.com/570232. The return value from
// SkBlurMask::BoxBlur wasn't being checked in SkBlurMaskFilter.cpp::GrRRectBlurEffect::Create
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SmallBoxBlurBug, reporter, ctxInfo, CtsEnforcement::kNever) {
    SkImageInfo info = SkImageInfo::MakeN32Premul(128, 128);
    auto surface(SkSurfaces::RenderTarget(ctxInfo.directContext(), skgpu::Budgeted::kNo, info));
    SkCanvas* canvas = surface->getCanvas();

    SkRect r = SkRect::MakeXYWH(10, 10, 100, 100);
    SkRRect rr = SkRRect::MakeRectXY(r, 10, 10);

    SkPaint p;
    p.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 0.01f));

    canvas->drawRRect(rr, p);
}

DEF_TEST(BlurredRRectNinePatchComputation, reporter) {
    const SkRect r = SkRect::MakeXYWH(10, 10, 100, 100);
    static const SkScalar kBlurRad = 3.0f;

    bool ninePatchable;
    SkRRect rrectToDraw;
    SkISize size;
    SkScalar rectXs[GrBlurUtils::kBlurRRectMaxDivisions],
             rectYs[GrBlurUtils::kBlurRRectMaxDivisions];
    SkScalar texXs[GrBlurUtils::kBlurRRectMaxDivisions],
             texYs[GrBlurUtils::kBlurRRectMaxDivisions];

    // not nine-patchable
    {
        SkVector radii[4] = { { 100, 100 }, { 0, 0 }, { 100, 100 }, { 0, 0 } };

        SkRRect rr;
        rr.setRectRadii(r, radii);

        ninePatchable = GrBlurUtils::ComputeBlurredRRectParams(rr, rr, kBlurRad, kBlurRad,
                                                                  &rrectToDraw, &size,
                                                                  rectXs, rectYs, texXs, texYs);
        REPORTER_ASSERT(reporter, !ninePatchable);
    }

    // simple circular
    {
        static const SkScalar kCornerRad = 10.0f;
        SkRRect rr;
        rr.setRectXY(r, kCornerRad, kCornerRad);

        ninePatchable = GrBlurUtils::ComputeBlurredRRectParams(rr, rr, kBlurRad, kBlurRad,
                                                                  &rrectToDraw, &size,
                                                                  rectXs, rectYs, texXs, texYs);

        static const SkScalar kAns = 12.0f * kBlurRad + 2.0f * kCornerRad + 1.0f;
        REPORTER_ASSERT(reporter, ninePatchable);
        REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fWidth), kAns));
        REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fHeight), kAns));
    }

    // simple elliptical
    {
        static const SkScalar kXCornerRad = 2.0f;
        static const SkScalar kYCornerRad = 10.0f;
        SkRRect rr;
        rr.setRectXY(r, kXCornerRad, kYCornerRad);

        ninePatchable = GrBlurUtils::ComputeBlurredRRectParams(rr, rr, kBlurRad, kBlurRad,
                                                                  &rrectToDraw, &size,
                                                                  rectXs, rectYs, texXs, texYs);

        static const SkScalar kXAns = 12.0f * kBlurRad + 2.0f * kXCornerRad + 1.0f;
        static const SkScalar kYAns = 12.0f * kBlurRad + 2.0f * kYCornerRad + 1.0f;

        REPORTER_ASSERT(reporter, ninePatchable);
        REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fWidth), kXAns));
        REPORTER_ASSERT(reporter, SkScalarNearlyEqual(SkIntToScalar(size.fHeight), kYAns));
    }
}

// https://crbugs.com/787712
DEF_TEST(EmbossPerlinCrash, reporter) {
    SkPaint p;

    static constexpr SkEmbossMaskFilter::Light light = {
        { 1, 1, 1 }, 0, 127, 127
    };
    p.setMaskFilter(SkEmbossMaskFilter::Make(1, light));
    p.setShader(SkShaders::MakeFractalNoise(1.0f, 1.0f, 2, 0.0f));

    sk_sp<SkSurface> surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(100, 100));
    surface->getCanvas()->drawPaint(p);
}

///////////////////////////////////////////////////////////////////////////////////////////

DEF_TEST(BlurZeroSigma, reporter) {
    auto surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(20, 20));
    SkPaint paint;
    paint.setAntiAlias(true);

    const SkIRect ir = { 5, 5, 15, 15 };
    const SkRect r = SkRect::Make(ir);

    const SkScalar sigmas[] = { 0, SkBits2Float(1) };
    // if sigma is zero (or nearly so), we need to draw correctly (unblurred) and not crash
    // or assert.
    for (auto sigma : sigmas) {
        paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma));
        surf->getCanvas()->drawRect(r, paint);

        ToolUtils::PixelIter iter(surf.get());
        SkIPoint  loc;
        while (const SkPMColor* p = (const SkPMColor*)iter.next(&loc)) {
            if (ir.contains(loc.fX, loc.fY)) {
                // inside the rect we draw (opaque black)
                REPORTER_ASSERT(reporter, *p == SkPackARGB32(0xFF, 0, 0, 0));
            } else {
                // outside the rect we didn't draw at all, no blurred edges
                REPORTER_ASSERT(reporter, *p == 0);
            }
        }
    }
}


///////////////////////////////////////////////////////////////////////////////////////////

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(BlurMaskBiggerThanDest,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    auto context = ctxInfo.directContext();

    SkImageInfo ii = SkImageInfo::Make(32, 32, kRGBA_8888_SkColorType, kPremul_SkAlphaType);

    sk_sp<SkSurface> dst(SkSurfaces::RenderTarget(context, skgpu::Budgeted::kNo, ii));
    if (!dst) {
        ERRORF(reporter, "Could not create surface for test.");
        return;
    }

    SkPaint p;
    p.setColor(SK_ColorRED);
    p.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 3));

    SkCanvas* canvas = dst->getCanvas();

    canvas->clear(SK_ColorBLACK);
    canvas->drawCircle(SkPoint::Make(16, 16), 8, p);

    SkBitmap readback;
    SkAssertResult(readback.tryAllocPixels(ii));

    canvas->readPixels(readback, 0, 0);
    REPORTER_ASSERT(reporter, SkColorGetR(readback.getColor(15, 15)) > 128);
    REPORTER_ASSERT(reporter, SkColorGetG(readback.getColor(15, 15)) == 0);
    REPORTER_ASSERT(reporter, SkColorGetB(readback.getColor(15, 15)) == 0);
    REPORTER_ASSERT(reporter, readback.getColor(31, 31) == SK_ColorBLACK);
}

DEF_TEST(zero_blur, reporter) {
    SkBitmap alpha, bitmap;

    SkPaint paint;
    paint.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3));
    SkIPoint offset;
    bitmap.extractAlpha(&alpha, &paint, nullptr, &offset);
}

///////////////////////////////////////////////////////////////////////////////////////////

// b/444805331 : Fuzzer created a view matrix that did not preserveRightAngles but could still
// result in a rect, resulting in a rect in a rrect only path.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(BlurDegenerateAffineFuzzer,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kNever) {
    auto context = ctxInfo.directContext();
    SkImageInfo ii = SkImageInfo::Make(128, 128, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface(SkSurfaces::RenderTarget(context, skgpu::Budgeted::kNo, ii));
    if (!surface) {
        ERRORF(reporter, "Could not create surface.");
        return;
    }
    SkCanvas* canvas = surface->getCanvas();
    canvas->clear(SK_ColorBLACK);

    SkPaint paint;
    paint.setColor(SK_ColorRED);
    // Set respectCTM to false to get past the skgpu::BlurIsEffectivelyIdentity check
    paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 128.0f, /*respectCTM=*/false));

    // Create a degenerate affine matrix [0 tiny 0][tiny 0 0][0 0 1]. This fails
    // preservesRightAngles() because it's degenerate, but its 90-degree rotational structure still
    // passes rectStaysRect().
    const float tiny = .000001f;
    SkMatrix matrix = SkMatrix::MakeAll(0.f,  tiny, 0.f,
                                        tiny, 0.f,  0.f,
                                        0.f,  0.f,  1.f);

    // Verify our matrix has the magic properties
    REPORTER_ASSERT(reporter, !matrix.preservesRightAngles());
    REPORTER_ASSERT(reporter, matrix.rectStaysRect());

    canvas->concat(matrix);
    canvas->drawRect(SkRect::MakeWH(100.f, 100.f), paint);
    context->flushAndSubmit();  // The test passes if no assertions are hit
}

///////////////////////////////////////////////////////////////////////////////////////////

#if defined(SK_GRAPHITE)

// Reproducing integer overflow in https://g-issues.skia.org/issues/413427423
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(BlurPointCircle,
                                         reporter,
                                         context,
                                         CtsEnforcement::kNever) {
    using namespace skgpu::graphite;
    SkImageInfo ii = SkImageInfo::Make(SkISize::Make(1, 1),
                                       SkColorType::kRGBA_8888_SkColorType,
                                       SkAlphaType::kPremul_SkAlphaType);
    std::unique_ptr<Recorder> recorder = context->makeRecorder();
    sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(recorder.get(), ii);
    SkCanvas* canvas = surface->getCanvas();

    SkPaint paint;
    paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 5.f, /*respectCTM=*/false));

    canvas->concat(SkMatrix::MakeAll(0.000256608007f, 0.f, 0.f,
                                     0.f, 0.000256608007f, 0.f,
                                     0.f, 0.f, 1.f));
    canvas->drawArc(SkRect::MakeLTRB(-1, -1, 1, 1), 0.f, 360.f, false, paint);

    (void) recorder->snap();
}

#endif // SK_GRAPHITE
