/*
 * Copyright 2014 Google Inc.
 * Copyright 2017 ARM Ltd.
 *
 * 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/SmallPathRenderer.h"

#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/gpu/ganesh/GrRecordingContext.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkMath.h"
#include "include/private/base/SkPoint_impl.h"
#include "include/private/base/SkTArray.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/base/SkAutoMalloc.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkColorData.h"
#include "src/core/SkDistanceFieldGen.h"
#include "src/core/SkDraw.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkRasterClip.h"
#include "src/gpu/AtlasTypes.h"
#include "src/gpu/BufferWriter.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrAuditTrail.h"
#include "src/gpu/ganesh/GrBuffer.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColorSpaceXform.h"
#include "src/gpu/ganesh/GrDeferredUpload.h"
#include "src/gpu/ganesh/GrDistanceFieldGenFromVector.h"
#include "src/gpu/ganesh/GrDrawOpAtlas.h"
#include "src/gpu/ganesh/GrDrawOpTest.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/GrProcessorAnalysis.h"
#include "src/gpu/ganesh/GrProcessorSet.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrSamplerState.h"
#include "src/gpu/ganesh/GrShaderCaps.h"
#include "src/gpu/ganesh/GrSimpleMesh.h"
#include "src/gpu/ganesh/GrStyle.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/effects/GrBitmapTextGeoProc.h"
#include "src/gpu/ganesh/effects/GrDistanceFieldGeoProc.h"
#include "src/gpu/ganesh/geometry/GrStyledShape.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelperWithStencil.h"
#include "src/gpu/ganesh/ops/SmallPathAtlasMgr.h"
#include "src/gpu/ganesh/ops/SmallPathShapeData.h"

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

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <utility>

class GrDstProxyView;
class GrProgramInfo;
class GrSurfaceProxy;
class SkArenaAlloc;
enum class GrXferBarrierFlags;
struct GrUserStencilSettings;

using namespace skia_private;

#if !defined(SK_ENABLE_OPTIMIZE_SIZE)

using MaskFormat = skgpu::MaskFormat;

namespace skgpu::ganesh {

namespace {

// mip levels
static constexpr SkScalar kIdealMinMIP = 12;
static constexpr SkScalar kMaxMIP = 162;

static constexpr SkScalar kMaxDim = 73;
static constexpr SkScalar kMinSize = SK_ScalarHalf;
static constexpr SkScalar kMaxSize = 2*kMaxMIP;

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

// padding around path bounds to allow for antialiased pixels
static const int kAntiAliasPad = 1;

class SmallPathOp final : public GrMeshDrawOp {
private:
    using Helper = GrSimpleMeshDrawOpHelperWithStencil;

public:
    DEFINE_OP_CLASS_ID

    static GrOp::Owner Make(GrRecordingContext* context,
                            GrPaint&& paint,
                            const GrStyledShape& shape,
                            const SkMatrix& viewMatrix,
                            bool gammaCorrect,
                            const GrUserStencilSettings* stencilSettings) {
        return Helper::FactoryHelper<SmallPathOp>(context, std::move(paint), shape, viewMatrix,
                                                  gammaCorrect, stencilSettings);
    }

    SmallPathOp(GrProcessorSet* processorSet, const SkPMColor4f& color, const GrStyledShape& shape,
                const SkMatrix& viewMatrix, bool gammaCorrect,
                const GrUserStencilSettings* stencilSettings)
            : INHERITED(ClassID())
            , fHelper(processorSet, GrAAType::kCoverage, stencilSettings) {
        SkASSERT(shape.hasUnstyledKey());
        // Compute bounds
        this->setTransformedBounds(shape.bounds(), viewMatrix, HasAABloat::kYes, IsHairline::kNo);

#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
        fUsesDistanceField = true;
#else
        // only use distance fields on desktop and Android framework to save space in the atlas
        fUsesDistanceField = this->bounds().width() > kMaxMIP || this->bounds().height() > kMaxMIP;
#endif
        // always use distance fields if in perspective
        fUsesDistanceField = fUsesDistanceField || viewMatrix.hasPerspective();

        fShapes.emplace_back(Entry{color, shape, viewMatrix});

        fGammaCorrect = gammaCorrect;
    }

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

    void visitProxies(const GrVisitProxyFunc& func) const override {
        fHelper.visitProxies(func);
    }

    FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }

    GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip,
                                      GrClampType clampType) override {
        return fHelper.finalizeProcessors(caps, clip, clampType,
                                          GrProcessorAnalysisCoverage::kSingleChannel,
                                          &fShapes.front().fColor, &fWideColor);
    }

private:
    struct FlushInfo {
        sk_sp<const GrBuffer> fVertexBuffer;
        sk_sp<const GrBuffer> fIndexBuffer;
        GrGeometryProcessor*  fGeometryProcessor;
        const GrSurfaceProxy** fPrimProcProxies;
        int fVertexOffset;
        int fInstancesToFlush;
    };

    GrProgramInfo* programInfo() override {
        // TODO [PI]: implement
        return nullptr;
    }

    void onCreateProgramInfo(const GrCaps*,
                             SkArenaAlloc*,
                             const GrSurfaceProxyView& writeView,
                             bool usesMSAASurface,
                             GrAppliedClip&&,
                             const GrDstProxyView&,
                             GrXferBarrierFlags renderPassXferBarriers,
                             GrLoadOp colorLoadOp) override {
        // We cannot surface the SmallPathOp's programInfo at record time. As currently
        // implemented, the GP is modified at flush time based on the number of pages in the
        // atlas.
    }

    void onPrePrepareDraws(GrRecordingContext*,
                           const GrSurfaceProxyView& writeView,
                           GrAppliedClip*,
                           const GrDstProxyView&,
                           GrXferBarrierFlags renderPassXferBarriers,
                           GrLoadOp colorLoadOp) override {
        // TODO [PI]: implement
    }

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

        auto atlasMgr = target->smallPathAtlasManager();
        if (!atlasMgr) {
            return;
        }

        static constexpr int kMaxTextures = GrDistanceFieldPathGeoProc::kMaxTextures;
        static_assert(GrBitmapTextGeoProc::kMaxTextures == kMaxTextures);

        FlushInfo flushInfo;
        flushInfo.fPrimProcProxies = target->allocPrimProcProxyPtrs(kMaxTextures);

        int numActiveProxies;
        const GrSurfaceProxyView* views = atlasMgr->getViews(&numActiveProxies);
        for (int i = 0; i < numActiveProxies; ++i) {
            // This op does not know its atlas proxies when it is added to a OpsTasks, so the
            // proxies don't get added during the visitProxies call. Thus we add them here.
            flushInfo.fPrimProcProxies[i] = views[i].proxy();
            target->sampledProxyArray()->push_back(views[i].proxy());
        }

        // Setup GrGeometryProcessor
        const SkMatrix& ctm = fShapes[0].fViewMatrix;
        SkMatrix invert;
        if (fHelper.usesLocalCoords()) {
            if (!ctm.invert(&invert)) {
                return;
            }
        }
        if (fUsesDistanceField) {
            uint32_t flags = 0;
            // Still need to key off of ctm to pick the right shader for the transformed quad
            flags |= ctm.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0;
            flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
            flags |= fGammaCorrect ? kGammaCorrect_DistanceFieldEffectFlag : 0;
            flags |= fWideColor ? kWideColor_DistanceFieldEffectFlag : 0;
            // We always use Point3 for position
            flags |= kPerspective_DistanceFieldEffectFlag;

            flushInfo.fGeometryProcessor = GrDistanceFieldPathGeoProc::Make(
                    target->allocator(), *target->caps().shaderCaps(),
                    views, numActiveProxies, GrSamplerState::Filter::kLinear,
                    invert, flags);
        } else {
            flushInfo.fGeometryProcessor = GrBitmapTextGeoProc::Make(
                    target->allocator(), *target->caps().shaderCaps(), this->color(), fWideColor,
                    /*colorSpaceXform=*/nullptr, views, numActiveProxies,
                    GrSamplerState::Filter::kNearest, MaskFormat::kA8, invert, false);
        }

        // allocate vertices
        const size_t kVertexStride = flushInfo.fGeometryProcessor->vertexStride();

        // We need to make sure we don't overflow a 32 bit int when we request space in the
        // makeVertexSpace call below.
        if (instanceCount > SK_MaxS32 / GrResourceProvider::NumVertsPerNonAAQuad()) {
            return;
        }
        VertexWriter vertices = target->makeVertexWriter(
            kVertexStride, GrResourceProvider::NumVertsPerNonAAQuad() * instanceCount,
            &flushInfo.fVertexBuffer, &flushInfo.fVertexOffset);

        flushInfo.fIndexBuffer = target->resourceProvider()->refNonAAQuadIndexBuffer();
        if (!vertices || !flushInfo.fIndexBuffer) SK_UNLIKELY {
            SkDebugf("Could not allocate vertices\n");
            return;
        }

        flushInfo.fInstancesToFlush = 0;
        for (int i = 0; i < instanceCount; i++) {
            const Entry& args = fShapes[i];

            skgpu::ganesh::SmallPathShapeData* shapeData;
            if (fUsesDistanceField) {
                // get mip level
                SkScalar maxScale;
                const SkRect& bounds = args.fShape.bounds();
                if (args.fViewMatrix.hasPerspective()) {
                    // approximate the scale since we can't get it from the matrix
                    SkRect xformedBounds;
                    args.fViewMatrix.mapRect(&xformedBounds, bounds);
                    maxScale = SkScalarAbs(std::max(xformedBounds.width() / bounds.width(),
                                                  xformedBounds.height() / bounds.height()));
                } else {
                    maxScale = SkScalarAbs(args.fViewMatrix.getMaxScale());
                }
                SkScalar maxDim = std::max(bounds.width(), bounds.height());
                // We try to create the DF at a 2^n scaled path resolution (1/2, 1, 2, 4, etc.)
                // In the majority of cases this will yield a crisper rendering.
                SkScalar mipScale = 1.0f;
                // Our mipscale is the maxScale clamped to the next highest power of 2
                if (maxScale <= SK_ScalarHalf) {
                    SkScalar log = SkScalarFloorToScalar(SkScalarLog2(SkScalarInvert(maxScale)));
                    mipScale = SkScalarPow(2, -log);
                } else if (maxScale > SK_Scalar1) {
                    SkScalar log = SkScalarCeilToScalar(SkScalarLog2(maxScale));
                    mipScale = SkScalarPow(2, log);
                }
                // Log2 isn't very precise at values close to a power of 2,
                // so add a little tolerance here. A little bit of scaling up is fine.
                SkASSERT(maxScale <= mipScale + SK_ScalarNearlyZero);

                SkScalar mipSize = mipScale*SkScalarAbs(maxDim);
                // For sizes less than kIdealMinMIP we want to use as large a distance field as we can
                // so we can preserve as much detail as possible. However, we can't scale down more
                // than a 1/4 of the size without artifacts. So the idea is that we pick the mipsize
                // just bigger than the ideal, and then scale down until we are no more than 4x the
                // original mipsize.
                if (mipSize < kIdealMinMIP) {
                    SkScalar newMipSize = mipSize;
                    do {
                        newMipSize *= 2;
                    } while (newMipSize < kIdealMinMIP);
                    while (newMipSize > 4 * mipSize) {
                        newMipSize *= 0.25f;
                    }
                    mipSize = newMipSize;
                }

                SkScalar desiredDimension = std::min(mipSize, kMaxMIP);
                int ceilDesiredDimension = SkScalarCeilToInt(desiredDimension);

                // check to see if df path is cached
                shapeData = atlasMgr->findOrCreate(args.fShape, ceilDesiredDimension);
                if (!shapeData->fAtlasLocator.plotLocator().isValid()) {
                    SkScalar scale = desiredDimension / maxDim;

                    if (!this->addDFPathToAtlas(target,
                                                &flushInfo,
                                                atlasMgr,
                                                shapeData,
                                                args.fShape,
                                                ceilDesiredDimension,
                                                scale)) {
                        atlasMgr->deleteCacheEntry(shapeData);
                        continue;
                    }
                }
            } else {
                // check to see if bitmap path is cached
                shapeData = atlasMgr->findOrCreate(args.fShape, args.fViewMatrix);
                if (!shapeData->fAtlasLocator.plotLocator().isValid()) {
                    if (!this->addBMPathToAtlas(target,
                                                &flushInfo,
                                                atlasMgr,
                                                shapeData,
                                                args.fShape,
                                                args.fViewMatrix)) {
                        atlasMgr->deleteCacheEntry(shapeData);
                        continue;
                    }
                }
            }

            auto uploadTarget = target->deferredUploadTarget();
            atlasMgr->setUseToken(shapeData, uploadTarget->tokenTracker()->nextDrawToken());

            this->writePathVertices(vertices, VertexColor(args.fColor, fWideColor),
                                    args.fViewMatrix, shapeData);
            flushInfo.fInstancesToFlush++;
        }

        this->flush(target, &flushInfo);
    }

    bool addToAtlasWithRetry(GrMeshDrawTarget* target,
                             FlushInfo* flushInfo,
                             skgpu::ganesh::SmallPathAtlasMgr* atlasMgr,
                             int width,
                             int height,
                             const void* image,
                             const SkRect& bounds,
                             int srcInset,
                             skgpu::ganesh::SmallPathShapeData* shapeData) const {
        auto resourceProvider = target->resourceProvider();
        auto uploadTarget = target->deferredUploadTarget();

        auto code = atlasMgr->addToAtlas(resourceProvider, uploadTarget, width, height,
                                         image, &shapeData->fAtlasLocator);
        if (GrDrawOpAtlas::ErrorCode::kError == code) {
            return false;
        }

        if (GrDrawOpAtlas::ErrorCode::kTryAgain == code) {
            this->flush(target, flushInfo);

            code = atlasMgr->addToAtlas(resourceProvider, uploadTarget, width, height,
                                        image, &shapeData->fAtlasLocator);
        }

        shapeData->fAtlasLocator.insetSrc(srcInset);
        shapeData->fBounds = bounds;

        return GrDrawOpAtlas::ErrorCode::kSucceeded == code;
    }

    bool addDFPathToAtlas(GrMeshDrawTarget* target,
                          FlushInfo* flushInfo,
                          skgpu::ganesh::SmallPathAtlasMgr* atlasMgr,
                          skgpu::ganesh::SmallPathShapeData* shapeData,
                          const GrStyledShape& shape,
                          uint32_t dimension,
                          SkScalar scale) const {
        const SkRect& bounds = shape.bounds();

        // generate bounding rect for bitmap draw
        SkRect scaledBounds = bounds;
        // scale to mip level size
        scaledBounds.fLeft *= scale;
        scaledBounds.fTop *= scale;
        scaledBounds.fRight *= scale;
        scaledBounds.fBottom *= scale;
        // subtract out integer portion of origin
        // (SDF created will be placed with fractional offset burnt in)
        SkScalar dx = SkScalarFloorToScalar(scaledBounds.fLeft);
        SkScalar dy = SkScalarFloorToScalar(scaledBounds.fTop);
        scaledBounds.offset(-dx, -dy);
        // get integer boundary
        SkIRect devPathBounds;
        scaledBounds.roundOut(&devPathBounds);
        // place devBounds at origin with padding to allow room for antialiasing
        int width = devPathBounds.width() + 2 * kAntiAliasPad;
        int height = devPathBounds.height() + 2 * kAntiAliasPad;
        devPathBounds = SkIRect::MakeWH(width, height);
        SkScalar translateX = kAntiAliasPad - dx;
        SkScalar translateY = kAntiAliasPad - dy;

        // draw path to bitmap
        SkMatrix drawMatrix;
        drawMatrix.setScale(scale, scale);
        drawMatrix.postTranslate(translateX, translateY);

        SkASSERT(devPathBounds.fLeft == 0);
        SkASSERT(devPathBounds.fTop == 0);
        SkASSERT(devPathBounds.width() > 0);
        SkASSERT(devPathBounds.height() > 0);

        // setup signed distance field storage
        SkIRect dfBounds = devPathBounds.makeOutset(SK_DistanceFieldPad, SK_DistanceFieldPad);
        width = dfBounds.width();
        height = dfBounds.height();
        // TODO We should really generate this directly into the plot somehow
        SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char));

        SkPath path = shape.asPath();
        // Generate signed distance field directly from SkPath
        bool succeed = GrGenerateDistanceFieldFromPath((unsigned char*)dfStorage.get(),
                                                       path, drawMatrix, width, height,
                                                       width * sizeof(unsigned char));
        if (!succeed) {
            // setup bitmap backing
            SkAutoPixmapStorage dst;
            if (!dst.tryAlloc(SkImageInfo::MakeA8(devPathBounds.width(), devPathBounds.height()))) {
                return false;
            }
            sk_bzero(dst.writable_addr(), dst.computeByteSize());

            // rasterize path
            SkPaint paint;
            paint.setStyle(SkPaint::kFill_Style);
            paint.setAntiAlias(true);

            skcpu::Draw draw;

            SkRasterClip rasterClip;
            rasterClip.setRect(devPathBounds);
            draw.fRC = &rasterClip;
            draw.fCTM = &drawMatrix;
            draw.fDst = dst;

            draw.drawPathCoverage(path, paint);

            // Generate signed distance field
            SkGenerateDistanceFieldFromA8Image((unsigned char*)dfStorage.get(),
                                               (const unsigned char*)dst.addr(),
                                               dst.width(), dst.height(), dst.rowBytes());
        }

        SkRect drawBounds = SkRect::Make(devPathBounds).makeOffset(-translateX, -translateY);
        drawBounds.fLeft /= scale;
        drawBounds.fTop /= scale;
        drawBounds.fRight /= scale;
        drawBounds.fBottom /= scale;

        return this->addToAtlasWithRetry(target, flushInfo, atlasMgr,
                                         width, height, dfStorage.get(),
                                         drawBounds, SK_DistanceFieldPad, shapeData);
    }

    bool addBMPathToAtlas(GrMeshDrawTarget* target,
                          FlushInfo* flushInfo,
                          skgpu::ganesh::SmallPathAtlasMgr* atlasMgr,
                          skgpu::ganesh::SmallPathShapeData* shapeData,
                          const GrStyledShape& shape,
                          const SkMatrix& ctm) const {
        const SkRect& bounds = shape.bounds();
        if (bounds.isEmpty()) {
            return false;
        }
        SkMatrix drawMatrix(ctm);
        SkScalar tx = ctm.getTranslateX();
        SkScalar ty = ctm.getTranslateY();
        tx -= SkScalarFloorToScalar(tx);
        ty -= SkScalarFloorToScalar(ty);
        drawMatrix.set(SkMatrix::kMTransX, tx);
        drawMatrix.set(SkMatrix::kMTransY, ty);
        SkRect shapeDevBounds;
        drawMatrix.mapRect(&shapeDevBounds, bounds);
        SkScalar dx = SkScalarFloorToScalar(shapeDevBounds.fLeft);
        SkScalar dy = SkScalarFloorToScalar(shapeDevBounds.fTop);

        // get integer boundary
        SkIRect devPathBounds;
        shapeDevBounds.roundOut(&devPathBounds);
        // place devBounds at origin with padding to allow room for antialiasing
        int width = devPathBounds.width() + 2 * kAntiAliasPad;
        int height = devPathBounds.height() + 2 * kAntiAliasPad;
        devPathBounds = SkIRect::MakeWH(width, height);
        SkScalar translateX = kAntiAliasPad - dx;
        SkScalar translateY = kAntiAliasPad - dy;

        SkASSERT(devPathBounds.fLeft == 0);
        SkASSERT(devPathBounds.fTop == 0);
        SkASSERT(devPathBounds.width() > 0);
        SkASSERT(devPathBounds.height() > 0);

        SkPath path = shape.asPath();
        // setup bitmap backing
        SkAutoPixmapStorage dst;
        if (!dst.tryAlloc(SkImageInfo::MakeA8(devPathBounds.width(), devPathBounds.height()))) {
            return false;
        }
        sk_bzero(dst.writable_addr(), dst.computeByteSize());

        // rasterize path
        SkPaint paint;
        paint.setStyle(SkPaint::kFill_Style);
        paint.setAntiAlias(true);

        skcpu::Draw draw;

        SkRasterClip rasterClip;
        rasterClip.setRect(devPathBounds);
        drawMatrix.postTranslate(translateX, translateY);
        draw.fRC = &rasterClip;
        draw.fCTM = &drawMatrix;
        draw.fDst = dst;

        draw.drawPathCoverage(path, paint);

        SkRect drawBounds = SkRect::Make(devPathBounds).makeOffset(-translateX, -translateY);

        return this->addToAtlasWithRetry(target, flushInfo, atlasMgr,
                                         dst.width(), dst.height(), dst.addr(),
                                         drawBounds, 0, shapeData);
    }

    void writePathVertices(VertexWriter& vertices,
                           const VertexColor& color,
                           const SkMatrix& ctm,
                           const skgpu::ganesh::SmallPathShapeData* shapeData) const {
        SkRect translatedBounds(shapeData->fBounds);
        if (!fUsesDistanceField) {
            translatedBounds.offset(SkScalarFloorToScalar(ctm.get(SkMatrix::kMTransX)),
                                    SkScalarFloorToScalar(ctm.get(SkMatrix::kMTransY)));
        }

        // set up texture coordinates
        auto texCoords = VertexWriter::TriStripFromUVs(shapeData->fAtlasLocator.getUVs());

        if (fUsesDistanceField) {
            SkPoint3 out[4];
            ctm.mapPointsToHomogeneous(out, translatedBounds.toQuad());

            vertices << out[0] << color << texCoords.l << texCoords.t;
            vertices << out[3] << color << texCoords.l << texCoords.b;
            vertices << out[1] << color << texCoords.r << texCoords.t;
            vertices << out[2] << color << texCoords.r << texCoords.b;
        } else {
            vertices.writeQuad(VertexWriter::TriStripFromRect(translatedBounds),
                               color,
                               texCoords);
        }
    }

    void flush(GrMeshDrawTarget* target, FlushInfo* flushInfo) const {
        auto atlasMgr = target->smallPathAtlasManager();
        if (!atlasMgr) {
            return;
        }

        int numActiveProxies;
        const GrSurfaceProxyView* views = atlasMgr->getViews(&numActiveProxies);

        GrGeometryProcessor* gp = flushInfo->fGeometryProcessor;
        if (gp->numTextureSamplers() != numActiveProxies) {
            for (int i = gp->numTextureSamplers(); i < numActiveProxies; ++i) {
                flushInfo->fPrimProcProxies[i] = views[i].proxy();
                // This op does not know its atlas proxies when it is added to a OpsTasks, so the
                // proxies don't get added during the visitProxies call. Thus we add them here.
                target->sampledProxyArray()->push_back(views[i].proxy());
            }
            // During preparation the number of atlas pages has increased.
            // Update the proxies used in the GP to match.
            if (fUsesDistanceField) {
                reinterpret_cast<GrDistanceFieldPathGeoProc*>(gp)->addNewViews(
                        views, numActiveProxies, GrSamplerState::Filter::kLinear);
            } else {
                reinterpret_cast<GrBitmapTextGeoProc*>(gp)->addNewViews(
                        views, numActiveProxies, GrSamplerState::Filter::kNearest);
            }
        }

        if (flushInfo->fInstancesToFlush) {
            GrSimpleMesh* mesh = target->allocMesh();
            mesh->setIndexedPatterned(flushInfo->fIndexBuffer,
                                      GrResourceProvider::NumIndicesPerNonAAQuad(),
                                      flushInfo->fInstancesToFlush,
                                      GrResourceProvider::MaxNumNonAAQuads(),
                                      flushInfo->fVertexBuffer,
                                      GrResourceProvider::NumVertsPerNonAAQuad(),
                                      flushInfo->fVertexOffset);
            target->recordDraw(flushInfo->fGeometryProcessor, mesh, 1, flushInfo->fPrimProcProxies,
                               GrPrimitiveType::kTriangles);
            flushInfo->fVertexOffset += GrResourceProvider::NumVertsPerNonAAQuad() *
                                        flushInfo->fInstancesToFlush;
            flushInfo->fInstancesToFlush = 0;
        }
    }

    void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
        auto pipeline = fHelper.createPipeline(flushState);

        flushState->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds, pipeline,
                                                        fHelper.stencilSettings());
    }

    const SkPMColor4f& color() const { return fShapes[0].fColor; }
    bool usesDistanceField() const { return fUsesDistanceField; }

    CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override {
        SmallPathOp* that = t->cast<SmallPathOp>();
        if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
            return CombineResult::kCannotCombine;
        }

        if (this->usesDistanceField() != that->usesDistanceField()) {
            return CombineResult::kCannotCombine;
        }

        const SkMatrix& thisCtm = this->fShapes[0].fViewMatrix;
        const SkMatrix& thatCtm = that->fShapes[0].fViewMatrix;

        if (this->usesDistanceField()) {
            // Need to make sure local matrices are identical
            if (fHelper.usesLocalCoords() && !SkMatrixPriv::CheapEqual(thisCtm, thatCtm)) {
                return CombineResult::kCannotCombine;
            }

            // Depending on the ctm we may have a different shader for SDF paths
            if (thisCtm.isScaleTranslate() != thatCtm.isScaleTranslate() ||
                thisCtm.isSimilarity() != thatCtm.isSimilarity()) {
                return CombineResult::kCannotCombine;
            }
        } else {
            if (thisCtm.hasPerspective() != thatCtm.hasPerspective()) {
                return CombineResult::kCannotCombine;
            }

            // We can position on the cpu unless we're in perspective,
            // but also need to make sure local matrices are identical
            if ((thisCtm.hasPerspective() || fHelper.usesLocalCoords()) &&
                !SkMatrixPriv::CheapEqual(thisCtm, thatCtm)) {
                return CombineResult::kCannotCombine;
            }
        }

        fShapes.push_back_n(that->fShapes.size(), that->fShapes.begin());
        fWideColor |= that->fWideColor;
        return CombineResult::kMerged;
    }

#if defined(GPU_TEST_UTILS)
    SkString onDumpInfo() const override {
        SkString string;
        for (const auto& geo : fShapes) {
            string.appendf("Color: 0x%08x\n", geo.fColor.toBytes_RGBA());
        }
        string += fHelper.dumpInfo();
        return string;
    }
#endif

    bool fUsesDistanceField;

    struct Entry {
        SkPMColor4f   fColor;
        GrStyledShape fShape;
        SkMatrix      fViewMatrix;
    };

    STArray<1, Entry> fShapes;
    Helper fHelper;
    bool fGammaCorrect;
    bool fWideColor;

    using INHERITED = GrMeshDrawOp;
};

} // anonymous namespace

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

PathRenderer::CanDrawPath SmallPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
    if (!args.fCaps->shaderCaps()->fShaderDerivativeSupport) {
        return CanDrawPath::kNo;
    }
    // If the shape has no key then we won't get any reuse.
    if (!args.fShape->hasUnstyledKey()) {
        return CanDrawPath::kNo;
    }
    // This only supports filled paths, however, the caller may apply the style to make a filled
    // path and try again.
    if (!args.fShape->style().isSimpleFill()) {
        return CanDrawPath::kNo;
    }
    // This does non-inverse coverage-based antialiased fills.
    if (GrAAType::kCoverage != args.fAAType) {
        return CanDrawPath::kNo;
    }
    // TODO: Support inverse fill
    if (args.fShape->inverseFilled()) {
        return CanDrawPath::kNo;
    }

    SkScalar scaleFactors[2] = { 1, 1 };
    // TODO: handle perspective distortion
    if (!args.fViewMatrix->hasPerspective() && !args.fViewMatrix->getMinMaxScales(scaleFactors)) {
        return CanDrawPath::kNo;
    }
    // For affine transformations, too much shear can produce artifacts.
    if (!scaleFactors[0] || scaleFactors[1]/scaleFactors[0] > 4) {
        return CanDrawPath::kNo;
    }
    // Only support paths with bounds within kMaxDim by kMaxDim,
    // scaled to have bounds within kMaxSize by kMaxSize.
    // The goal is to accelerate rendering of lots of small paths that may be scaling.
    SkRect bounds = args.fShape->styledBounds();
    SkScalar minDim = std::min(bounds.width(), bounds.height());
    SkScalar maxDim = std::max(bounds.width(), bounds.height());
    SkScalar minSize = minDim * SkScalarAbs(scaleFactors[0]);
    SkScalar maxSize = maxDim * SkScalarAbs(scaleFactors[1]);
    if (maxDim > kMaxDim || kMinSize > minSize || maxSize > kMaxSize) {
        return CanDrawPath::kNo;
    }

    return CanDrawPath::kYes;
}

bool SmallPathRenderer::onDrawPath(const DrawPathArgs& args) {
    GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
                              "SmallPathRenderer::onDrawPath");

    // we've already bailed on inverse filled paths, so this is safe
    SkASSERT(!args.fShape->isEmpty());
    SkASSERT(args.fShape->hasUnstyledKey());

    GrOp::Owner op = SmallPathOp::Make(
            args.fContext, std::move(args.fPaint), *args.fShape, *args.fViewMatrix,
            args.fGammaCorrect, args.fUserStencilSettings);
    args.fSurfaceDrawContext->addDrawOp(args.fClip, std::move(op));

    return true;
}

}  // namespace skgpu::ganesh

#if defined(GPU_TEST_UTILS)

GR_DRAW_OP_TEST_DEFINE(SmallPathOp) {
    SkMatrix viewMatrix = GrTest::TestMatrix(random);
    bool gammaCorrect = random->nextBool();

    // This path renderer only allows fill styles.
    GrStyledShape shape(GrTest::TestPath(random), GrStyle::SimpleFill());
    return skgpu::ganesh::SmallPathOp::Make(context,
                                            std::move(paint),
                                            shape,
                                            viewMatrix,
                                            gammaCorrect,
                                            GrGetRandomStencil(random, context));
}

#endif // defined(GPU_TEST_UTILS)

#endif // SK_ENABLE_OPTIMIZE_SIZE
