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

#ifndef GrCCPRCoverageProcessor_DEFINED
#define GrCCPRCoverageProcessor_DEFINED

#include "GrGeometryProcessor.h"
#include "glsl/GrGLSLGeometryProcessor.h"
#include "glsl/GrGLSLVarying.h"

class GrGLSLFragmentBuilder;

/**
 * This is the geometry processor for the simple convex primitive shapes (triangles and closed curve
 * segments) from which ccpr paths are composed. The output is a single-channel alpha value,
 * positive for clockwise primitives and negative for counter-clockwise, that indicates coverage.
 *
 * The caller is responsible to render all modes for all applicable primitives into a cleared,
 * floating point, alpha-only render target using SkBlendMode::kPlus. Once all of a path's
 * primitives have been drawn, the render target contains a composite coverage count that can then
 * be used to draw the path (see GrCCPRPathProcessor).
 *
 * Caller provides the primitives' (x,y) points in an fp32x2 (RG) texel buffer, and an instance
 * buffer with a single int32x4 attrib (for triangles) or int32x2 (for curves) defined below. There
 * are no vertex attribs.
 *
 * Draw calls are instanced, with one vertex per bezier point (3 for triangles). They use the
 * corresponding GrPrimitiveType as defined below.
 */
class GrCCPRCoverageProcessor : public GrGeometryProcessor {
public:
    // Use top-left to avoid a uniform access in the fragment shader.
    static constexpr GrSurfaceOrigin kAtlasOrigin = kTopLeft_GrSurfaceOrigin;

    static constexpr GrPrimitiveType kTrianglesGrPrimitiveType = GrPrimitiveType::kTriangles;
    static constexpr GrPrimitiveType kQuadraticsGrPrimitiveType = GrPrimitiveType::kTriangles;
    static constexpr GrPrimitiveType kCubicsGrPrimitiveType = GrPrimitiveType::kLinesAdjacency;

    struct TriangleInstance {
        int32_t fPt0Idx;
        int32_t fPt1Idx;
        int32_t fPt2Idx;
        int32_t fPackedAtlasOffset; // (offsetY << 16) | (offsetX & 0xffff)
    };

    GR_STATIC_ASSERT(4 * 4 == sizeof(TriangleInstance));

    struct CurveInstance {
        int32_t fPtsIdx;
        int32_t fPackedAtlasOffset; // (offsetY << 16) | (offsetX & 0xffff)
    };

    GR_STATIC_ASSERT(2 * 4 == sizeof(CurveInstance));

    enum class Mode {
        // Triangles.
        kTriangleHulls,
        kTriangleEdges,
        kCombinedTriangleHullsAndEdges,
        kTriangleCorners,

        // Quadratics.
        kQuadraticHulls,
        kQuadraticCorners,

        // Cubics.
        kSerpentineHulls,
        kLoopHulls,
        kSerpentineCorners,
        kLoopCorners
    };
    static constexpr GrVertexAttribType InstanceArrayFormat(Mode mode) {
        return mode < Mode::kQuadraticHulls ? kVec4i_GrVertexAttribType : kVec2i_GrVertexAttribType;
    }
    static const char* GetProcessorName(Mode);

    GrCCPRCoverageProcessor(Mode, GrBuffer* pointsBuffer);

    const char* instanceAttrib() const { return fInstanceAttrib.fName; }
    int atlasOffsetIdx() const {
        return kVec4i_GrVertexAttribType == InstanceArrayFormat(fMode) ? 3 : 1;
    }
    const char* name() const override { return GetProcessorName(fMode); }
    SkString dumpInfo() const override {
        return SkStringPrintf("%s\n%s", this->name(), this->INHERITED::dumpInfo().c_str());
    }

    void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
    GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;

#ifdef SK_DEBUG
    // Increases the 1/2 pixel AA bloat by a factor of debugBloat and outputs color instead of
    // coverage (coverage=+1 -> green, coverage=0 -> black, coverage=-1 -> red).
    void enableDebugVisualizations(float debugBloat) { fDebugBloat = debugBloat; }
    bool debugVisualizationsEnabled() const { return fDebugBloat > 0; }
    float debugBloat() const { SkASSERT(this->debugVisualizationsEnabled()); return fDebugBloat; }

    static void Validate(GrRenderTargetProxy* atlasProxy);
#endif

    class PrimitiveProcessor;

private:
    const Mode          fMode;
    const Attribute&    fInstanceAttrib;
    BufferAccess        fPointsBufferAccess;
    SkDEBUGCODE(float   fDebugBloat = false;)

    typedef GrGeometryProcessor INHERITED;
};

/**
 * This class represents the actual SKSL implementation for the various primitives and modes of
 * GrCCPRCoverageProcessor.
 */
class GrCCPRCoverageProcessor::PrimitiveProcessor : public GrGLSLGeometryProcessor {
protected:
    // Slightly undershoot a bloat radius of 0.5 so vertices that fall on integer boundaries don't
    // accidentally bleed into neighbor pixels.
    static constexpr float kAABloatRadius = 0.491111f;

    // Specifies how the fragment shader should calculate sk_FragColor.a.
    enum class CoverageType {
        kOne, // Output +1 all around, modulated by wind.
        kInterpolated, // Interpolate the coverage values that the geometry shader associates with
                       // each point, modulated by wind.
        kShader // Call emitShaderCoverage and let the subclass decide, then a modulate by wind.
    };

    PrimitiveProcessor(CoverageType coverageType)
            : fCoverageType(coverageType)
            , fGeomWind("wind", kHalf_GrSLType, GrShaderVar::kNonArray, kLow_GrSLPrecision)
            , fFragWind(kHalf_GrSLType)
            , fFragCoverageTimesWind(kHalf_GrSLType) {}

    // Called before generating shader code. Subclass should add its custom varyings to the handler
    // and update its corresponding internal member variables.
    virtual void resetVaryings(GrGLSLVaryingHandler*) {}

    // Here the subclass fetches its vertex from the texel buffer, translates by atlasOffset, and
    // sets "fPositionVar" in the GrGPArgs.
    virtual void onEmitVertexShader(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
                                    const TexelBufferHandle& pointsBuffer, const char* atlasOffset,
                                    const char* rtAdjust, GrGPArgs*) const = 0;

    // Here the subclass determines the winding direction of its primitive. It must write a value of
    // either -1, 0, or +1 to "outputWind" (e.g. "sign(area)"). Fractional values are not valid.
    virtual void emitWind(GrGLSLGeometryBuilder*, const char* rtAdjust,
                          const char* outputWind) const = 0;

    // This is where the subclass generates the actual geometry to be rasterized by hardware:
    //
    //   emitVertexFn(point1, coverage);
    //   emitVertexFn(point2, coverage);
    //   ...
    //   EndPrimitive();
    //
    // Generally a subclass will want to use emitHullGeometry and/or emitEdgeGeometry rather than
    // calling emitVertexFn directly.
    //
    // Subclass must also call GrGLSLGeometryBuilder::configure.
    virtual void onEmitGeometryShader(GrGLSLGeometryBuilder*, const char* emitVertexFn,
                                      const char* wind, const char* rtAdjust) const = 0;

    // This is a hook to inject code in the geometry shader's "emitVertex" function. Subclass
    // should use this to write values to its custom varyings.
    // NOTE: even flat varyings should be rewritten at each vertex.
    virtual void emitPerVertexGeometryCode(SkString* fnBody, const char* position,
                                           const char* coverage, const char* wind) const {}

    // Called when the subclass has selected CoverageType::kShader. Primitives should produce
    // coverage values between +0..1. Base class modulates the sign for wind.
    // TODO: subclasses might have good spots to stuff the winding information without burning a
    // whole new varying slot. Consider requiring them to generate the correct coverage sign.
    virtual void emitShaderCoverage(GrGLSLFragmentBuilder*, const char* outputCoverage) const {
        SK_ABORT("Shader coverage not implemented when using CoverageType::kShader.");
    }

    // Emits one wedge of the conservative raster hull of a convex polygon. The complete hull has
    // one wedge for each side of the polygon (i.e. call this N times, generally from different
    // geometry shader invocations). Coverage is +1 all around.
    //
    // Logically, the conservative raster hull is equivalent to the convex hull of pixel-size boxes
    // centered on the vertices.
    //
    // Geometry shader must be configured to output triangle strips.
    //
    // Returns the maximum number of vertices that will be emitted.
    int emitHullGeometry(GrGLSLGeometryBuilder*, const char* emitVertexFn, const char* polygonPts,
                         int numSides, const char* wedgeIdx, const char* midpoint = nullptr) const;

    // Emits the conservative raster of an edge (i.e. convex hull of two pixel-size boxes centered
    // on the endpoints). Coverage is -1 on the outside border of the edge geometry and 0 on the
    // inside. This effectively converts a jagged conservative raster edge into a smooth antialiased
    // edge when using CoverageType::kInterpolated.
    //
    // If the subclass has already called emitEdgeDistanceEquation, then provide the distance
    // equation. Otherwise this function will call emitEdgeDistanceEquation implicitly.
    //
    // Geometry shader must be configured to output triangle strips.
    //
    // Returns the maximum number of vertices that will be emitted.
    int emitEdgeGeometry(GrGLSLGeometryBuilder*, const char* emitVertexFn, const char* leftPt,
                         const char* rightPt, const char* distanceEquation = nullptr) const;

    // Defines an equation ("dot(float3(pt, 1), distance_equation)") that is -1 on the outside
    // border of a conservative raster edge and 0 on the inside (see emitEdgeGeometry).
    void emitEdgeDistanceEquation(GrGLSLGeometryBuilder*, const char* leftPt, const char* rightPt,
                                  const char* outputDistanceEquation) const;

    // Emits the conservative raster of a single point (i.e. pixel-size box centered on the point).
    // Coverage is +1 all around.
    //
    // Geometry shader must be configured to output triangle strips.
    //
    // Returns the number of vertices that were emitted.
    int emitCornerGeometry(GrGLSLGeometryBuilder*, const char* emitVertexFn, const char* pt) const;

    // Defines a global float2 array that contains MSAA sample locations as offsets from pixel
    // center. Subclasses can use this for software multisampling.
    //
    // Returns the number of samples.
    int defineSoftSampleLocations(GrGLSLFragmentBuilder*, const char* samplesName) const;

private:
    void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&,
                 FPCoordTransformIter&& transformIter) final {
        this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
    }

    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final;

    void emitVertexShader(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
                          const TexelBufferHandle& pointsBuffer, const char* rtAdjust,
                          GrGPArgs* gpArgs) const;
    void emitGeometryShader(const GrCCPRCoverageProcessor&, GrGLSLGeometryBuilder*,
                            const char* rtAdjust) const;
    void emitCoverage(const GrCCPRCoverageProcessor&, GrGLSLFragmentBuilder*,
                      const char* outputColor, const char* outputCoverage) const;

    const CoverageType   fCoverageType;
    GrShaderVar          fGeomWind;
    GrGLSLGeoToFrag      fFragWind;
    GrGLSLGeoToFrag      fFragCoverageTimesWind;

    typedef GrGLSLGeometryProcessor INHERITED;
};

#endif
