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

#include "GrCCPRCoverageProcessor.h"

#include "GrRenderTargetProxy.h"
#include "ccpr/GrCCPRTriangleProcessor.h"
#include "ccpr/GrCCPRQuadraticProcessor.h"
#include "ccpr/GrCCPRCubicProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLGeometryShaderBuilder.h"
#include "glsl/GrGLSLProgramBuilder.h"
#include "glsl/GrGLSLVertexShaderBuilder.h"

const char* GrCCPRCoverageProcessor::GetProcessorName(Mode mode) {
    switch (mode) {
        case Mode::kTriangleHulls:
            return "GrCCPRTriangleHullAndEdgeProcessor (hulls)";
        case Mode::kTriangleEdges:
            return "GrCCPRTriangleHullAndEdgeProcessor (edges)";
        case Mode::kTriangleCorners:
            return "GrCCPRTriangleCornerProcessor";
        case Mode::kQuadraticHulls:
            return "GrCCPRQuadraticHullProcessor";
        case Mode::kQuadraticCorners:
            return "GrCCPRQuadraticCornerProcessor";
        case Mode::kSerpentineHulls:
            return "GrCCPRCubicHullProcessor (serpentine)";
        case Mode::kLoopHulls:
            return "GrCCPRCubicHullProcessor (loop)";
        case Mode::kSerpentineCorners:
            return "GrCCPRCubicCornerProcessor (serpentine)";
        case Mode::kLoopCorners:
            return "GrCCPRCubicCornerProcessor (loop)";
    }
    SK_ABORT("Unexpected ccpr coverage processor mode.");
    return nullptr;
}

GrCCPRCoverageProcessor::GrCCPRCoverageProcessor(Mode mode, GrBuffer* pointsBuffer)
        : INHERITED(kGrCCPRCoverageProcessor_ClassID)
        , fMode(mode)
        , fInstanceAttrib(this->addInstanceAttrib("instance", InstanceArrayFormat(mode))) {
    fPointsBufferAccess.reset(kRG_float_GrPixelConfig, pointsBuffer, kVertex_GrShaderFlag);
    this->addBufferAccess(&fPointsBufferAccess);

    this->setWillUseGeoShader();
}

void GrCCPRCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&,
                                                  GrProcessorKeyBuilder* b) const {
    b->add32(int(fMode));
}

GrGLSLPrimitiveProcessor* GrCCPRCoverageProcessor::createGLSLInstance(const GrShaderCaps&) const {
    switch (fMode) {
        using GeometryType = GrCCPRTriangleHullAndEdgeProcessor::GeometryType;

        case Mode::kTriangleHulls:
            return new GrCCPRTriangleHullAndEdgeProcessor(GeometryType::kHulls);
        case Mode::kTriangleEdges:
            return new GrCCPRTriangleHullAndEdgeProcessor(GeometryType::kEdges);
        case Mode::kTriangleCorners:
            return new GrCCPRTriangleCornerProcessor();
        case Mode::kQuadraticHulls:
            return new GrCCPRQuadraticHullProcessor();
        case Mode::kQuadraticCorners:
            return new GrCCPRQuadraticCornerProcessor();
        case Mode::kSerpentineHulls:
            return new GrCCPRCubicHullProcessor(GrCCPRCubicProcessor::CubicType::kSerpentine);
        case Mode::kLoopHulls:
            return new GrCCPRCubicHullProcessor(GrCCPRCubicProcessor::CubicType::kLoop);
        case Mode::kSerpentineCorners:
            return new GrCCPRCubicCornerProcessor(GrCCPRCubicProcessor::CubicType::kSerpentine);
        case Mode::kLoopCorners:
            return new GrCCPRCubicCornerProcessor(GrCCPRCubicProcessor::CubicType::kLoop);
    }
    SK_ABORT("Unexpected ccpr coverage processor mode.");
    return nullptr;
}

using PrimitiveProcessor = GrCCPRCoverageProcessor::PrimitiveProcessor;

void PrimitiveProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
    const GrCCPRCoverageProcessor& proc = args.fGP.cast<GrCCPRCoverageProcessor>();

    GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
    switch (fCoverageType) {
        case CoverageType::kOne:
        case CoverageType::kShader:
            varyingHandler->addFlatVarying("wind", &fFragWind, kLow_GrSLPrecision);
            break;
        case CoverageType::kInterpolated:
            varyingHandler->addVarying("coverage_times_wind", &fFragCoverageTimesWind,
                                       kMedium_GrSLPrecision);
            break;
    }
    this->resetVaryings(varyingHandler);

    varyingHandler->emitAttributes(proc);

    this->emitVertexShader(proc, args.fVertBuilder, args.fTexelBuffers[0], args.fRTAdjustName,
                           gpArgs);
    this->emitGeometryShader(proc, args.fGeomBuilder, args.fRTAdjustName);
    this->emitCoverage(proc, args.fFragBuilder, args.fOutputColor, args.fOutputCoverage);

    SkASSERT(!args.fFPCoordTransformHandler->nextCoordTransform());
}

void PrimitiveProcessor::emitVertexShader(const GrCCPRCoverageProcessor& proc,
                                          GrGLSLVertexBuilder* v,
                                          const TexelBufferHandle& pointsBuffer,
                                          const char* rtAdjust, GrGPArgs* gpArgs) const {
    v->codeAppendf("int packedoffset = %s[%i];", proc.instanceAttrib(), proc.atlasOffsetIdx());
    v->codeAppend ("float2 atlasoffset = float2((packedoffset<<16) >> 16, "
                                                       "packedoffset >> 16);");

    this->onEmitVertexShader(proc, v, pointsBuffer, "atlasoffset", rtAdjust, gpArgs);
}

void PrimitiveProcessor::emitGeometryShader(const GrCCPRCoverageProcessor& proc,
                                            GrGLSLGeometryBuilder* g, const char* rtAdjust) const {
    g->declareGlobal(fGeomWind);
    this->emitWind(g, rtAdjust, fGeomWind.c_str());

    SkString emitVertexFn;
    SkSTArray<2, GrShaderVar> emitArgs;
    const char* position = emitArgs.emplace_back("position", kFloat2_GrSLType,
                                                 GrShaderVar::kNonArray).c_str();
    const char* coverage = emitArgs.emplace_back("coverage", kFloat_GrSLType,
                                                 GrShaderVar::kNonArray).c_str();
    g->emitFunction(kVoid_GrSLType, "emitVertex", emitArgs.count(), emitArgs.begin(), [&]() {
        SkString fnBody;
        this->emitPerVertexGeometryCode(&fnBody, position, coverage, fGeomWind.c_str());
        if (fFragWind.gsOut()) {
            fnBody.appendf("%s = %s;", fFragWind.gsOut(), fGeomWind.c_str());
        }
        if (fFragCoverageTimesWind.gsOut()) {
            fnBody.appendf("%s = %s * %s;",
                           fFragCoverageTimesWind.gsOut(), coverage, fGeomWind.c_str());
        }
        fnBody.append ("sk_Position = float4(position, 0, 1);");
        fnBody.append ("EmitVertex();");
        return fnBody;
    }().c_str(), &emitVertexFn);

    g->codeAppendf("float2 bloat = %f * abs(%s.xz);", kAABloatRadius, rtAdjust);

#ifdef SK_DEBUG
    if (proc.debugVisualizationsEnabled()) {
        g->codeAppendf("bloat *= %f;", proc.debugBloat());
    }
#endif

    return this->onEmitGeometryShader(g, emitVertexFn.c_str(), fGeomWind.c_str(), rtAdjust);
}

int PrimitiveProcessor::emitHullGeometry(GrGLSLGeometryBuilder* g, const char* emitVertexFn,
                                         const char* polygonPts, int numSides,
                                         const char* wedgeIdx, const char* midpoint) const {
    SkASSERT(numSides >= 3);

    if (!midpoint) {
        g->codeAppendf("float2 midpoint = %s * float%i(%f);",
                       polygonPts, numSides, 1.0 / numSides);
        midpoint = "midpoint";
    }

    g->codeAppendf("int previdx = (%s + %i) %% %i, "
                       "nextidx = (%s + 1) %% %i;",
                   wedgeIdx, numSides - 1, numSides, wedgeIdx, numSides);

    g->codeAppendf("float2 self = %s[%s];"
                   "int leftidx = %s > 0 ? previdx : nextidx;"
                   "int rightidx = %s > 0 ? nextidx : previdx;",
                   polygonPts, wedgeIdx, fGeomWind.c_str(), fGeomWind.c_str());

    // Which quadrant does the vector from self -> right fall into?
    g->codeAppendf("float2 right = %s[rightidx];", polygonPts);
    if (3 == numSides) {
        // TODO: evaluate perf gains.
        g->codeAppend ("float2 qsr = sign(right - self);");
    } else {
        SkASSERT(4 == numSides);
        g->codeAppendf("float2 diag = %s[(%s + 2) %% 4];", polygonPts, wedgeIdx);
        g->codeAppend ("float2 qsr = sign((right != self ? right : diag) - self);");
    }

    // Which quadrant does the vector from left -> self fall into?
    g->codeAppendf("float2 qls = sign(self - %s[leftidx]);", polygonPts);

    // d2 just helps us reduce triangle counts with orthogonal, axis-aligned lines.
    // TODO: evaluate perf gains.
    const char* dr2 = "dr";
    if (3 == numSides) {
        // TODO: evaluate perf gains.
        g->codeAppend ("float2 dr = float2(qsr.y != 0 ? +qsr.y : +qsr.x, "
                                                  "qsr.x != 0 ? -qsr.x : +qsr.y);");
        g->codeAppend ("float2 dr2 = float2(qsr.y != 0 ? +qsr.y : -qsr.x, "
                                                   "qsr.x != 0 ? -qsr.x : -qsr.y);");
        g->codeAppend ("float2 dl = float2(qls.y != 0 ? +qls.y : +qls.x, "
                                                  "qls.x != 0 ? -qls.x : +qls.y);");
        dr2 = "dr2";
    } else {
        g->codeAppend ("float2 dr = float2(qsr.y != 0 ? +qsr.y : 1, "
                                                  "qsr.x != 0 ? -qsr.x : 1);");
        g->codeAppend ("float2 dl = (qls == float2(0)) ? dr : "
                                   "float2(qls.y != 0 ? +qls.y : 1, qls.x != 0 ? -qls.x : 1);");
    }
    g->codeAppendf("bool2 dnotequal = notEqual(%s, dl);", dr2);

    // Emit one third of what is the convex hull of pixel-size boxes centered on the vertices.
    // Each invocation emits a different third.
    g->codeAppendf("%s(right + bloat * dr, 1);", emitVertexFn);
    g->codeAppendf("%s(%s, 1);", emitVertexFn, midpoint);
    g->codeAppendf("%s(self + bloat * %s, 1);", emitVertexFn, dr2);
    g->codeAppend ("if (any(dnotequal)) {");
    g->codeAppendf(    "%s(self + bloat * dl, 1);", emitVertexFn);
    g->codeAppend ("}");
    g->codeAppend ("if (all(dnotequal)) {");
    g->codeAppendf(    "%s(self + bloat * float2(-dl.y, dl.x), 1);", emitVertexFn);
    g->codeAppend ("}");
    g->codeAppend ("EndPrimitive();");

    return 5;
}

int PrimitiveProcessor::emitEdgeGeometry(GrGLSLGeometryBuilder* g, const char* emitVertexFn,
                                         const char* leftPt, const char* rightPt,
                                         const char* distanceEquation) const {
    if (!distanceEquation) {
        this->emitEdgeDistanceEquation(g, leftPt, rightPt, "float3 edge_distance_equation");
        distanceEquation = "edge_distance_equation";
    }

    // qlr is defined in emitEdgeDistanceEquation.
    g->codeAppendf("float2x2 endpts = float2x2(%s - bloat * qlr, %s + bloat * qlr);",
                   leftPt, rightPt);
    g->codeAppendf("half2 endpts_coverage = %s.xy * endpts + %s.z;",
                   distanceEquation, distanceEquation);

    // d1 is defined in emitEdgeDistanceEquation.
    g->codeAppend ("float2 d2 = d1;");
    g->codeAppend ("bool aligned = qlr.x == 0 || qlr.y == 0;");
    g->codeAppend ("if (aligned) {");
    g->codeAppend (    "d1 -= qlr;");
    g->codeAppend (    "d2 += qlr;");
    g->codeAppend ("}");

    // Emit the convex hull of 2 pixel-size boxes centered on the endpoints of the edge. Each
    // invocation emits a different edge. Emit negative coverage that subtracts the appropiate
    // amount back out from the hull we drew above.
    g->codeAppend ("if (!aligned) {");
    g->codeAppendf(    "%s(endpts[0], endpts_coverage[0]);", emitVertexFn);
    g->codeAppend ("}");
    g->codeAppendf("%s(%s + bloat * d1, -1);", emitVertexFn, leftPt);
    g->codeAppendf("%s(%s - bloat * d2, 0);", emitVertexFn, leftPt);
    g->codeAppendf("%s(%s + bloat * d2, -1);", emitVertexFn, rightPt);
    g->codeAppendf("%s(%s - bloat * d1, 0);", emitVertexFn, rightPt);
    g->codeAppend ("if (!aligned) {");
    g->codeAppendf(    "%s(endpts[1], endpts_coverage[1]);", emitVertexFn);
    g->codeAppend ("}");
    g->codeAppend ("EndPrimitive();");

    return 6;
}

void PrimitiveProcessor::emitEdgeDistanceEquation(GrGLSLGeometryBuilder* g,
                                                  const char* leftPt, const char* rightPt,
                                                  const char* outputDistanceEquation) const {
    // Which quadrant does the vector from left -> right fall into?
    g->codeAppendf("float2 qlr = sign(%s - %s);", rightPt, leftPt);
    g->codeAppend ("float2 d1 = float2(qlr.y, -qlr.x);");

    g->codeAppendf("float2 n = float2(%s.y - %s.y, %s.x - %s.x);",
                   rightPt, leftPt, leftPt, rightPt);
    g->codeAppendf("float2 kk = n * float2x2(%s + bloat * d1, %s - bloat * d1);",
                   leftPt, leftPt);
    // Clamp for when n=0. wind=0 when n=0 so as long as we don't get Inf or NaN we are fine.
    g->codeAppendf("float scale = 1 / max(kk[0] - kk[1], 1e-30);");

    g->codeAppendf("%s = half3(-n, kk[1]) * scale;", outputDistanceEquation);
}

int PrimitiveProcessor::emitCornerGeometry(GrGLSLGeometryBuilder* g, const char* emitVertexFn,
                                           const char* pt) const {
    g->codeAppendf("%s(%s + float2(-bloat.x, -bloat.y), 1);", emitVertexFn, pt);
    g->codeAppendf("%s(%s + float2(-bloat.x, +bloat.y), 1);", emitVertexFn, pt);
    g->codeAppendf("%s(%s + float2(+bloat.x, -bloat.y), 1);", emitVertexFn, pt);
    g->codeAppendf("%s(%s + float2(+bloat.x, +bloat.y), 1);", emitVertexFn, pt);
    g->codeAppend ("EndPrimitive();");

    return 4;
}

void PrimitiveProcessor::emitCoverage(const GrCCPRCoverageProcessor& proc, GrGLSLFragmentBuilder* f,
                                      const char* outputColor, const char* outputCoverage) const {
    switch (fCoverageType) {
        case CoverageType::kOne:
            f->codeAppendf("%s.a = %s;", outputColor, fFragWind.fsIn());
            break;
        case CoverageType::kInterpolated:
            f->codeAppendf("%s.a = %s;", outputColor, fFragCoverageTimesWind.fsIn());
            break;
        case CoverageType::kShader:
            f->codeAppendf("half coverage = 0;");
            this->emitShaderCoverage(f, "coverage");
            f->codeAppendf("%s.a = coverage * %s;", outputColor, fFragWind.fsIn());
            break;
    }

    f->codeAppendf("%s = half4(1);", outputCoverage);

#ifdef SK_DEBUG
    if (proc.debugVisualizationsEnabled()) {
        f->codeAppendf("%s = half4(-%s.a, %s.a, 0, 1);", outputColor, outputColor, outputColor);
    }
#endif
}

int PrimitiveProcessor::defineSoftSampleLocations(GrGLSLFragmentBuilder* f,
                                                  const char* samplesName) const {
    // Standard DX11 sample locations.
#if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
    f->defineConstant("float2[8]", samplesName, "float2[8]("
        "float2(+1, -3)/16, float2(-1, +3)/16, float2(+5, +1)/16, float2(-3, -5)/16, "
        "float2(-5, +5)/16, float2(-7, -1)/16, float2(+3, +7)/16, float2(+7, -7)/16."
    ")");
    return 8;
#else
    f->defineConstant("float2[16]", samplesName, "float2[16]("
        "float2(+1, +1)/16, float2(-1, -3)/16, float2(-3, +2)/16, float2(+4, -1)/16, "
        "float2(-5, -2)/16, float2(+2, +5)/16, float2(+5, +3)/16, float2(+3, -5)/16, "
        "float2(-2, +6)/16, float2( 0, -7)/16, float2(-4, -6)/16, float2(-6, +4)/16, "
        "float2(-8,  0)/16, float2(+7, -4)/16, float2(+6, +7)/16, float2(-7, -8)/16."
    ")");
    return 16;
#endif
}

#ifdef SK_DEBUG

#include "GrRenderTarget.h"

void GrCCPRCoverageProcessor::Validate(GrRenderTargetProxy* atlasProxy) {
    SkASSERT(kAtlasOrigin == atlasProxy->origin());
    SkASSERT(GrPixelConfigIsAlphaOnly(atlasProxy->config()));
    SkASSERT(GrPixelConfigIsFloatingPoint(atlasProxy->config()));
}

#endif
