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

#include "SkRRectsGaussianEdgeMaskFilter.h"
#include "SkReadBuffer.h"
#include "SkRRect.h"
#include "SkWriteBuffer.h"

#if SK_SUPPORT_GPU
#include "GrFragmentProcessor.h"
#endif

 /** \class SkRRectsGaussianEdgeMaskFilterImpl
  * This mask filter applies a gaussian edge to the intersection of two round rects.
  * The round rects must have the same radii at each corner and the x&y radii
  * must also be equal.
  */
class SkRRectsGaussianEdgeMaskFilterImpl : public SkMaskFilter {
public:
    SkRRectsGaussianEdgeMaskFilterImpl(const SkRRect& first, const SkRRect& second,
                                       SkScalar radius)
        : fFirst(first)
        , fSecond(second)
        , fRadius(radius) {
    }

    SkMask::Format getFormat() const override { return SkMask::kA8_Format; }
    bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
                    SkIPoint* margin) const override;

#if SK_SUPPORT_GPU
    bool asFragmentProcessor(GrFragmentProcessor**) const override;
#endif

    SK_TO_STRING_OVERRIDE()
    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRRectsGaussianEdgeMaskFilterImpl)

protected:
    void flatten(SkWriteBuffer&) const override;

private:
    SkRRect  fFirst;
    SkRRect  fSecond;
    SkScalar fRadius;

    friend class SkRRectsGaussianEdgeMaskFilter; // for serialization registration system

    typedef SkMaskFilter INHERITED;
};

// x & y are in device space
static SkScalar compute_rrect_normalized_dist(const SkRRect& rr, const SkPoint& p, SkScalar rad) {
    SkASSERT(rr.getType() == SkRRect::kOval_Type || rr.getType() == SkRRect::kRect_Type ||
             rr.getType() == SkRRect::kSimple_Type);
    SkASSERT(rad > 0.0f);

    SkVector delta = { SkTAbs(p.fX - rr.rect().centerX()), SkTAbs(p.fY - rr.rect().centerY()) };

    SkScalar halfW = 0.5f * rr.rect().width();
    SkScalar halfH = 0.5f * rr.rect().height();
    SkScalar invRad = 1.0f/rad;

    const SkVector& radii = rr.getSimpleRadii();
    SkASSERT(SkScalarNearlyEqual(radii.fX, radii.fY));

    switch (rr.getType()) {
        case SkRRect::kOval_Type: {
            float scaledDist = delta.length() * invRad;
            return SkTPin(halfW * invRad - scaledDist, 0.0f, 1.0f);
        }
        case SkRRect::kRect_Type: {
            SkScalar xDist = (halfW - delta.fX) * invRad;
            SkScalar yDist = (halfH - delta.fY) * invRad;

            SkVector v = { 1.0f - SkTPin(xDist, 0.0f, 1.0f), 1.0f - SkTPin(yDist, 0.0f, 1.0f) };
            return SkTPin(1.0f - v.length(), 0.0f, 1.0f);
        }
        case SkRRect::kSimple_Type: {

            //----------------
            // ice-cream-cone fractional distance computation

            // When the blurRadius is larger than the corner radius we want to use it to
            // compute the pointy end of the ice cream cone. If it smaller we just want to use
            // the center of the corner's circle. When using the blurRadius the inset amount
            // can't exceed the halfwidths of the RRect.
            SkScalar insetDist = SkTMin(SkTMax(rad, radii.fX), SkTMin(halfW, halfH));

            // "maxValue" is a correction term for if the blurRadius is larger than the
            // size of the RRect. In that case we don't want to go all the way to black.
            SkScalar maxValue = insetDist * invRad;

            SkVector coneBottom = { halfW - insetDist, halfH - insetDist };
            SkVector ptInConeSpace = delta - coneBottom;

            SkVector cornerTop = { halfW - radii.fX - coneBottom.fX, halfH - coneBottom.fY };
            SkVector cornerRight = { halfW - coneBottom.fX, halfH - radii.fY - coneBottom.fY };

            SkScalar cross1 = ptInConeSpace.cross(cornerTop);
            SkScalar cross2 = cornerRight.cross(ptInConeSpace);
            bool inCone = cross1 > 0.0f && cross2 > 0.0f;

            if (!inCone) {
                SkScalar xDist = (halfW - delta.fX) * invRad;
                SkScalar yDist = (halfH - delta.fY) * invRad;

                return SkTPin(SkTMin(xDist, yDist), 0.0f, 1.0f); // perpendicular distance
            }

            SkVector cornerCenterInConeSpace = { insetDist - radii.fX, insetDist - radii.fY };

            SkVector connectingVec = ptInConeSpace - cornerCenterInConeSpace;
            float distToPtInConeSpace = SkPoint::Normalize(&ptInConeSpace);

            // "a" (i.e., dot(ptInConeSpace, ptInConeSpace) should always be 1.0f since
            // ptInConeSpace is now normalized
            SkScalar b = 2.0f * ptInConeSpace.dot(connectingVec);
            SkScalar c = connectingVec.dot(connectingVec) - radii.fX * radii.fY;

            // lop off negative values that are outside the cone
            SkScalar coneDist = SkTMax(0.0f, 0.5f * (-b + SkScalarSqrt(b*b - 4*c)));

            // make the coneDist a fraction of how far it is from the edge to the cone's base
            coneDist = (maxValue*coneDist) / (coneDist+distToPtInConeSpace);
            return SkTPin(coneDist, 0.0f, 1.0f);
        }
        default:
            return 0.0f;
    }
}

bool SkRRectsGaussianEdgeMaskFilterImpl::filterMask(SkMask* dst, const SkMask& src,
                                                    const SkMatrix& matrix,
                                                    SkIPoint* margin) const {

    if (src.fFormat != SkMask::kA8_Format) {
        return false;
    }

    if (margin) {
        margin->set(0, 0);
    }

    dst->fBounds = src.fBounds;
    dst->fRowBytes = dst->fBounds.width();
    dst->fFormat = SkMask::kA8_Format;
    dst->fImage = nullptr;

    if (src.fImage) {
        size_t dstSize = dst->computeImageSize();
        if (0 == dstSize) {
            return false;   // too big to allocate, abort
        }

        const uint8_t* srcPixels = src.fImage;
        uint8_t* dstPixels = dst->fImage = SkMask::AllocImage(dstSize);

        SkPoint basePt = { SkIntToScalar(src.fBounds.fLeft), SkIntToScalar(src.fBounds.fTop) };

        for (int y = 0; y < dst->fBounds.height(); ++y) {
            const uint8_t* srcRow = srcPixels + y * dst->fRowBytes;
            uint8_t* dstRow = dstPixels + y*dst->fRowBytes;

            for (int x = 0; x < dst->fBounds.width(); ++x) {
                SkPoint curPt = { basePt.fX + x, basePt.fY + y };

                SkVector vec;
                vec.fX = 1.0f - compute_rrect_normalized_dist(fFirst, curPt, fRadius);
                vec.fY = 1.0f - compute_rrect_normalized_dist(fSecond, curPt, fRadius);

                SkScalar factor = SkTPin(vec.length(), 0.0f, 1.0f);
                factor = exp(-factor * factor * 4.0f) - 0.018f;
                SkASSERT(factor >= 0.0f && factor <= 1.0f);

                dstRow[x] = (uint8_t) (factor * srcRow[x]);
            }
        }
    }

    return true;
}

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

#if SK_SUPPORT_GPU

#include "GrCoordTransform.h"
#include "GrFragmentProcessor.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"
#include "SkGr.h"

class RRectsGaussianEdgeFP : public GrFragmentProcessor {
public:
    enum Mode {
        kCircle_Mode,
        kRect_Mode,
        kSimpleCircular_Mode,
    };

    static std::unique_ptr<GrFragmentProcessor> Make(const SkRRect& first, const SkRRect& second,
                                                     SkScalar radius) {
        return std::unique_ptr<GrFragmentProcessor>(
                new RRectsGaussianEdgeFP(first, second, radius));
    }

    const char* name() const override { return "RRectsGaussianEdgeFP"; }

    std::unique_ptr<GrFragmentProcessor> clone() const override {
        return std::unique_ptr<GrFragmentProcessor>(new RRectsGaussianEdgeFP(*this));
    }

    const SkRRect& first() const { return fFirst; }
    Mode firstMode() const { return fFirstMode; }
    const SkRRect& second() const { return fSecond; }
    Mode secondMode() const { return fSecondMode; }
    SkScalar radius() const { return fRadius; }

private:
    class GLSLRRectsGaussianEdgeFP : public GrGLSLFragmentProcessor {
    public:
        GLSLRRectsGaussianEdgeFP() {}

        // This method emits code so that, for each shape, the distance from the edge is returned
        // in 'outputName' clamped to 0..1 with positive distance being towards the center of the
        // shape. The distance will have been normalized by the radius.
        void emitModeCode(Mode mode,
                          GrGLSLFPFragmentBuilder* fragBuilder,
                          const char* posName,
                          const char* sizesName,
                          const char* radiiName,
                          const char* radName,
                          const char* outputName,
                          const char  indices[2]) { // how to access the params for the 2 rrects

            // Positive distance is towards the center of the circle.
            // Map all the cases to the lower right quadrant.
            fragBuilder->codeAppendf("half2 delta = abs(sk_FragCoord.xy - %s.%s);",
                                     posName, indices);

            switch (mode) {
                case kCircle_Mode:
                    // When a shadow circle gets large we can have some precision issues if
                    // we do "length(delta)/radius". The scaleDist temporary cuts the
                    // delta vector down a bit before invoking length.
                    fragBuilder->codeAppendf("half scaledDist = length(delta/%s);", radName);
                    fragBuilder->codeAppendf("%s = clamp((%s.%c/%s - scaledDist), 0.0, 1.0);",
                                             outputName, sizesName, indices[0], radName);
                    break;
                case kRect_Mode:
                    fragBuilder->codeAppendf(
                        "half2 rectDist = half2(1.0 - clamp((%s.%c - delta.x)/%s, 0.0, 1.0),"
                                               "1.0 - clamp((%s.%c - delta.y)/%s, 0.0, 1.0));",
                        sizesName, indices[0], radName,
                        sizesName, indices[1], radName);
                    fragBuilder->codeAppendf("%s = clamp(1.0 - length(rectDist), 0.0, 1.0);",
                                             outputName);
                    break;
                case kSimpleCircular_Mode:
                    // For the circular round rect we combine 2 distances:
                    //    the fractional position from the corner inset point to the corner's circle
                    //    the minimum perpendicular distance to the bounding rectangle
                    // The first distance is used when the pixel is inside the ice-cream-cone-shaped
                    // portion of a corner. The second is used everywhere else.
                    // This is intended to approximate the interpolation pattern if we had
                    // tessellated this geometry into a RRect outside and a rect inside.

                    //----------------
                    // rect distance computation
                    fragBuilder->codeAppendf("half xDist = (%s.%c - delta.x) / %s;",
                                             sizesName, indices[0], radName);
                    fragBuilder->codeAppendf("half yDist = (%s.%c - delta.y) / %s;",
                                             sizesName, indices[1], radName);
                    fragBuilder->codeAppend("half rectDist = clamp(min(xDist, yDist), 0.0, 1.0);");

                    //----------------
                    // ice-cream-cone fractional distance computation

                    // When the blurRadius is larger than the corner radius we want to use it to
                    // compute the pointy end of the ice cream cone. If it smaller we just want to
                    // use the center of the corner's circle. When using the blurRadius the inset
                    // amount can't exceed the halfwidths of the RRect.
                    fragBuilder->codeAppendf("half insetDist = min(max(%s, %s.%c),"
                                                                   "min(%s.%c, %s.%c));",
                                             radName, radiiName, indices[0],
                                             sizesName, indices[0], sizesName, indices[1]);
                    // "maxValue" is a correction term for if the blurRadius is larger than the
                    // size of the RRect. In that case we don't want to go all the way to black.
                    fragBuilder->codeAppendf("half maxValue = insetDist/%s;", radName);

                    fragBuilder->codeAppendf("half2 coneBottom = half2(%s.%c - insetDist,"
                                                                       "%s.%c - insetDist);",
                                             sizesName, indices[0], sizesName, indices[1]);

                    fragBuilder->codeAppendf("half2 cornerTop = half2(%s.%c - %s.%c, %s.%c) -"
                                                                        "coneBottom;",
                                             sizesName, indices[0], radiiName, indices[0],
                                             sizesName, indices[1]);
                    fragBuilder->codeAppendf("half2 cornerRight = half2(%s.%c, %s.%c - %s.%c) -"
                                                                        "coneBottom;",
                                             sizesName, indices[0],
                                             sizesName, indices[1], radiiName, indices[1]);

                    fragBuilder->codeAppend("half2 ptInConeSpace = delta - coneBottom;");
                    fragBuilder->codeAppend("half distToPtInConeSpace = length(ptInConeSpace);");

                    fragBuilder->codeAppend("half cross1 =  ptInConeSpace.x * cornerTop.y -"
                                                           "ptInConeSpace.y * cornerTop.x;");
                    fragBuilder->codeAppend("half cross2 = -ptInConeSpace.x * cornerRight.y + "
                                                           "ptInConeSpace.y * cornerRight.x;");

                    fragBuilder->codeAppend("half inCone = step(0.0, cross1) *"
                                                          "step(0.0, cross2);");

                    fragBuilder->codeAppendf("half2 cornerCenterInConeSpace = half2(insetDist -"
                                                                                 "%s.%c);",
                                             radiiName, indices[0]);

                    fragBuilder->codeAppend("half2 connectingVec = ptInConeSpace -"
                                                                        "cornerCenterInConeSpace;");
                    fragBuilder->codeAppend("ptInConeSpace = normalize(ptInConeSpace);");

                    // "a" (i.e., dot(ptInConeSpace, ptInConeSpace) should always be 1.0f since
                    // ptInConeSpace is now normalized
                    fragBuilder->codeAppend("half b = 2.0 * dot(ptInConeSpace, connectingVec);");
                    fragBuilder->codeAppendf("half c = dot(connectingVec, connectingVec) - "
                                                                                   "%s.%c * %s.%c;",
                                             radiiName, indices[0], radiiName, indices[0]);

                    fragBuilder->codeAppend("half fourAC = 4*c;");
                    // This max prevents sqrt(-1) when outside the cone
                    fragBuilder->codeAppend("half bSq = max(b*b, fourAC);");

                    // lop off negative values that are outside the cone
                    fragBuilder->codeAppend("half coneDist = "
                                                    "max(0.0, 0.5 * (-b + sqrt(bSq - fourAC)));");
                    // make the coneDist a fraction of how far it is from the edge to the
                    // cone's base
                    fragBuilder->codeAppend("coneDist = (maxValue*coneDist) /"
                                                                "(coneDist+distToPtInConeSpace);");
                    fragBuilder->codeAppend("coneDist = clamp(coneDist, 0.0, 1.0);");

                    //----------------
                    fragBuilder->codeAppendf("%s = mix(rectDist, coneDist, inCone);", outputName);
                    break;
                }
        }

        void emitCode(EmitArgs& args) override {
            const RRectsGaussianEdgeFP& fp = args.fFp.cast<RRectsGaussianEdgeFP>();
            GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
            GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;

            const char* positionsUniName = nullptr;
            fPositionsUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
                                                       "Positions", &positionsUniName);
            const char* sizesUniName = nullptr;
            fSizesUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
                                                   kDefault_GrSLPrecision, "Sizes", &sizesUniName);
            const char* radiiUniName = nullptr;
            if (fp.fFirstMode == kSimpleCircular_Mode || fp.fSecondMode == kSimpleCircular_Mode) {
                fRadiiUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
                                                       "Radii", &radiiUniName);
            }
            const char* radUniName = nullptr;
            fRadiusUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
                                                    "Radius", &radUniName);

            fragBuilder->codeAppend("half firstDist;");
            fragBuilder->codeAppend("{");
            this->emitModeCode(fp.firstMode(), fragBuilder,
                               positionsUniName, sizesUniName, radiiUniName,
                               radUniName, "firstDist", "xy");
            fragBuilder->codeAppend("}");

            fragBuilder->codeAppend("half secondDist;");
            fragBuilder->codeAppend("{");
            this->emitModeCode(fp.secondMode(), fragBuilder,
                               positionsUniName, sizesUniName, radiiUniName,
                               radUniName, "secondDist", "zw");
            fragBuilder->codeAppend("}");

            fragBuilder->codeAppend("half2 distVec = half2(1.0 - firstDist, 1.0 - secondDist);");

            // Finally use the distance to apply the Gaussian edge
            fragBuilder->codeAppend("half factor = clamp(length(distVec), 0.0, 1.0);");
            fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
            fragBuilder->codeAppendf("%s = factor*%s;",
                                     args.fOutputColor, args.fInputColor);
        }

        static void GenKey(const GrProcessor& proc, const GrShaderCaps&, GrProcessorKeyBuilder* b) {
            const RRectsGaussianEdgeFP& fp = proc.cast<RRectsGaussianEdgeFP>();

            b->add32(fp.firstMode() | (fp.secondMode() << 4));
        }

    protected:
        void onSetData(const GrGLSLProgramDataManager& pdman,
                       const GrFragmentProcessor& proc) override {
            const RRectsGaussianEdgeFP& edgeFP = proc.cast<RRectsGaussianEdgeFP>();

            const SkRRect& first = edgeFP.first();
            const SkRRect& second = edgeFP.second();

            pdman.set4f(fPositionsUni,
                        first.getBounds().centerX(),
                        first.getBounds().centerY(),
                        second.getBounds().centerX(),
                        second.getBounds().centerY());

            pdman.set4f(fSizesUni, 
                        0.5f * first.rect().width(),
                        0.5f * first.rect().height(),
                        0.5f * second.rect().width(),
                        0.5f * second.rect().height());

            if (edgeFP.firstMode() == kSimpleCircular_Mode ||
                edgeFP.secondMode() == kSimpleCircular_Mode) {
                // This is a bit of overkill since fX should equal fY for both round rects but it
                // makes the shader code simpler.
                pdman.set4f(fRadiiUni, 
                            first.getSimpleRadii().fX,  first.getSimpleRadii().fY,
                            second.getSimpleRadii().fX, second.getSimpleRadii().fY);
            }

            pdman.set1f(fRadiusUni, edgeFP.radius());
        }

    private:
        // The centers of the two round rects (x1, y1, x2, y2)
        GrGLSLProgramDataManager::UniformHandle fPositionsUni;

        // The half widths and half heights of the two round rects (w1/2, h1/2, w2/2, h2/2)
        // For circles we still upload both width & height to simplify things
        GrGLSLProgramDataManager::UniformHandle fSizesUni;

        // The corner radii of the two round rects (rx1, ry1, rx2, ry2)
        // We upload both the x&y radii (although they are currently always the same) to make
        // the indexing in the shader code simpler. In some future world we could also support
        // non-circular corner round rects & ellipses.
        GrGLSLProgramDataManager::UniformHandle fRadiiUni;

        // The radius parameters (radius)
        GrGLSLProgramDataManager::UniformHandle fRadiusUni;

        typedef GrGLSLFragmentProcessor INHERITED;
    };

    void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
        GLSLRRectsGaussianEdgeFP::GenKey(*this, caps, b);
    }

    RRectsGaussianEdgeFP(const SkRRect& first, const SkRRect& second, SkScalar radius)
            : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
            , fFirst(first)
            , fSecond(second)
            , fRadius(radius) {
        this->initClassID<RRectsGaussianEdgeFP>();

        fFirstMode = ComputeMode(fFirst);
        fSecondMode = ComputeMode(fSecond);
    }
    RRectsGaussianEdgeFP(const RRectsGaussianEdgeFP& that)
            : INHERITED(kCompatibleWithCoverageAsAlpha_OptimizationFlag)
            , fFirst(that.fFirst)
            , fFirstMode(that.fFirstMode)
            , fSecond(that.fSecond)
            , fSecondMode(that.fSecondMode)
            , fRadius(that.fRadius) {
        this->initClassID<RRectsGaussianEdgeFP>();
    }

    static Mode ComputeMode(const SkRRect& rr) {
        if (rr.isCircle()) {
            return kCircle_Mode;
        } else if (rr.isRect()) {
            return kRect_Mode;
        } else {
            SkASSERT(rr.isSimpleCircular());
            return kSimpleCircular_Mode;
        }
    }

    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
        return new GLSLRRectsGaussianEdgeFP;
    }

    bool onIsEqual(const GrFragmentProcessor& proc) const override {
        const RRectsGaussianEdgeFP& edgeFP = proc.cast<RRectsGaussianEdgeFP>();
        return fFirst  == edgeFP.fFirst &&
               fSecond == edgeFP.fSecond && 
               fRadius == edgeFP.fRadius;
    }

    SkRRect  fFirst;
    Mode     fFirstMode;
    SkRRect  fSecond;
    Mode     fSecondMode;
    SkScalar fRadius;

    typedef GrFragmentProcessor INHERITED;
};

////////////////////////////////////////////////////////////////////////////
bool SkRRectsGaussianEdgeMaskFilterImpl::asFragmentProcessor(GrFragmentProcessor** fp) const {
    if (fp) {
        *fp = RRectsGaussianEdgeFP::Make(fFirst, fSecond, fRadius).release();
    }

    return true;
}

#endif

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

#ifndef SK_IGNORE_TO_STRING
void SkRRectsGaussianEdgeMaskFilterImpl::toString(SkString* str) const {
    str->appendf("RRectsGaussianEdgeMaskFilter: ()");
}
#endif

sk_sp<SkFlattenable> SkRRectsGaussianEdgeMaskFilterImpl::CreateProc(SkReadBuffer& buf) {
    SkRect rect1, rect2;

    buf.readRect(&rect1);
    SkScalar xRad1 = buf.readScalar();
    SkScalar yRad1 = buf.readScalar();

    buf.readRect(&rect2);
    SkScalar xRad2 = buf.readScalar();
    SkScalar yRad2 = buf.readScalar();

    SkScalar radius = buf.readScalar();

    return sk_make_sp<SkRRectsGaussianEdgeMaskFilterImpl>(SkRRect::MakeRectXY(rect1, xRad1, yRad1),
                                                          SkRRect::MakeRectXY(rect2, xRad2, yRad2),
                                                          radius);
}

void SkRRectsGaussianEdgeMaskFilterImpl::flatten(SkWriteBuffer& buf) const {
    INHERITED::flatten(buf);

    SkASSERT(fFirst.isRect() || fFirst.isCircle() || fFirst.isSimpleCircular());
    buf.writeRect(fFirst.rect());
    const SkVector& radii1 = fFirst.getSimpleRadii();
    buf.writeScalar(radii1.fX);
    buf.writeScalar(radii1.fY);

    SkASSERT(fSecond.isRect() || fSecond.isCircle() || fSecond.isSimpleCircular());
    buf.writeRect(fSecond.rect());
    const SkVector& radii2 = fSecond.getSimpleRadii();
    buf.writeScalar(radii2.fX);
    buf.writeScalar(radii2.fY);

    buf.writeScalar(fRadius);
}

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

sk_sp<SkMaskFilter> SkRRectsGaussianEdgeMaskFilter::Make(const SkRRect& first,
                                                         const SkRRect& second,
                                                         SkScalar radius) {
    if ((!first.isRect()  && !first.isCircle()  && !first.isSimpleCircular()) || 
        (!second.isRect() && !second.isCircle() && !second.isSimpleCircular())) {
        // we only deal with the shapes where the x & y radii are equal 
        // and the same for all four corners
        return nullptr;
    }

    return sk_make_sp<SkRRectsGaussianEdgeMaskFilterImpl>(first, second, radius);
}

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

SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkRRectsGaussianEdgeMaskFilter)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRRectsGaussianEdgeMaskFilterImpl)
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END

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