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

#include "GrPLSPathRenderer.h"

#include "SkChunkAlloc.h"
#include "SkGeometry.h"
#include "SkPathPriv.h"
#include "SkString.h"
#include "SkTSort.h"
#include "SkTraceEvent.h"
#include "GrBatchFlushState.h"
#include "GrBatchTest.h"
#include "GrCaps.h"
#include "GrContext.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrPLSGeometryProcessor.h"
#include "GrInvariantOutput.h"
#include "GrPathUtils.h"
#include "GrProcessor.h"
#include "GrPipelineBuilder.h"
#include "GrStyle.h"
#include "GrTessellator.h"
#include "batches/GrVertexBatch.h"
#include "glsl/GrGLSLGeometryProcessor.h"
#include "gl/builders/GrGLProgramBuilder.h"
#include "glsl/GrGLSLPLSPathRendering.h"

GrPLSPathRenderer::GrPLSPathRenderer() {
}

struct PLSVertex {
    SkPoint  fPos;
    // for triangles, these are the three triangle vertices
    // for quads, vert1 is the texture UV coords, and vert2 and vert3 are the line segment
    // comprising the flat edge of the quad
    SkPoint  fVert1;
    SkPoint  fVert2;
    SkPoint  fVert3;
    int fWinding;
};
typedef SkTArray<PLSVertex, true> PLSVertices;

typedef SkTArray<SkPoint, true> FinishVertices;

static const float kCubicTolerance = 0.5f;
static const float kConicTolerance = 0.5f;

static const float kBloatSize = 1.0f;

static const float kBloatLimit = 640000.0f;

#define kQuadNumVertices 5
static void add_quad(SkPoint pts[3], PLSVertices& vertices) {
    SkPoint normal = SkPoint::Make(pts[0].fY - pts[2].fY,
                                   pts[2].fX - pts[0].fX);
    normal.setLength(kBloatSize);
    SkScalar cross = (pts[1] - pts[0]).cross(pts[2] - pts[0]);
    if (cross < 0) {
        normal = -normal;
    }
    PLSVertex quad[kQuadNumVertices];
    quad[0].fPos = pts[0] + normal;
    quad[1].fPos = pts[0] - normal;
    quad[2].fPos = pts[1] - normal;
    quad[3].fPos = pts[2] - normal;
    quad[4].fPos = pts[2] + normal;
    for (int i = 0; i < kQuadNumVertices; i++) {
        quad[i].fWinding = cross < 0 ? 1 : -1;
        if (cross > 0.0) {
            quad[i].fVert2 = pts[0];
            quad[i].fVert3 = pts[2];
        }
        else {
            quad[i].fVert2 = pts[2];
            quad[i].fVert3 = pts[0];
        }
    }
    GrPathUtils::QuadUVMatrix DevToUV(pts);
    DevToUV.apply<kQuadNumVertices, sizeof(PLSVertex), sizeof(SkPoint)>(quad);
    for (int i = 2; i < kQuadNumVertices; i++) {
        vertices.push_back(quad[0]);
        vertices.push_back(quad[i - 1]);
        vertices.push_back(quad[i]);
    }
}

/* Used by bloat_tri; outsets a single point. */
static bool outset(SkPoint* p1, SkPoint line1, SkPoint line2) {
    // rotate the two line vectors 90 degrees to form the normals, and compute
    // the dot product of the normals
    SkScalar dotProd = line1.fY * line2.fY + line1.fX * line2.fX;
    SkScalar lengthSq = 1.0f / ((1.0f - dotProd) / 2.0f);
    if (lengthSq > kBloatLimit) {
        return false;
    }
    SkPoint bisector = line1 + line2;
    bisector.setLength(SkScalarSqrt(lengthSq) * kBloatSize);
    *p1 += bisector;
    return true;
}

/* Bloats a triangle so as to create a border kBloatSize pixels wide all around it. */
static bool bloat_tri(SkPoint pts[3]) {
    SkPoint line1 = pts[0] - pts[1];
    line1.normalize();
    SkPoint line2 = pts[0] - pts[2];
    line2.normalize();
    SkPoint line3 = pts[1] - pts[2];
    line3.normalize();

    SkPoint result[3];
    result[0] = pts[0];
    if (!outset(&result[0], line1, line2)) {
        return false;
    }
    result[1] = pts[1];
    if (!outset(&result[1], -line1, line3)) {
        return false;
    }
    result[2] = pts[2];
    if (!outset(&result[2], -line3, -line2)) {
        return false;
    }
    pts[0] = result[0];
    pts[1] = result[1];
    pts[2] = result[2];
    return true;
}

static bool get_geometry(const SkPath& path, const SkMatrix& m, PLSVertices& triVertices,
                         PLSVertices& quadVertices, GrResourceProvider* resourceProvider,
                         SkRect bounds) {
    SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
    SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, m, bounds);
    int contourCnt;
    int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt, tol);
    if (maxPts <= 0) {
        return 0;
    }
    SkPath linesOnlyPath;
    linesOnlyPath.setFillType(path.getFillType());
    SkSTArray<15, SkPoint, true> quadPoints;
    SkPath::Iter iter(path, true);
    bool done = false;
    while (!done) {
        SkPoint pts[4];
        SkPath::Verb verb = iter.next(pts);
        switch (verb) {
            case SkPath::kMove_Verb:
                SkASSERT(quadPoints.count() % 3 == 0);
                for (int i = 0; i < quadPoints.count(); i += 3) {
                    add_quad(&quadPoints[i], quadVertices);
                }
                quadPoints.reset();
                m.mapPoints(&pts[0], 1);
                linesOnlyPath.moveTo(pts[0]);
                break;
            case SkPath::kLine_Verb:
                m.mapPoints(&pts[1], 1);
                linesOnlyPath.lineTo(pts[1]);
                break;
            case SkPath::kQuad_Verb:
                m.mapPoints(pts, 3);
                linesOnlyPath.lineTo(pts[2]);
                quadPoints.push_back(pts[0]);
                quadPoints.push_back(pts[1]);
                quadPoints.push_back(pts[2]);
                break;
            case SkPath::kCubic_Verb: {
                m.mapPoints(pts, 4);
                SkSTArray<15, SkPoint, true> quads;
                GrPathUtils::convertCubicToQuads(pts, kCubicTolerance, &quads);
                int count = quads.count();
                for (int q = 0; q < count; q += 3) {
                    linesOnlyPath.lineTo(quads[q + 2]);
                    quadPoints.push_back(quads[q]);
                    quadPoints.push_back(quads[q + 1]);
                    quadPoints.push_back(quads[q + 2]);
                }
                break;
            }
            case SkPath::kConic_Verb: {
                m.mapPoints(pts, 3);
                SkScalar weight = iter.conicWeight();
                SkAutoConicToQuads converter;
                const SkPoint* quads = converter.computeQuads(pts, weight, kConicTolerance);
                int count = converter.countQuads();
                for (int i = 0; i < count; ++i) {
                    linesOnlyPath.lineTo(quads[2 * i + 2]);
                    quadPoints.push_back(quads[2 * i]);
                    quadPoints.push_back(quads[2 * i + 1]);
                    quadPoints.push_back(quads[2 * i + 2]);
                }
                break;
            }
            case SkPath::kClose_Verb:
                linesOnlyPath.close();
                break;
            case SkPath::kDone_Verb:
                done = true;
                break;
            default: SkASSERT(false);
        }
    }
    SkASSERT(quadPoints.count() % 3 == 0);
    for (int i = 0; i < quadPoints.count(); i += 3) {
        add_quad(&quadPoints[i], quadVertices);
    }

    static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
    GrUniqueKey key;
    GrUniqueKey::Builder builder(&key, kDomain, 2);
    builder[0] = path.getGenerationID();
    builder[1] = path.getFillType();
    builder.finish();
    GrTessellator::WindingVertex* windingVertices;
    int triVertexCount = GrTessellator::PathToVertices(linesOnlyPath, 0, bounds, &windingVertices);
    if (triVertexCount > 0) {
        for (int i = 0; i < triVertexCount; i += 3) {
            SkPoint p1 = windingVertices[i].fPos;
            SkPoint p2 = windingVertices[i + 1].fPos;
            SkPoint p3 = windingVertices[i + 2].fPos;
            int winding = windingVertices[i].fWinding;
            SkASSERT(windingVertices[i + 1].fWinding == winding);
            SkASSERT(windingVertices[i + 2].fWinding == winding);
            SkScalar cross = (p2 - p1).cross(p3 - p1);
            SkPoint bloated[3] = { p1, p2, p3 };
            if (cross < 0.0f) {
                SkTSwap(p1, p3);
            }
            if (bloat_tri(bloated)) {
                triVertices.push_back({ bloated[0], p1, p2, p3, winding });
                triVertices.push_back({ bloated[1], p1, p2, p3, winding });
                triVertices.push_back({ bloated[2], p1, p2, p3, winding });
            }
            else {
                SkScalar minX = SkTMin(p1.fX, SkTMin(p2.fX, p3.fX)) - 1.0f;
                SkScalar minY = SkTMin(p1.fY, SkTMin(p2.fY, p3.fY)) - 1.0f;
                SkScalar maxX = SkTMax(p1.fX, SkTMax(p2.fX, p3.fX)) + 1.0f;
                SkScalar maxY = SkTMax(p1.fY, SkTMax(p2.fY, p3.fY)) + 1.0f;
                triVertices.push_back({ { minX, minY }, p1, p2, p3, winding });
                triVertices.push_back({ { maxX, minY }, p1, p2, p3, winding });
                triVertices.push_back({ { minX, maxY }, p1, p2, p3, winding });
                triVertices.push_back({ { maxX, minY }, p1, p2, p3, winding });
                triVertices.push_back({ { maxX, maxY }, p1, p2, p3, winding });
                triVertices.push_back({ { minX, maxY }, p1, p2, p3, winding });
            }
        }
        delete[] windingVertices;
    }
    return triVertexCount > 0 || quadVertices.count() > 0;
}

class PLSAATriangleEffect : public GrPLSGeometryProcessor {
public:

    static GrPLSGeometryProcessor* Create(const SkMatrix& localMatrix,
                                          bool usesLocalCoords) {
        return new PLSAATriangleEffect(localMatrix, usesLocalCoords);
    }

    virtual ~PLSAATriangleEffect() {}

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

    const Attribute* inPosition() const { return fInPosition; }
    const Attribute* inVertex1() const { return fInVertex1; }
    const Attribute* inVertex2() const { return fInVertex2; }
    const Attribute* inVertex3() const { return fInVertex3; }
    const Attribute* inWindings() const { return fInWindings; }
    const SkMatrix& localMatrix() const { return fLocalMatrix; }
    bool usesLocalCoords() const { return fUsesLocalCoords; }

    class GLSLProcessor : public GrGLSLGeometryProcessor {
    public:
        GLSLProcessor(const GrGeometryProcessor&) {}

        void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
            const PLSAATriangleEffect& te = args.fGP.cast<PLSAATriangleEffect>();
            GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
            GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
            GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;

            varyingHandler->emitAttributes(te);

            this->setupPosition(vsBuilder, gpArgs, te.inPosition()->fName);

            GrGLSLVertToFrag v1(kVec2f_GrSLType);
            varyingHandler->addVarying("Vertex1", &v1, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);",
                                   v1.vsOut(),
                                   te.inVertex1()->fName,
                                   te.inVertex1()->fName);

            GrGLSLVertToFrag v2(kVec2f_GrSLType);
            varyingHandler->addVarying("Vertex2", &v2, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);",
                                   v2.vsOut(),
                                   te.inVertex2()->fName,
                                   te.inVertex2()->fName);

            GrGLSLVertToFrag v3(kVec2f_GrSLType);
            varyingHandler->addVarying("Vertex3", &v3, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);",
                                   v3.vsOut(),
                                   te.inVertex3()->fName,
                                   te.inVertex3()->fName);

            GrGLSLVertToFrag delta1(kVec2f_GrSLType);
            varyingHandler->addVarying("delta1", &delta1, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;",
                                   delta1.vsOut(), v1.vsOut(), v2.vsOut(), v2.vsOut(), v1.vsOut());

            GrGLSLVertToFrag delta2(kVec2f_GrSLType);
            varyingHandler->addVarying("delta2", &delta2, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;",
                                   delta2.vsOut(), v2.vsOut(), v3.vsOut(), v3.vsOut(), v2.vsOut());

            GrGLSLVertToFrag delta3(kVec2f_GrSLType);
            varyingHandler->addVarying("delta3", &delta3, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;",
                                   delta3.vsOut(), v3.vsOut(), v1.vsOut(), v1.vsOut(), v3.vsOut());

            GrGLSLVertToFrag windings(kInt_GrSLType);
            varyingHandler->addFlatVarying("windings", &windings, kLow_GrSLPrecision);
            vsBuilder->codeAppendf("%s = %s;",
                                   windings.vsOut(), te.inWindings()->fName);

            // emit transforms
            this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
                                 te.inPosition()->fName, te.localMatrix(), args.fTransformsIn,
                                 args.fTransformsOut);

            GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
            SkAssertResult(fsBuilder->enableFeature(
                           GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature));
            SkAssertResult(fsBuilder->enableFeature(
                    GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
            fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL);
            // Compute four subsamples, each shifted a quarter pixel along x and y from
            // gl_FragCoord. The oriented box positioning of the subsamples is of course not
            // optimal, but it greatly simplifies the math and this simplification is necessary for
            // performance reasons.
            fsBuilder->codeAppendf("highp vec2 firstSample = %s.xy - vec2(0.25);",
                                   fsBuilder->fragmentPosition());
            fsBuilder->codeAppendf("highp vec2 delta1 = %s;", delta1.fsIn());
            fsBuilder->codeAppendf("highp vec2 delta2 = %s;", delta2.fsIn());
            fsBuilder->codeAppendf("highp vec2 delta3 = %s;", delta3.fsIn());
            // Check whether first sample is inside the triangle by computing three dot products. If
            // all are < 0, we're inside. The first vector in each case is half of what it is
            // "supposed" to be, because we re-use them later as adjustment factors for which half
            // is the correct value, so we multiply the dots by two to compensate.
            fsBuilder->codeAppendf("highp float d1 = dot(delta1, (firstSample - %s).yx) * 2.0;",
                                   v1.fsIn());
            fsBuilder->codeAppendf("highp float d2 = dot(delta2, (firstSample - %s).yx) * 2.0;",
                                   v2.fsIn());
            fsBuilder->codeAppendf("highp float d3 = dot(delta3, (firstSample - %s).yx) * 2.0;",
                                   v3.fsIn());
            fsBuilder->codeAppend("highp float dmax = max(d1, max(d2, d3));");
            fsBuilder->codeAppendf("pls.windings[0] += (dmax <= 0.0) ? %s : 0;", windings.fsIn());
            // for subsequent samples, we don't recalculate the entire dot product -- just adjust it
            // to the value it would have if we did recompute it.
            fsBuilder->codeAppend("d1 += delta1.x;");
            fsBuilder->codeAppend("d2 += delta2.x;");
            fsBuilder->codeAppend("d3 += delta3.x;");
            fsBuilder->codeAppend("dmax = max(d1, max(d2, d3));");
            fsBuilder->codeAppendf("pls.windings[1] += (dmax <= 0.0) ? %s : 0;", windings.fsIn());
            fsBuilder->codeAppend("d1 += delta1.y;");
            fsBuilder->codeAppend("d2 += delta2.y;");
            fsBuilder->codeAppend("d3 += delta3.y;");
            fsBuilder->codeAppend("dmax = max(d1, max(d2, d3));");
            fsBuilder->codeAppendf("pls.windings[2] += (dmax <= 0.0) ? %s : 0;", windings.fsIn());
            fsBuilder->codeAppend("d1 -= delta1.x;");
            fsBuilder->codeAppend("d2 -= delta2.x;");
            fsBuilder->codeAppend("d3 -= delta3.x;");
            fsBuilder->codeAppend("dmax = max(d1, max(d2, d3));");
            fsBuilder->codeAppendf("pls.windings[3] += (dmax <= 0.0) ? %s : 0;", windings.fsIn());
        }

        static inline void GenKey(const GrGeometryProcessor& gp,
                                  const GrGLSLCaps&,
                                  GrProcessorKeyBuilder* b) {
            const PLSAATriangleEffect& te = gp.cast<PLSAATriangleEffect>();
            uint32_t key = 0;
            key |= te.localMatrix().hasPerspective() ? 0x1 : 0x0;
            b->add32(key);
        }

        virtual void setData(const GrGLSLProgramDataManager& pdman,
                             const GrPrimitiveProcessor& gp) override {
        }

        void setTransformData(const GrPrimitiveProcessor& primProc,
                              const GrGLSLProgramDataManager& pdman,
                              int index,
                              const SkTArray<const GrCoordTransform*, true>& transforms) override {
            this->setTransformDataHelper(primProc.cast<PLSAATriangleEffect>().fLocalMatrix, pdman,
                                         index, transforms);
        }

    private:
        typedef GrGLSLGeometryProcessor INHERITED;
    };

    virtual void getGLSLProcessorKey(const GrGLSLCaps& caps,
                                   GrProcessorKeyBuilder* b) const override {
        GLSLProcessor::GenKey(*this, caps, b);
    }

    virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) const override {
        return new GLSLProcessor(*this);
    }

private:
    PLSAATriangleEffect(const SkMatrix& localMatrix, bool usesLocalCoords)
        : fLocalMatrix(localMatrix)
        , fUsesLocalCoords(usesLocalCoords) {
        this->initClassID<PLSAATriangleEffect>();
        fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
                                             kHigh_GrSLPrecision);
        fInVertex1 = &this->addVertexAttrib("inVertex1", kVec2f_GrVertexAttribType,
                                            kHigh_GrSLPrecision);
        fInVertex2 = &this->addVertexAttrib("inVertex2", kVec2f_GrVertexAttribType,
                                            kHigh_GrSLPrecision);
        fInVertex3 = &this->addVertexAttrib("inVertex3", kVec2f_GrVertexAttribType,
                                            kHigh_GrSLPrecision);
        fInWindings = &this->addVertexAttrib("inWindings", kInt_GrVertexAttribType,
                                             kLow_GrSLPrecision);
        this->setWillReadFragmentPosition();
    }

    const Attribute* fInPosition;
    const Attribute* fInVertex1;
    const Attribute* fInVertex2;
    const Attribute* fInVertex3;
    const Attribute* fInWindings;
    SkMatrix         fLocalMatrix;
    bool             fUsesLocalCoords;

    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;

    typedef GrGeometryProcessor INHERITED;
};

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

/*
 * Quadratic specified by 0=u^2-v canonical coords. u and v are the first
 * two components of the vertex attribute. Coverage is based on signed
 * distance with negative being inside, positive outside. The edge is specified in
 * window space (y-down). If either the third or fourth component of the interpolated
 * vertex coord is > 0 then the pixel is considered outside the edge. This is used to
 * attempt to trim to a portion of the infinite quad.
 * Requires shader derivative instruction support.
 */

class PLSQuadEdgeEffect : public GrPLSGeometryProcessor {
public:

    static GrPLSGeometryProcessor* Create(const SkMatrix& localMatrix,
                                          bool usesLocalCoords) {
        return new PLSQuadEdgeEffect(localMatrix, usesLocalCoords);
    }

    virtual ~PLSQuadEdgeEffect() {}

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

    const Attribute* inPosition() const { return fInPosition; }
    const Attribute* inUV() const { return fInUV; }
    const Attribute* inEndpoint1() const { return fInEndpoint1; }
    const Attribute* inEndpoint2() const { return fInEndpoint2; }
    const Attribute* inWindings() const { return fInWindings; }
    const SkMatrix& localMatrix() const { return fLocalMatrix; }
    bool usesLocalCoords() const { return fUsesLocalCoords; }

    class GLSLProcessor : public GrGLSLGeometryProcessor {
    public:
        GLSLProcessor(const GrGeometryProcessor&) {}

        void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
            const PLSQuadEdgeEffect& qe = args.fGP.cast<PLSQuadEdgeEffect>();
            GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
            GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
            GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;

            // emit attributes
            varyingHandler->emitAttributes(qe);

            GrGLSLVertToFrag uv(kVec2f_GrSLType);
            varyingHandler->addVarying("uv", &uv, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = %s;", uv.vsOut(), qe.inUV()->fName);

            GrGLSLVertToFrag ep1(kVec2f_GrSLType);
            varyingHandler->addVarying("endpoint1", &ep1, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);", ep1.vsOut(),
                                  qe.inEndpoint1()->fName, qe.inEndpoint1()->fName);

            GrGLSLVertToFrag ep2(kVec2f_GrSLType);
            varyingHandler->addVarying("endpoint2", &ep2, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x, %s.y);", ep2.vsOut(),
                                  qe.inEndpoint2()->fName, qe.inEndpoint2()->fName);

            GrGLSLVertToFrag delta(kVec2f_GrSLType);
            varyingHandler->addVarying("delta", &delta, kHigh_GrSLPrecision);
            vsBuilder->codeAppendf("%s = vec2(%s.x - %s.x, %s.y - %s.y) * 0.5;",
                                   delta.vsOut(), ep1.vsOut(), ep2.vsOut(), ep2.vsOut(),
                                   ep1.vsOut());

            GrGLSLVertToFrag windings(kInt_GrSLType);
            varyingHandler->addFlatVarying("windings", &windings, kLow_GrSLPrecision);
            vsBuilder->codeAppendf("%s = %s;",
                                   windings.vsOut(), qe.inWindings()->fName);

            // Setup position
            this->setupPosition(vsBuilder, gpArgs, qe.inPosition()->fName);

            // emit transforms
            this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
                                 qe.inPosition()->fName, qe.localMatrix(), args.fTransformsIn,
                                 args.fTransformsOut);

            GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
            SkAssertResult(fsBuilder->enableFeature(
                           GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature));
            SkAssertResult(fsBuilder->enableFeature(
                    GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
            static const int QUAD_ARGS = 2;
            GrGLSLShaderVar inQuadArgs[QUAD_ARGS] = {
                GrGLSLShaderVar("dot", kFloat_GrSLType, 0, kHigh_GrSLPrecision),
                GrGLSLShaderVar("uv", kVec2f_GrSLType, 0, kHigh_GrSLPrecision)
            };
            SkString inQuadName;

            const char* inQuadCode = "if (uv.x * uv.x <= uv.y) {"
                                     "return dot >= 0.0;"
                                     "} else {"
                                     "return false;"
                                     "}";
            fsBuilder->emitFunction(kBool_GrSLType, "in_quad", QUAD_ARGS, inQuadArgs, inQuadCode,
                                    &inQuadName);
            fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL);
            // keep the derivative instructions outside the conditional
            fsBuilder->codeAppendf("highp vec2 uvdX = dFdx(%s);", uv.fsIn());
            fsBuilder->codeAppendf("highp vec2 uvdY = dFdy(%s);", uv.fsIn());
            fsBuilder->codeAppend("highp vec2 uvIncX = uvdX * 0.45 + uvdY * -0.1;");
            fsBuilder->codeAppend("highp vec2 uvIncY = uvdX * 0.1 + uvdY * 0.55;");
            fsBuilder->codeAppendf("highp vec2 uv = %s.xy - uvdX * 0.35 - uvdY * 0.25;",
                                   uv.fsIn());
            fsBuilder->codeAppendf("highp vec2 firstSample = %s.xy - vec2(0.25);",
                                   fsBuilder->fragmentPosition());
            fsBuilder->codeAppendf("highp float d = dot(%s, (firstSample - %s).yx) * 2.0;",
                                   delta.fsIn(), ep1.fsIn());
            fsBuilder->codeAppendf("pls.windings[0] += %s(d, uv) ? %s : 0;", inQuadName.c_str(),
                                   windings.fsIn());
            fsBuilder->codeAppend("uv += uvIncX;");
            fsBuilder->codeAppendf("d += %s.x;", delta.fsIn());
            fsBuilder->codeAppendf("pls.windings[1] += %s(d, uv) ? %s : 0;", inQuadName.c_str(),
                                   windings.fsIn());
            fsBuilder->codeAppend("uv += uvIncY;");
            fsBuilder->codeAppendf("d += %s.y;", delta.fsIn());
            fsBuilder->codeAppendf("pls.windings[2] += %s(d, uv) ? %s : 0;", inQuadName.c_str(),
                                   windings.fsIn());
            fsBuilder->codeAppend("uv -= uvIncX;");
            fsBuilder->codeAppendf("d -= %s.x;", delta.fsIn());
            fsBuilder->codeAppendf("pls.windings[3] += %s(d, uv) ? %s : 0;", inQuadName.c_str(),
                                   windings.fsIn());
        }

        static inline void GenKey(const GrGeometryProcessor& gp,
                                  const GrGLSLCaps&,
                                  GrProcessorKeyBuilder* b) {
            const PLSQuadEdgeEffect& qee = gp.cast<PLSQuadEdgeEffect>();
            uint32_t key = 0;
            key |= qee.usesLocalCoords() && qee.localMatrix().hasPerspective() ? 0x1 : 0x0;
            b->add32(key);
        }

        virtual void setData(const GrGLSLProgramDataManager& pdman,
                             const GrPrimitiveProcessor& gp) override {
        }

        void setTransformData(const GrPrimitiveProcessor& primProc,
                              const GrGLSLProgramDataManager& pdman,
                              int index,
                              const SkTArray<const GrCoordTransform*, true>& transforms) override {
            this->setTransformDataHelper(primProc.cast<PLSQuadEdgeEffect>().fLocalMatrix, pdman,
                                         index, transforms);
        }

    private:
        typedef GrGLSLGeometryProcessor INHERITED;
    };

    virtual void getGLSLProcessorKey(const GrGLSLCaps& caps,
                                   GrProcessorKeyBuilder* b) const override {
        GLSLProcessor::GenKey(*this, caps, b);
    }

    virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) const override {
        return new GLSLProcessor(*this);
    }

private:
    PLSQuadEdgeEffect(const SkMatrix& localMatrix, bool usesLocalCoords)
        : fLocalMatrix(localMatrix)
        , fUsesLocalCoords(usesLocalCoords) {
        this->initClassID<PLSQuadEdgeEffect>();
        fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
                                             kHigh_GrSLPrecision);
        fInUV = &this->addVertexAttrib("inUV", kVec2f_GrVertexAttribType, kHigh_GrSLPrecision);
        fInEndpoint1 = &this->addVertexAttrib("inEndpoint1", kVec2f_GrVertexAttribType,
                                              kHigh_GrSLPrecision);
        fInEndpoint2 = &this->addVertexAttrib("inEndpoint2", kVec2f_GrVertexAttribType,
                                              kHigh_GrSLPrecision);
        fInWindings  = &this->addVertexAttrib("inWindings", kInt_GrVertexAttribType,
                                              kLow_GrSLPrecision);
        this->setWillReadFragmentPosition();
    }

    const Attribute* fInPosition;
    const Attribute* fInUV;
    const Attribute* fInEndpoint1;
    const Attribute* fInEndpoint2;
    const Attribute* fInWindings;
    SkMatrix         fLocalMatrix;
    bool             fUsesLocalCoords;

    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;

    typedef GrGeometryProcessor INHERITED;
};

class PLSFinishEffect : public GrGeometryProcessor {
public:

    static GrGeometryProcessor* Create(GrColor color, bool useEvenOdd, const SkMatrix& localMatrix,
                                       bool usesLocalCoords) {
        return new PLSFinishEffect(color, useEvenOdd, localMatrix, usesLocalCoords);
    }

    virtual ~PLSFinishEffect() {}

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

    const Attribute* inPosition() const { return fInPosition; }
    GrColor color() const { return fColor; }
    bool colorIgnored() const { return GrColor_ILLEGAL == fColor; }
    const SkMatrix& localMatrix() const { return fLocalMatrix; }
    bool usesLocalCoords() const { return fUsesLocalCoords; }

    GrPixelLocalStorageState getPixelLocalStorageState() const override {
        return GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState;
    }

    const char* getDestColorOverride() const override {
        return GR_GL_PLS_DSTCOLOR_NAME;
    }

    class GLSLProcessor : public GrGLSLGeometryProcessor {
    public:
        GLSLProcessor(const GrGeometryProcessor&) {}

        void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
            const PLSFinishEffect& fe = args.fGP.cast<PLSFinishEffect>();
            GrGLSLVertexBuilder* vsBuilder = args.fVertBuilder;
            GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
            GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;

            fUseEvenOdd = uniformHandler->addUniform(kFragment_GrShaderFlag,
                                                    kFloat_GrSLType, kLow_GrSLPrecision,
                                                    "useEvenOdd");
            const char* useEvenOdd = uniformHandler->getUniformCStr(fUseEvenOdd);

            varyingHandler->emitAttributes(fe);
            this->setupPosition(vsBuilder, gpArgs, fe.inPosition()->fName);
            this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar,
                                 fe.inPosition()->fName, fe.localMatrix(), args.fTransformsIn,
                                 args.fTransformsOut);

            GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder;
            SkAssertResult(fsBuilder->enableFeature(
                           GrGLSLFragmentShaderBuilder::kPixelLocalStorage_GLSLFeature));
            fsBuilder->declAppendf(GR_GL_PLS_PATH_DATA_DECL);
            fsBuilder->codeAppend("float coverage;");
            fsBuilder->codeAppendf("if (%s != 0.0) {", useEvenOdd);
            fsBuilder->codeAppend("coverage = float(abs(pls.windings[0]) % 2) * 0.25;");
            fsBuilder->codeAppend("coverage += float(abs(pls.windings[1]) % 2) * 0.25;");
            fsBuilder->codeAppend("coverage += float(abs(pls.windings[2]) % 2) * 0.25;");
            fsBuilder->codeAppend("coverage += float(abs(pls.windings[3]) % 2) * 0.25;");
            fsBuilder->codeAppend("} else {");
            fsBuilder->codeAppend("coverage = pls.windings[0] != 0 ? 0.25 : 0.0;");
            fsBuilder->codeAppend("coverage += pls.windings[1] != 0 ? 0.25 : 0.0;");
            fsBuilder->codeAppend("coverage += pls.windings[2] != 0 ? 0.25 : 0.0;");
            fsBuilder->codeAppend("coverage += pls.windings[3] != 0 ? 0.25 : 0.0;");
            fsBuilder->codeAppend("}");
            if (!fe.colorIgnored()) {
                this->setupUniformColor(fsBuilder, uniformHandler, args.fOutputColor,
                                        &fColorUniform);
            }
            fsBuilder->codeAppendf("%s = vec4(coverage);", args.fOutputCoverage);
            fsBuilder->codeAppendf("%s = vec4(1.0, 0.0, 1.0, 1.0);", args.fOutputColor);
        }

        static inline void GenKey(const GrGeometryProcessor& gp,
                                  const GrGLSLCaps&,
                                  GrProcessorKeyBuilder* b) {
            const PLSFinishEffect& fe = gp.cast<PLSFinishEffect>();
            uint32_t key = 0;
            key |= fe.usesLocalCoords() && fe.localMatrix().hasPerspective() ? 0x1 : 0x0;
            b->add32(key);
        }

        virtual void setData(const GrGLSLProgramDataManager& pdman,
                             const GrPrimitiveProcessor& gp) override {
            const PLSFinishEffect& fe = gp.cast<PLSFinishEffect>();
            pdman.set1f(fUseEvenOdd, fe.fUseEvenOdd);
            if (fe.color() != fColor && !fe.colorIgnored()) {
                GrGLfloat c[4];
                GrColorToRGBAFloat(fe.color(), c);
                pdman.set4fv(fColorUniform, 1, c);
                fColor = fe.color();
            }
        }

        void setTransformData(const GrPrimitiveProcessor& primProc,
                              const GrGLSLProgramDataManager& pdman,
                              int index,
                              const SkTArray<const GrCoordTransform*, true>& transforms) override {
            this->setTransformDataHelper(primProc.cast<PLSFinishEffect>().fLocalMatrix, pdman,
                                         index, transforms);
        }

    private:
        GrColor fColor;
        UniformHandle fColorUniform;
        UniformHandle fUseEvenOdd;

        typedef GrGLSLGeometryProcessor INHERITED;
    };

    virtual void getGLSLProcessorKey(const GrGLSLCaps& caps,
                                   GrProcessorKeyBuilder* b) const override {
        GLSLProcessor::GenKey(*this, caps, b);
    }

    virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) const override {
        return new GLSLProcessor(*this);
    }

private:
    PLSFinishEffect(GrColor color, bool useEvenOdd, const SkMatrix& localMatrix,
                    bool usesLocalCoords)
        : fColor(color)
        , fUseEvenOdd(useEvenOdd)
        , fLocalMatrix(localMatrix)
        , fUsesLocalCoords(usesLocalCoords) {
        this->initClassID<PLSFinishEffect>();
        fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
                                             kHigh_GrSLPrecision);
    }

    const Attribute* fInPosition;
    GrColor          fColor;
    bool             fUseEvenOdd;
    SkMatrix         fLocalMatrix;
    bool             fUsesLocalCoords;

    typedef GrGeometryProcessor INHERITED;
};

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

bool GrPLSPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
    // We have support for even-odd rendering, but are having some troublesome
    // seams. Disable in the presence of even-odd for now.
    SkPath path;
    args.fShape->asPath(&path);
    return args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
            args.fShape->style().isSimpleFill() && !path.isInverseFillType() &&
            path.getFillType() == SkPath::FillType::kWinding_FillType;
}

class PLSPathBatch : public GrVertexBatch {
public:
    DEFINE_BATCH_CLASS_ID
    PLSPathBatch(GrColor color, const SkPath& path, const SkMatrix& viewMatrix)
            : INHERITED(ClassID())
            , fColor(color)
            , fPath(path)
            , fViewMatrix(viewMatrix) {
        // compute bounds
        this->setTransformedBounds(path.getBounds(), fViewMatrix, HasAABloat::kYes,
                                   IsZeroArea::kNo);
    }

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

    void computePipelineOptimizations(GrInitInvariantOutput* color,
                                      GrInitInvariantOutput* coverage,
                                      GrBatchToXPOverrides* overrides) const override {
        // When this is called on a batch, there is only one geometry bundle
        color->setKnownFourComponents(fColor);
        coverage->setUnknownSingleComponent();
        overrides->fUsePLSDstRead = true;
    }

    void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
        // Handle any color overrides
        if (!overrides.readsColor()) {
            fColor = GrColor_ILLEGAL;
        }
        overrides.getOverrideColorIfSet(&fColor);

        // setup batch properties
        fUsesLocalCoords = overrides.readsLocalCoords();
    }

    void onPrepareDraws(Target* target) const override {

        SkMatrix invert;
        if (fUsesLocalCoords && !fViewMatrix.invert(&invert)) {
            SkDebugf("Could not invert viewmatrix\n");
            return;
        }

        // Setup GrGeometryProcessors
        SkAutoTUnref<GrPLSGeometryProcessor> triangleProcessor(
                PLSAATriangleEffect::Create(invert, fUsesLocalCoords));
        SkAutoTUnref<GrPLSGeometryProcessor> quadProcessor(
                PLSQuadEdgeEffect::Create(invert, fUsesLocalCoords));

        GrResourceProvider* rp = target->resourceProvider();
        SkRect bounds;
        this->bounds().roundOut(&bounds);
        triangleProcessor->setBounds(bounds);
        quadProcessor->setBounds(bounds);

        // We use the fact that SkPath::transform path does subdivision based on
        // perspective. Otherwise, we apply the view matrix when copying to the
        // segment representation.
        const SkMatrix* viewMatrix = &fViewMatrix;

        // We avoid initializing the path unless we have to
        const SkPath* pathPtr = &fPath;
        SkTLazy<SkPath> tmpPath;
        if (viewMatrix->hasPerspective()) {
            SkPath* tmpPathPtr = tmpPath.init(*pathPtr);
            tmpPathPtr->setIsVolatile(true);
            tmpPathPtr->transform(*viewMatrix);
            viewMatrix = &SkMatrix::I();
            pathPtr = tmpPathPtr;
        }

        GrMesh mesh;

        PLSVertices triVertices;
        PLSVertices quadVertices;
        if (!get_geometry(*pathPtr, *viewMatrix, triVertices, quadVertices, rp, bounds)) {
            return;
        }

        if (triVertices.count()) {
            const GrBuffer* triVertexBuffer;
            int firstTriVertex;
            size_t triStride = triangleProcessor->getVertexStride();
            PLSVertex* triVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace(
                    triStride, triVertices.count(), &triVertexBuffer, &firstTriVertex));
            if (!triVerts) {
                SkDebugf("Could not allocate vertices\n");
                return;
            }
            for (int i = 0; i < triVertices.count(); ++i) {
                triVerts[i] = triVertices[i];
            }
            mesh.init(kTriangles_GrPrimitiveType, triVertexBuffer, firstTriVertex,
                      triVertices.count());
            target->draw(triangleProcessor, mesh);
        }

        if (quadVertices.count()) {
            const GrBuffer* quadVertexBuffer;
            int firstQuadVertex;
            size_t quadStride = quadProcessor->getVertexStride();
            PLSVertex* quadVerts = reinterpret_cast<PLSVertex*>(target->makeVertexSpace(
                    quadStride, quadVertices.count(), &quadVertexBuffer, &firstQuadVertex));
            if (!quadVerts) {
                SkDebugf("Could not allocate vertices\n");
                return;
            }
            for (int i = 0; i < quadVertices.count(); ++i) {
                quadVerts[i] = quadVertices[i];
            }
            mesh.init(kTriangles_GrPrimitiveType, quadVertexBuffer, firstQuadVertex,
                      quadVertices.count());
            target->draw(quadProcessor, mesh);
        }

        SkAutoTUnref<GrGeometryProcessor> finishProcessor(
                PLSFinishEffect::Create(fColor,
                                        pathPtr->getFillType() ==
                                                            SkPath::FillType::kEvenOdd_FillType,
                                        invert,
                                        fUsesLocalCoords));
        const GrBuffer* rectVertexBuffer;
        size_t finishStride = finishProcessor->getVertexStride();
        int firstRectVertex;
        static const int kRectVertexCount = 6;
        SkPoint* rectVerts = reinterpret_cast<SkPoint*>(target->makeVertexSpace(
                finishStride, kRectVertexCount, &rectVertexBuffer, &firstRectVertex));
        if (!rectVerts) {
            SkDebugf("Could not allocate vertices\n");
            return;
        }
        rectVerts[0] = { bounds.fLeft, bounds.fTop };
        rectVerts[1] = { bounds.fLeft, bounds.fBottom };
        rectVerts[2] = { bounds.fRight, bounds.fBottom };
        rectVerts[3] = { bounds.fLeft, bounds.fTop };
        rectVerts[4] = { bounds.fRight, bounds.fTop };
        rectVerts[5] = { bounds.fRight, bounds.fBottom };

        mesh.init(kTriangles_GrPrimitiveType, rectVertexBuffer, firstRectVertex,
                  kRectVertexCount);
        target->draw(finishProcessor, mesh);
    }

private:
    bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
        return false;
    }

    bool fUsesLocalCoords;

    GrColor fColor;
    SkPath fPath;
    SkMatrix fViewMatrix;
    typedef GrVertexBatch INHERITED;
};

SkDEBUGCODE(bool inPLSDraw = false;)
bool GrPLSPathRenderer::onDrawPath(const DrawPathArgs& args) {
    SkASSERT(!args.fShape->isEmpty());
    SkASSERT(!inPLSDraw);
    SkDEBUGCODE(inPLSDraw = true;)
    SkPath path;
    args.fShape->asPath(&path);

    SkAutoTUnref<GrDrawBatch> batch(new PLSPathBatch(args.fPaint->getColor(),
                                                     path, *args.fViewMatrix));

    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHWAA(*args.fPaint));
    pipelineBuilder.setUserStencil(args.fUserStencilSettings);

    args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);

    SkDEBUGCODE(inPLSDraw = false;)
    return true;

}

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

#ifdef GR_TEST_UTILS

DRAW_BATCH_TEST_DEFINE(PLSPathBatch) {
    GrColor color = GrRandomColor(random);
    SkMatrix vm = GrTest::TestMatrixInvertible(random);
    SkPath path = GrTest::TestPathConvex(random);

    return new PLSPathBatch(color, path, vm);
}

#endif
