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

#ifndef GrTessellatePathOp_DEFINED
#define GrTessellatePathOp_DEFINED

#include "src/gpu/ops/GrDrawOp.h"

class GrAppliedHardClip;
class GrFillPathShader;
class GrStencilPathShader;

// Renders paths using a hybrid Red Book "stencil, then cover" method. Curves get linearized by
// GPU tessellation shaders. This Op doesn't apply analytic AA, so it requires a render target that
// supports either MSAA or mixed samples if AA is desired.
class GrTessellatePathOp : public GrDrawOp {
public:
    enum class Flags {
        kNone = 0,
        kStencilOnly = (1 << 0),
        kWireframe = (1 << 1)
    };

private:
    DEFINE_OP_CLASS_ID

    GrTessellatePathOp(const SkMatrix& viewMatrix, const SkPath& path, GrPaint&& paint,
                       GrAAType aaType, Flags flags = Flags::kNone)
            : GrDrawOp(ClassID())
            , fFlags(flags)
            , fViewMatrix(viewMatrix)
            , fPath(path)
            , fAAType(aaType)
            , fColor(paint.getColor4f())
            , fProcessors(std::move(paint)) {
        SkRect devBounds;
        fViewMatrix.mapRect(&devBounds, path.getBounds());
        this->setBounds(devBounds, HasAABloat(GrAAType::kCoverage == fAAType), IsHairline::kNo);
    }

    const char* name() const override { return "GrTessellatePathOp"; }
    void visitProxies(const VisitProxyFunc& fn) const override { fProcessors.visitProxies(fn); }
    GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip,
                                      bool hasMixedSampledCoverage,
                                      GrClampType clampType) override {
        return fProcessors.finalize(
                fColor, GrProcessorAnalysisCoverage::kNone, clip, &GrUserStencilSettings::kUnused,
                hasMixedSampledCoverage, caps, clampType, &fColor);
    }

    FixedFunctionFlags fixedFunctionFlags() const override;
    void onPrePrepare(GrRecordingContext*,
                      const GrSurfaceProxyView* writeView,
                      GrAppliedClip*,
                      const GrXferProcessor::DstProxyView&) override;
    void onPrepare(GrOpFlushState* state) override;
    void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;

    void drawStencilPass(GrOpFlushState*);
    void drawCoverPass(GrOpFlushState*);

    const Flags fFlags;
    const SkMatrix fViewMatrix;
    const SkPath fPath;
    const GrAAType fAAType;
    SkPMColor4f fColor;
    GrProcessorSet fProcessors;

    // These path shaders get created during onPrepare for drawing the below path vertex data.
    //
    // If fFillPathShader is null, then we just stencil the full path using fStencilPathShader and
    // fCubicInstanceBuffer, and then fill it using a simple bounding box.
    //
    // If fFillPathShader is not null, then we fill the path using it plus cubic hulls from
    // fCubicInstanceBuffer instead of a bounding box.
    //
    // If fFillPathShader is not null and fStencilPathShader *is* null, then the vertex data
    // contains non-overlapping path geometry that can be drawn directly to the final render target.
    // We only need to stencil curves from fCubicInstanceBuffer, and then draw the rest of the path
    // directly.
    GrStencilPathShader* fStencilPathShader = nullptr;
    GrFillPathShader* fFillPathShader = nullptr;

    // The "path vertex data" is made up of cubic wedges or inner polygon triangles (either red book
    // style or fully tessellated). The geometry is generated by
    // GrPathParser::EmitCenterWedgePatches, GrPathParser::EmitInnerPolygonTriangles,
    // or GrTriangulator::PathToTriangles.
    sk_sp<const GrBuffer> fPathVertexBuffer;
    int fBasePathVertex;
    int fPathVertexCount;

    // The cubic instance buffer defines standalone cubics to tessellate into the stencil buffer, in
    // addition to the above path geometry.
    sk_sp<const GrBuffer> fCubicInstanceBuffer;
    int fBaseCubicInstance;
    int fCubicInstanceCount;

    friend class GrOpMemoryPool;  // For ctor.
};

GR_MAKE_BITFIELD_CLASS_OPS(GrTessellatePathOp::Flags);

#endif
