/*
 * 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 "src/gpu/ganesh/ops/ShadowRRectOp.h"

#include "include/core/SkBitmap.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRRect.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/gpu/ganesh/GrTypes.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkPoint_impl.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTo.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkColorData.h"
#include "src/core/SkRRectPriv.h"
#include "src/gpu/ResourceKey.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrBuffer.h"
#include "src/gpu/ganesh/GrGeometryProcessor.h"
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrPipeline.h"
#include "src/gpu/ganesh/GrProcessorSet.h"
#include "src/gpu/ganesh/GrProgramInfo.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrSimpleMesh.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrThreadSafeCache.h"
#include "src/gpu/ganesh/GrUserStencilSettings.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/effects/GrShadowGeoProc.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"

#if defined(GPU_TEST_UTILS)
#include "src/base/SkRandom.h"
#include "src/gpu/ganesh/GrDrawOpTest.h"
#include "src/gpu/ganesh/GrTestUtils.h"
#endif

#include <algorithm>
#include <array>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <tuple>
#include <utility>

class GrCaps;
class GrDstProxyView;
class SkArenaAlloc;
enum class GrXferBarrierFlags;
namespace skgpu {
enum class Mipmapped : bool;
}
namespace skgpu::ganesh {
class SurfaceDrawContext;
}

using namespace skia_private;

namespace {

///////////////////////////////////////////////////////////////////////////////
// Circle Data
//
// We have two possible cases for geometry for a circle:

// In the case of a normal fill, we draw geometry for the circle as an octagon.
static const uint16_t gFillCircleIndices[] = {
        // enter the octagon
        // clang-format off
        0, 1, 8, 1, 2, 8,
        2, 3, 8, 3, 4, 8,
        4, 5, 8, 5, 6, 8,
        6, 7, 8, 7, 0, 8,
        // clang-format on
};

// For stroked circles, we use two nested octagons.
static const uint16_t gStrokeCircleIndices[] = {
        // enter the octagon
        // clang-format off
        0, 1,  9, 0,  9,  8,
        1, 2, 10, 1, 10,  9,
        2, 3, 11, 2, 11, 10,
        3, 4, 12, 3, 12, 11,
        4, 5, 13, 4, 13, 12,
        5, 6, 14, 5, 14, 13,
        6, 7, 15, 6, 15, 14,
        7, 0,  8, 7,  8, 15,
        // clang-format on
};

static const int kIndicesPerFillCircle = std::size(gFillCircleIndices);
static const int kIndicesPerStrokeCircle = std::size(gStrokeCircleIndices);
static const int kVertsPerStrokeCircle = 16;
static const int kVertsPerFillCircle = 9;

int circle_type_to_vert_count(bool stroked) {
    return stroked ? kVertsPerStrokeCircle : kVertsPerFillCircle;
}

int circle_type_to_index_count(bool stroked) {
    return stroked ? kIndicesPerStrokeCircle : kIndicesPerFillCircle;
}

const uint16_t* circle_type_to_indices(bool stroked) {
    return stroked ? gStrokeCircleIndices : gFillCircleIndices;
}

///////////////////////////////////////////////////////////////////////////////
// RoundRect Data
//
// The geometry for a shadow roundrect is similar to a 9-patch:
//    ____________
//   |_|________|_|
//   | |        | |
//   | |        | |
//   | |        | |
//   |_|________|_|
//   |_|________|_|
//
// However, each corner is rendered as a fan rather than a simple quad, as below. (The diagram
// shows the upper part of the upper left corner. The bottom triangle would similarly be split
// into two triangles.)
//    ________
//   |\  \   |
//   |  \ \  |
//   |    \\ |
//   |      \|
//   --------
//
// The center of the fan handles the curve of the corner. For roundrects where the stroke width
// is greater than the corner radius, the outer triangles blend from the curve to the straight
// sides. Otherwise these triangles will be degenerate.
//
// In the case where the stroke width is greater than the corner radius and the
// blur radius (overstroke), we add additional geometry to mark out the rectangle in the center.
// This rectangle extends the coverage values of the center edges of the 9-patch.
//    ____________
//   |_|________|_|
//   | |\ ____ /| |
//   | | |    | | |
//   | | |____| | |
//   |_|/______\|_|
//   |_|________|_|
//
// For filled rrects we reuse the stroke geometry but add an additional quad to the center.

static const uint16_t gRRectIndices[] = {
    // clang-format off
    // overstroke quads
    // we place this at the beginning so that we can skip these indices when rendering as filled
    0, 6, 25, 0, 25, 24,
    6, 18, 27, 6, 27, 25,
    18, 12, 26, 18, 26, 27,
    12, 0, 24, 12, 24, 26,

    // corners
    0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5,
    6, 11, 10, 6, 10, 9, 6, 9, 8, 6, 8, 7,
    12, 17, 16, 12, 16, 15, 12, 15, 14, 12, 14, 13,
    18, 19, 20, 18, 20, 21, 18, 21, 22, 18, 22, 23,

    // edges
    0, 5, 11, 0, 11, 6,
    6, 7, 19, 6, 19, 18,
    18, 23, 17, 18, 17, 12,
    12, 13, 1, 12, 1, 0,

    // fill quad
    // we place this at the end so that we can skip these indices when rendering as stroked
    0, 6, 18, 0, 18, 12,
    // clang-format on
};

// overstroke count
static const int kIndicesPerOverstrokeRRect = std::size(gRRectIndices) - 6;
// simple stroke count skips overstroke indices
static const int kIndicesPerStrokeRRect = kIndicesPerOverstrokeRRect - 6*4;
// fill count adds final quad to stroke count
static const int kIndicesPerFillRRect = kIndicesPerStrokeRRect + 6;
static const int kVertsPerStrokeRRect = 24;
static const int kVertsPerOverstrokeRRect = 28;
static const int kVertsPerFillRRect = 24;

enum RRectType {
    kFill_RRectType,
    kStroke_RRectType,
    kOverstroke_RRectType,
};

int rrect_type_to_vert_count(RRectType type) {
    switch (type) {
        case kFill_RRectType:
            return kVertsPerFillRRect;
        case kStroke_RRectType:
            return kVertsPerStrokeRRect;
        case kOverstroke_RRectType:
            return kVertsPerOverstrokeRRect;
    }
    SK_ABORT("Invalid type");
}

int rrect_type_to_index_count(RRectType type) {
    switch (type) {
        case kFill_RRectType:
            return kIndicesPerFillRRect;
        case kStroke_RRectType:
            return kIndicesPerStrokeRRect;
        case kOverstroke_RRectType:
            return kIndicesPerOverstrokeRRect;
    }
    SK_ABORT("Invalid type");
}

const uint16_t* rrect_type_to_indices(RRectType type) {
    switch (type) {
        case kFill_RRectType:
        case kStroke_RRectType:
            return gRRectIndices + 6*4;
        case kOverstroke_RRectType:
            return gRRectIndices;
    }
    SK_ABORT("Invalid type");
}

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

class ShadowCircularRRectOp final : public GrMeshDrawOp {
public:
    DEFINE_OP_CLASS_ID

    // An insetWidth > 1/2 rect width or height indicates a simple fill.
    ShadowCircularRRectOp(GrColor color, const SkRect& devRect,
                          float devRadius, bool isCircle, float blurRadius, float insetWidth,
                          GrSurfaceProxyView falloffView)
            : INHERITED(ClassID())
            , fFalloffView(std::move(falloffView)) {
        SkRect bounds = devRect;
        SkASSERT(insetWidth > 0);
        SkScalar innerRadius = 0.0f;
        SkScalar outerRadius = devRadius;
        SkScalar umbraInset;

        RRectType type = kFill_RRectType;
        if (isCircle) {
            umbraInset = 0;
        } else {
            umbraInset = std::max(outerRadius, blurRadius);
        }

        // If stroke is greater than width or height, this is still a fill,
        // otherwise we compute stroke params.
        if (isCircle) {
            innerRadius = devRadius - insetWidth;
            type = innerRadius > 0 ? kStroke_RRectType : kFill_RRectType;
        } else {
            if (insetWidth <= 0.5f*std::min(devRect.width(), devRect.height())) {
                // We don't worry about a real inner radius, we just need to know if we
                // need to create overstroke vertices.
                innerRadius = std::max(insetWidth - umbraInset, 0.0f);
                type = innerRadius > 0 ? kOverstroke_RRectType : kStroke_RRectType;
            }
        }

        this->setBounds(bounds, HasAABloat::kNo, IsHairline::kNo);

        fGeoData.emplace_back(Geometry{color, outerRadius, umbraInset, innerRadius,
                                       blurRadius, bounds, type, isCircle});
        if (isCircle) {
            fVertCount = circle_type_to_vert_count(kStroke_RRectType == type);
            fIndexCount = circle_type_to_index_count(kStroke_RRectType == type);
        } else {
            fVertCount = rrect_type_to_vert_count(type);
            fIndexCount = rrect_type_to_index_count(type);
        }
    }

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

    FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }

    GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override {
        return GrProcessorSet::EmptySetAnalysis();
    }

private:
    struct Geometry {
        GrColor   fColor;
        SkScalar  fOuterRadius;
        SkScalar  fUmbraInset;
        SkScalar  fInnerRadius;
        SkScalar  fBlurRadius;
        SkRect    fDevBounds;
        RRectType fType;
        bool      fIsCircle;
    };

    struct CircleVertex {
        SkPoint fPos;
        GrColor fColor;
        SkPoint fOffset;
        SkScalar fDistanceCorrection;
    };

    void fillInCircleVerts(const Geometry& args, bool isStroked, CircleVertex** verts) const {

        GrColor color = args.fColor;
        SkScalar outerRadius = args.fOuterRadius;
        SkScalar innerRadius = args.fInnerRadius;
        SkScalar blurRadius = args.fBlurRadius;
        SkScalar distanceCorrection = outerRadius / blurRadius;

        const SkRect& bounds = args.fDevBounds;

        // The inner radius in the vertex data must be specified in normalized space.
        innerRadius = innerRadius / outerRadius;

        SkPoint center = SkPoint::Make(bounds.centerX(), bounds.centerY());
        SkScalar halfWidth = 0.5f * bounds.width();
        SkScalar octOffset = 0.41421356237f;  // sqrt(2) - 1

        (*verts)->fPos = center + SkPoint::Make(-octOffset * halfWidth, -halfWidth);
        (*verts)->fColor = color;
        (*verts)->fOffset = SkPoint::Make(-octOffset, -1);
        (*verts)->fDistanceCorrection = distanceCorrection;
        (*verts)++;

        (*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, -halfWidth);
        (*verts)->fColor = color;
        (*verts)->fOffset = SkPoint::Make(octOffset, -1);
        (*verts)->fDistanceCorrection = distanceCorrection;
        (*verts)++;

        (*verts)->fPos = center + SkPoint::Make(halfWidth, -octOffset * halfWidth);
        (*verts)->fColor = color;
        (*verts)->fOffset = SkPoint::Make(1, -octOffset);
        (*verts)->fDistanceCorrection = distanceCorrection;
        (*verts)++;

        (*verts)->fPos = center + SkPoint::Make(halfWidth, octOffset * halfWidth);
        (*verts)->fColor = color;
        (*verts)->fOffset = SkPoint::Make(1, octOffset);
        (*verts)->fDistanceCorrection = distanceCorrection;
        (*verts)++;

        (*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, halfWidth);
        (*verts)->fColor = color;
        (*verts)->fOffset = SkPoint::Make(octOffset, 1);
        (*verts)->fDistanceCorrection = distanceCorrection;
        (*verts)++;

        (*verts)->fPos = center + SkPoint::Make(-octOffset * halfWidth, halfWidth);
        (*verts)->fColor = color;
        (*verts)->fOffset = SkPoint::Make(-octOffset, 1);
        (*verts)->fDistanceCorrection = distanceCorrection;
        (*verts)++;

        (*verts)->fPos = center + SkPoint::Make(-halfWidth, octOffset * halfWidth);
        (*verts)->fColor = color;
        (*verts)->fOffset = SkPoint::Make(-1, octOffset);
        (*verts)->fDistanceCorrection = distanceCorrection;
        (*verts)++;

        (*verts)->fPos = center + SkPoint::Make(-halfWidth, -octOffset * halfWidth);
        (*verts)->fColor = color;
        (*verts)->fOffset = SkPoint::Make(-1, -octOffset);
        (*verts)->fDistanceCorrection = distanceCorrection;
        (*verts)++;

        if (isStroked) {
            // compute the inner ring

            // cosine and sine of pi/8
            SkScalar c = 0.923579533f;
            SkScalar s = 0.382683432f;
            SkScalar r = args.fInnerRadius;

            (*verts)->fPos = center + SkPoint::Make(-s * r, -c * r);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(-s * innerRadius, -c * innerRadius);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = center + SkPoint::Make(s * r, -c * r);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(s * innerRadius, -c * innerRadius);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = center + SkPoint::Make(c * r, -s * r);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(c * innerRadius, -s * innerRadius);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = center + SkPoint::Make(c * r, s * r);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(c * innerRadius, s * innerRadius);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = center + SkPoint::Make(s * r, c * r);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(s * innerRadius, c * innerRadius);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = center + SkPoint::Make(-s * r, c * r);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(-s * innerRadius, c * innerRadius);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = center + SkPoint::Make(-c * r, s * r);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(-c * innerRadius, s * innerRadius);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = center + SkPoint::Make(-c * r, -s * r);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(-c * innerRadius, -s * innerRadius);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;
        } else {
            // filled
            (*verts)->fPos = center;
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(0, 0);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;
        }
    }

    void fillInRRectVerts(const Geometry& args, CircleVertex** verts) const {
        GrColor color = args.fColor;
        SkScalar outerRadius = args.fOuterRadius;

        const SkRect& bounds = args.fDevBounds;

        SkScalar umbraInset = args.fUmbraInset;
        SkScalar minDim = 0.5f*std::min(bounds.width(), bounds.height());
        if (umbraInset > minDim) {
            umbraInset = minDim;
        }

        SkScalar xInner[4] = { bounds.fLeft + umbraInset, bounds.fRight - umbraInset,
            bounds.fLeft + umbraInset, bounds.fRight - umbraInset };
        SkScalar xMid[4] = { bounds.fLeft + outerRadius, bounds.fRight - outerRadius,
            bounds.fLeft + outerRadius, bounds.fRight - outerRadius };
        SkScalar xOuter[4] = { bounds.fLeft, bounds.fRight,
            bounds.fLeft, bounds.fRight };
        SkScalar yInner[4] = { bounds.fTop + umbraInset, bounds.fTop + umbraInset,
            bounds.fBottom - umbraInset, bounds.fBottom - umbraInset };
        SkScalar yMid[4] = { bounds.fTop + outerRadius, bounds.fTop + outerRadius,
            bounds.fBottom - outerRadius, bounds.fBottom - outerRadius };
        SkScalar yOuter[4] = { bounds.fTop, bounds.fTop,
            bounds.fBottom, bounds.fBottom };

        SkScalar blurRadius = args.fBlurRadius;

        // In the case where we have to inset more for the umbra, our two triangles in the
        // corner get skewed to a diamond rather than a square. To correct for that,
        // we also skew the vectors we send to the shader that help define the circle.
        // By doing so, we end up with a quarter circle in the corner rather than the
        // elliptical curve.

        // This is a bit magical, but it gives us the correct results at extrema:
        //   a) umbraInset == outerRadius produces an orthogonal vector
        //   b) outerRadius == 0 produces a diagonal vector
        // And visually the corner looks correct.
        SkVector outerVec = SkVector::Make(outerRadius - umbraInset, -outerRadius - umbraInset);
        outerVec.normalize();
        // We want the circle edge to fall fractionally along the diagonal at
        //      (sqrt(2)*(umbraInset - outerRadius) + outerRadius)/sqrt(2)*umbraInset
        //
        // Setting the components of the diagonal offset to the following value will give us that.
        SkScalar diagVal = umbraInset / (SK_ScalarSqrt2*(outerRadius - umbraInset) - outerRadius);
        SkVector diagVec = SkVector::Make(diagVal, diagVal);
        SkScalar distanceCorrection = umbraInset / blurRadius;

        // build corner by corner
        for (int i = 0; i < 4; ++i) {
            // inner point
            (*verts)->fPos = SkPoint::Make(xInner[i], yInner[i]);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkVector::Make(0, 0);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            // outer points
            (*verts)->fPos = SkPoint::Make(xOuter[i], yInner[i]);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkVector::Make(0, -1);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = SkPoint::Make(xOuter[i], yMid[i]);
            (*verts)->fColor = color;
            (*verts)->fOffset = outerVec;
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = SkPoint::Make(xOuter[i], yOuter[i]);
            (*verts)->fColor = color;
            (*verts)->fOffset = diagVec;
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = SkPoint::Make(xMid[i], yOuter[i]);
            (*verts)->fColor = color;
            (*verts)->fOffset = outerVec;
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            (*verts)->fPos = SkPoint::Make(xInner[i], yOuter[i]);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkVector::Make(0, -1);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;
        }

        // Add the additional vertices for overstroked rrects.
        // Effectively this is an additional stroked rrect, with its
        // parameters equal to those in the center of the 9-patch. This will
        // give constant values across this inner ring.
        if (kOverstroke_RRectType == args.fType) {
            SkASSERT(args.fInnerRadius > 0.0f);

            SkScalar inset =  umbraInset + args.fInnerRadius;

            // TL
            (*verts)->fPos = SkPoint::Make(bounds.fLeft + inset, bounds.fTop + inset);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(0, 0);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            // TR
            (*verts)->fPos = SkPoint::Make(bounds.fRight - inset, bounds.fTop + inset);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(0, 0);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            // BL
            (*verts)->fPos = SkPoint::Make(bounds.fLeft + inset, bounds.fBottom - inset);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(0, 0);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;

            // BR
            (*verts)->fPos = SkPoint::Make(bounds.fRight - inset, bounds.fBottom - inset);
            (*verts)->fColor = color;
            (*verts)->fOffset = SkPoint::Make(0, 0);
            (*verts)->fDistanceCorrection = distanceCorrection;
            (*verts)++;
        }

    }

    GrProgramInfo* programInfo() override { return fProgramInfo; }

    void onCreateProgramInfo(const GrCaps* caps,
                             SkArenaAlloc* arena,
                             const GrSurfaceProxyView& writeView,
                             bool usesMSAASurface,
                             GrAppliedClip&& appliedClip,
                             const GrDstProxyView& dstProxyView,
                             GrXferBarrierFlags renderPassXferBarriers,
                             GrLoadOp colorLoadOp) override {
        GrGeometryProcessor* gp = GrRRectShadowGeoProc::Make(arena, fFalloffView);
        SkASSERT(sizeof(CircleVertex) == gp->vertexStride());

        fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, arena, writeView,
                                                                   usesMSAASurface,
                                                                   std::move(appliedClip),
                                                                   dstProxyView, gp,
                                                                   GrProcessorSet::MakeEmptySet(),
                                                                   GrPrimitiveType::kTriangles,
                                                                   renderPassXferBarriers,
                                                                   colorLoadOp,
                                                                   GrPipeline::InputFlags::kNone,
                                                                   &GrUserStencilSettings::kUnused);
    }

    void onPrepareDraws(GrMeshDrawTarget* target) override {
        int instanceCount = fGeoData.size();

        sk_sp<const GrBuffer> vertexBuffer;
        int firstVertex;
        CircleVertex* verts = (CircleVertex*)target->makeVertexSpace(
                sizeof(CircleVertex), fVertCount, &vertexBuffer, &firstVertex);
        if (!verts) {
            SkDebugf("Could not allocate vertices\n");
            return;
        }

        sk_sp<const GrBuffer> indexBuffer;
        int firstIndex = 0;
        uint16_t* indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &firstIndex);
        if (!indices) {
            SkDebugf("Could not allocate indices\n");
            return;
        }

        int currStartVertex = 0;
        for (int i = 0; i < instanceCount; i++) {
            const Geometry& args = fGeoData[i];

            if (args.fIsCircle) {
                bool isStroked = SkToBool(kStroke_RRectType == args.fType);
                this->fillInCircleVerts(args, isStroked, &verts);

                const uint16_t* primIndices = circle_type_to_indices(isStroked);
                const int primIndexCount = circle_type_to_index_count(isStroked);
                for (int j = 0; j < primIndexCount; ++j) {
                    *indices++ = primIndices[j] + currStartVertex;
                }

                currStartVertex += circle_type_to_vert_count(isStroked);

            } else {
                this->fillInRRectVerts(args, &verts);

                const uint16_t* primIndices = rrect_type_to_indices(args.fType);
                const int primIndexCount = rrect_type_to_index_count(args.fType);
                for (int j = 0; j < primIndexCount; ++j) {
                    *indices++ = primIndices[j] + currStartVertex;
                }

                currStartVertex += rrect_type_to_vert_count(args.fType);
            }
        }

        fMesh = target->allocMesh();
        fMesh->setIndexed(std::move(indexBuffer), fIndexCount, firstIndex, 0,
                          SkTo<uint16_t>(fVertCount - 1),
                          GrPrimitiveRestart::kNo, std::move(vertexBuffer), firstVertex);
    }

    void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
        if (!fProgramInfo) {
            this->createProgramInfo(flushState);
        }

        if (!fProgramInfo || !fMesh) {
            return;
        }

        flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
        flushState->bindTextures(fProgramInfo->geomProc(), *fFalloffView.proxy(),
                                 fProgramInfo->pipeline());
        flushState->drawMesh(*fMesh);
    }

    CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override {
        ShadowCircularRRectOp* that = t->cast<ShadowCircularRRectOp>();

        // Cannot combine if the net number of indices would overflow int32, or if the net number
        // of vertices would overflow uint16 (since the index values are 16-bit that point into
        // the vertex buffer).
        if ((fIndexCount > INT32_MAX - that->fIndexCount) ||
            (fVertCount > SkToInt(UINT16_MAX) - that->fVertCount)) {
            return CombineResult::kCannotCombine;
        }

        fGeoData.push_back_n(that->fGeoData.size(), that->fGeoData.begin());
        fVertCount += that->fVertCount;
        fIndexCount += that->fIndexCount;
        return CombineResult::kMerged;
    }

#if defined(GPU_TEST_UTILS)
    SkString onDumpInfo() const override {
        SkString string;
        for (int i = 0; i < fGeoData.size(); ++i) {
            string.appendf(
                    "Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f],"
                    "OuterRad: %.2f, Umbra: %.2f, InnerRad: %.2f, BlurRad: %.2f\n",
                    fGeoData[i].fColor, fGeoData[i].fDevBounds.fLeft, fGeoData[i].fDevBounds.fTop,
                    fGeoData[i].fDevBounds.fRight, fGeoData[i].fDevBounds.fBottom,
                    fGeoData[i].fOuterRadius, fGeoData[i].fUmbraInset,
                    fGeoData[i].fInnerRadius, fGeoData[i].fBlurRadius);
        }
        return string;
    }
#endif

    void visitProxies(const GrVisitProxyFunc& func) const override {
        func(fFalloffView.proxy(), skgpu::Mipmapped(false));
        if (fProgramInfo) {
            fProgramInfo->visitFPProxies(func);
        }
    }

    STArray<1, Geometry, true> fGeoData;
    int fVertCount;
    int fIndexCount;
    GrSurfaceProxyView fFalloffView;

    GrSimpleMesh*      fMesh = nullptr;
    GrProgramInfo*     fProgramInfo = nullptr;

    using INHERITED = GrMeshDrawOp;
};

}  // anonymous namespace

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

namespace skgpu::ganesh::ShadowRRectOp {

static GrSurfaceProxyView create_falloff_texture(GrRecordingContext* rContext) {
    static const skgpu::UniqueKey::Domain kDomain = skgpu::UniqueKey::GenerateDomain();
    skgpu::UniqueKey key;
    skgpu::UniqueKey::Builder builder(&key, kDomain, 0, "Shadow Gaussian Falloff");
    builder.finish();

    auto threadSafeCache = rContext->priv().threadSafeCache();

    GrSurfaceProxyView view = threadSafeCache->find(key);
    if (view) {
        SkASSERT(view.origin() == kTopLeft_GrSurfaceOrigin);
        return view;
    }

    static const int kWidth = 128;
    static const size_t kRowBytes = kWidth * GrColorTypeBytesPerPixel(GrColorType::kAlpha_8);
    SkImageInfo ii = SkImageInfo::MakeA8(kWidth, 1);

    SkBitmap bitmap;
    bitmap.allocPixels(ii, kRowBytes);

    unsigned char* values = (unsigned char*)bitmap.getPixels();
    for (int i = 0; i < 128; ++i) {
        SkScalar d = SK_Scalar1 - i / SkIntToScalar(127);
        values[i] = SkScalarRoundToInt((SkScalarExp(-4 * d * d) - 0.018f) * 255);
    }
    bitmap.setImmutable();

    view = std::get<0>(GrMakeUncachedBitmapProxyView(rContext, bitmap));
    if (!view) {
        return {};
    }

    view = threadSafeCache->add(key, view);
    SkASSERT(view.origin() == kTopLeft_GrSurfaceOrigin);
    return view;
}

GrOp::Owner Make(GrRecordingContext* context,
                 GrColor color,
                 const SkMatrix& viewMatrix,
                 const SkRRect& rrect,
                 SkScalar blurWidth,
                 SkScalar insetWidth) {
    // Shadow rrect ops only handle simple circular rrects.
    SkASSERT(viewMatrix.isSimilarity() && SkRRectPriv::EqualRadii(rrect));

    GrSurfaceProxyView falloffView = create_falloff_texture(context);
    if (!falloffView) {
        return nullptr;
    }

    // Do any matrix crunching before we reset the draw state for device coords.
    const SkRect& rrectBounds = rrect.getBounds();
    SkRect bounds;
    viewMatrix.mapRect(&bounds, rrectBounds);

    // Map radius and inset. As the matrix is a similarity matrix, this should be isotropic.
    SkScalar radius = SkRRectPriv::GetSimpleRadii(rrect).fX;
    SkScalar matrixFactor = viewMatrix[SkMatrix::kMScaleX] + viewMatrix[SkMatrix::kMSkewX];
    SkScalar scaledRadius = SkScalarAbs(radius*matrixFactor);
    SkScalar scaledInsetWidth = SkScalarAbs(insetWidth*matrixFactor);

    if (scaledInsetWidth <= 0) {
        return nullptr;
    }

    return GrOp::Make<ShadowCircularRRectOp>(context,
                                             color,
                                             bounds,
                                             scaledRadius,
                                             rrect.isOval(),
                                             blurWidth,
                                             scaledInsetWidth,
                                             std::move(falloffView));
}

}  // namespace skgpu::ganesh::ShadowRRectOp

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

#if defined(GPU_TEST_UTILS)

GR_DRAW_OP_TEST_DEFINE(ShadowRRectOp) {
    // We may choose matrix and inset values that cause the factory to fail. We loop until we find
    // an acceptable combination.
    do {
        // create a similarity matrix
        SkScalar rotate = random->nextSScalar1() * 360.f;
        SkScalar translateX = random->nextSScalar1() * 1000.f;
        SkScalar translateY = random->nextSScalar1() * 1000.f;
        SkScalar scale = random->nextSScalar1() * 100.f;
        SkMatrix viewMatrix;
        viewMatrix.setRotate(rotate);
        viewMatrix.postTranslate(translateX, translateY);
        viewMatrix.postScale(scale, scale);
        SkScalar insetWidth = random->nextSScalar1() * 72.f;
        SkScalar blurWidth = random->nextSScalar1() * 72.f;
        bool isCircle = random->nextBool();
        // This op doesn't use a full GrPaint, just a color.
        GrColor color = paint.getColor4f().toBytes_RGBA();
        if (isCircle) {
            SkRect circle = GrTest::TestSquare(random);
            SkRRect rrect = SkRRect::MakeOval(circle);
            if (auto op = skgpu::ganesh::ShadowRRectOp::Make(
                        context, color, viewMatrix, rrect, blurWidth, insetWidth)) {
                return op;
            }
        } else {
            SkRRect rrect;
            do {
                // This may return a rrect with elliptical corners, which will cause an assert.
                rrect = GrTest::TestRRectSimple(random);
            } while (!SkRRectPriv::IsSimpleCircular(rrect));
            if (auto op = skgpu::ganesh::ShadowRRectOp::Make(
                        context, color, viewMatrix, rrect, blurWidth, insetWidth)) {
                return op;
            }
        }
    } while (true);
}

#endif // defined(GPU_TEST_UTILS)
