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

#include "src/gpu/ccpr/GrCCConicShader.h"

#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"

void GrCCConicShader::emitSetupCode(
        GrGLSLVertexGeoBuilder* s, const char* pts, const char** outHull4) const {
    // K is distance from the line P2 -> P0. L is distance from the line P0 -> P1, scaled by 2w.
    // M is distance from the line P1 -> P2, scaled by 2w. We do this in a space where P1=0.
    s->declareGlobal(fKLMMatrix);
    s->codeAppendf("float x0 = %s[0].x - %s[1].x, x2 = %s[2].x - %s[1].x;", pts, pts, pts, pts);
    s->codeAppendf("float y0 = %s[0].y - %s[1].y, y2 = %s[2].y - %s[1].y;", pts, pts, pts, pts);
    s->codeAppendf("float w = %s[3].x;", pts);
    s->codeAppendf("%s = float3x3(y2 - y0, x0 - x2, x2*y0 - x0*y2, "
                                 "2*w * float2(+y0, -x0), 0, "
                                 "2*w * float2(-y2, +x2), 0);", fKLMMatrix.c_str());

    s->declareGlobal(fControlPoint);
    s->codeAppendf("%s = %s[1];", fControlPoint.c_str(), pts);

    // Scale KLM by the inverse Manhattan width of K, and make sure K is positive. This allows K to
    // double as the flat opposite edge AA. kwidth will not be 0 because we cull degenerate conics
    // on the CPU.
    s->codeAppendf("float kwidth = 2*bloat * (abs(%s[0].x) + abs(%s[0].y)) * sign(%s[0].z);",
                   fKLMMatrix.c_str(), fKLMMatrix.c_str(), fKLMMatrix.c_str());
    s->codeAppendf("%s *= 1/kwidth;", fKLMMatrix.c_str());

    if (outHull4) {
        // Clip the conic triangle by the tangent line at maximum height. Conics have the nice
        // property that maximum height always occurs at T=.5. This is a simple application for
        // De Casteljau's algorithm.
        s->codeAppendf("float2 p1w = %s[1]*w;", pts);
        s->codeAppend ("float r = 1 / (1 + w);");
        s->codeAppend ("float2 conic_hull[4];");
        s->codeAppendf("conic_hull[0] = %s[0];", pts);
        s->codeAppendf("conic_hull[1] = (%s[0] + p1w) * r;", pts);
        s->codeAppendf("conic_hull[2] = (p1w + %s[2]) * r;", pts);
        s->codeAppendf("conic_hull[3] = %s[2];", pts);
        *outHull4 = "conic_hull";
    }
}

void GrCCConicShader::onEmitVaryings(
        GrGLSLVaryingHandler* varyingHandler, GrGLSLVarying::Scope scope, SkString* code,
        const char* position, const char* coverage, const char* cornerCoverage, const char* wind) {
    code->appendf("float3 klm = float3(%s - %s, 1) * %s;",
                  position, fControlPoint.c_str(), fKLMMatrix.c_str());
    if (coverage) {
        fKLM_fWind.reset(kFloat4_GrSLType, scope);
        varyingHandler->addVarying("klm_and_wind", &fKLM_fWind);
        code->appendf("%s.w = %s;", OutName(fKLM_fWind), wind);
    } else {
        fKLM_fWind.reset(kFloat3_GrSLType, scope);
        varyingHandler->addVarying("klm", &fKLM_fWind);
    }
    code->appendf("%s.xyz = klm;", OutName(fKLM_fWind));

    fGrad_fCorner.reset(cornerCoverage ? kFloat4_GrSLType : kFloat2_GrSLType, scope);
    varyingHandler->addVarying((cornerCoverage) ? "grad_and_corner" : "grad", &fGrad_fCorner);
    code->appendf("%s.xy = 2*bloat * (float3x2(%s) * float3(2*klm[0], -klm[2], -klm[1]));",
                  OutName(fGrad_fCorner), fKLMMatrix.c_str());

    if (cornerCoverage) {
        SkASSERT(coverage);
        code->appendf("half hull_coverage;");
        this->calcHullCoverage(code, "klm", OutName(fGrad_fCorner), "hull_coverage");
        code->appendf("%s.zw = half2(hull_coverage, 1) * %s;",
                      OutName(fGrad_fCorner), cornerCoverage);
    }
}

void GrCCConicShader::emitFragmentCoverageCode(
        GrGLSLFPFragmentBuilder* f, const char* outputCoverage) const {
    this->calcHullCoverage(&AccessCodeString(f), fKLM_fWind.fsIn(), fGrad_fCorner.fsIn(),
                           outputCoverage);
    f->codeAppendf("%s *= half(%s.w);", outputCoverage, fKLM_fWind.fsIn());  // Wind.

    if (kFloat4_GrSLType == fGrad_fCorner.type()) {
        f->codeAppendf("%s = fma(half(%s.z), half(%s.w), %s);",  // Attenuated corner coverage.
                       outputCoverage, fGrad_fCorner.fsIn(), fGrad_fCorner.fsIn(),
                       outputCoverage);
    }
}

void GrCCConicShader::calcHullCoverage(SkString* code, const char* klm, const char* grad,
                                       const char* outputCoverage) const {
    code->appendf("float k = %s.x, l = %s.y, m = %s.z;", klm, klm, klm);
    code->append ("float f = k*k - l*m;");
    code->appendf("float fwidth = abs(%s.x) + abs(%s.y);", grad, grad);
    code->appendf("float curve_coverage = min(0.5 - f/fwidth, 1);");
    // K doubles as the flat opposite edge's AA.
    code->append ("float edge_coverage = min(k - 0.5, 0);");
    // Total hull coverage.
    code->appendf("%s = max(half(curve_coverage + edge_coverage), 0);", outputCoverage);
}

void GrCCConicShader::emitSampleMaskCode(GrGLSLFPFragmentBuilder* f) const {
    f->codeAppendf("float k = %s.x, l = %s.y, m = %s.z;",
                   fKLM_fWind.fsIn(), fKLM_fWind.fsIn(), fKLM_fWind.fsIn());
    f->codeAppendf("float f = k*k - l*m;");
    f->codeAppendf("float2 grad = %s;", fGrad_fCorner.fsIn());
    f->applyFnToMultisampleMask("f", "grad", GrGLSLFPFragmentBuilder::ScopeFlags::kTopLevel);
}
