/*
    Copyright 2011 Google Inc.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */

#include "GrGLProgram.h"

#include "GrBinHashKey.h"
#include "GrGLConfig.h"
#include "GrMemory.h"

#include "SkXfermode.h"

namespace {

const char* GrPrecision() {
    if (GR_GL_SUPPORT_ES2) {
        return "mediump";
    } else {
        return " ";
    }
}

const char* GrShaderPrecision() {
    if (GR_GL_SUPPORT_ES2) {
        return "precision mediump float;\n";
    } else {
        return "";
    }
}

}  // namespace

#define PRINT_SHADERS 0

#if GR_GL_ATTRIBUTE_MATRICES
    #define VIEW_MATRIX_NAME "aViewM"
#else
    #define VIEW_MATRIX_NAME "uViewM"
#endif

#define POS_ATTR_NAME "aPosition"
#define COL_ATTR_NAME "aColor"
#define COL_UNI_NAME "uColor"
#define EDGES_UNI_NAME "uEdges"
#define COL_FILTER_UNI_NAME "uColorFilter"

static inline void tex_attr_name(int coordIdx, GrStringBuilder* s) {
    *s = "aTexCoord";
    s->appendS32(coordIdx);
}

static inline const char* float_vector_type(int count) {
    static const char* FLOAT_VECS[] = {"ERROR", "float", "vec2", "vec3", "vec4"};
    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(FLOAT_VECS));
    return FLOAT_VECS[count];
}

static inline const char* vector_homog_coord(int count) {
    static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS));
    return HOMOGS[count];
}

static inline const char* vector_nonhomog_coords(int count) {
    static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
    return NONHOMOGS[count];
}

static inline const char* vector_all_coords(int count) {
    static const char* ALL[] = {"ERROR", "", ".xy", ".xyz", ".xyzw"};
    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ALL));
    return ALL[count];
}

static inline const char* all_ones_vec(int count) {
    static const char* ONESVEC[] = {"ERROR", "1.0", "vec2(1,1)",
                                    "vec3(1,1,1)", "vec4(1,1,1,1)"};
    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ONESVEC));
    return ONESVEC[count];
}

static inline const char* all_zeros_vec(int count) {
    static const char* ZEROSVEC[] = {"ERROR", "0.0", "vec2(0,0)",
                                    "vec3(0,0,0)", "vec4(0,0,0,0)"};
    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ZEROSVEC));
    return ZEROSVEC[count];
}

static inline const char* declared_color_output_name() { return "fsColorOut"; }
static inline const char* dual_source_output_name() { return "dualSourceOut"; }

static void tex_matrix_name(int stage, GrStringBuilder* s) {
#if GR_GL_ATTRIBUTE_MATRICES
    *s = "aTexM";
#else
    *s = "uTexM";
#endif
    s->appendS32(stage);
}

static void normalized_texel_size_name(int stage, GrStringBuilder* s) {
    *s = "uTexelSize";
    s->appendS32(stage);
}

static void sampler_name(int stage, GrStringBuilder* s) {
    *s = "uSampler";
    s->appendS32(stage);
}

static void stage_varying_name(int stage, GrStringBuilder* s) {
    *s = "vStage";
    s->appendS32(stage);
}

static void radial2_param_name(int stage, GrStringBuilder* s) {
    *s = "uRadial2Params";
    s->appendS32(stage);
}

static void radial2_varying_name(int stage, GrStringBuilder* s) {
    *s = "vB";
    s->appendS32(stage);
}

static void tex_domain_name(int stage, GrStringBuilder* s) {
    *s = "uTexDom";
    s->appendS32(stage);
}

GrGLProgram::GrGLProgram() {
}

GrGLProgram::~GrGLProgram() {
}

void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff,
                                GrBlendCoeff* dstCoeff) const {
    switch (fProgramDesc.fDualSrcOutput) {
        case ProgramDesc::kNone_DualSrcOutput:
            break;
        // the prog will write a coverage value to the secondary
        // output and the dst is blended by one minus that value.
        case ProgramDesc::kCoverage_DualSrcOutput:
        case ProgramDesc::kCoverageISA_DualSrcOutput:
        case ProgramDesc::kCoverageISC_DualSrcOutput:
        *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_BlendCoeff;
        break;
        default:
            GrCrash("Unexpected dual source blend output");
            break;
    }
}

void GrGLProgram::buildKey(GrBinHashKeyBuilder& key) const {
    // Add stage configuration to the key
    key.keyData(reinterpret_cast<const uint32_t*>(&fProgramDesc), sizeof(ProgramDesc));
}

// assigns modulation of two vars to an output var
// vars can be vec4s or floats (or one of each)
// result is always vec4
// if either var is "" then assign to the other var
// if both are "" then assign all ones
static inline void modulate_helper(const char* outputVar,
                                   const char* var0,
                                   const char* var1,
                                   GrStringBuilder* code) {
    GrAssert(NULL != outputVar);
    GrAssert(NULL != var0);
    GrAssert(NULL != var1);
    GrAssert(NULL != code);

    bool has0 = '\0' != *var0;
    bool has1 = '\0' != *var1;

    if (!has0 && !has1) {
        code->appendf("\t%s = %s;\n", outputVar, all_ones_vec(4));
    } else if (!has0) {
        code->appendf("\t%s = vec4(%s);\n", outputVar, var1);
    } else if (!has1) {
        code->appendf("\t%s = vec4(%s);\n", outputVar, var0);
    } else {
        code->appendf("\t%s = vec4(%s * %s);\n", outputVar, var0, var1);
    }
}

// assigns addition of two vars to an output var
// vars can be vec4s or floats (or one of each)
// result is always vec4
// if either var is "" then assign to the other var
// if both are "" then assign all zeros
static inline void add_helper(const char* outputVar,
                              const char* var0,
                              const char* var1,
                              GrStringBuilder* code) {
    GrAssert(NULL != outputVar);
    GrAssert(NULL != var0);
    GrAssert(NULL != var1);
    GrAssert(NULL != code);

    bool has0 = '\0' != *var0;
    bool has1 = '\0' != *var1;

    if (!has0 && !has1) {
        code->appendf("\t%s = %s;\n", outputVar, all_zeros_vec(4));
    } else if (!has0) {
        code->appendf("\t%s = vec4(%s);\n", outputVar, var1);
    } else if (!has1) {
        code->appendf("\t%s = vec4(%s);\n", outputVar, var0);
    } else {
        code->appendf("\t%s = vec4(%s + %s);\n", outputVar, var0, var1);
    }
}

// given two blend coeffecients determine whether the src
// and/or dst computation can be omitted.
static inline void needBlendInputs(SkXfermode::Coeff srcCoeff,
                                   SkXfermode::Coeff dstCoeff,
                                   bool* needSrcValue,
                                   bool* needDstValue) {
    if (SkXfermode::kZero_Coeff == srcCoeff) {
        switch (dstCoeff) {
            // these all read the src
            case SkXfermode::kSC_Coeff:
            case SkXfermode::kISC_Coeff:
            case SkXfermode::kSA_Coeff:
            case SkXfermode::kISA_Coeff:
                *needSrcValue = true;
                break;
            default:
                *needSrcValue = false;
                break;
        }
    } else {
        *needSrcValue = true;
    }
    if (SkXfermode::kZero_Coeff == dstCoeff) {
        switch (srcCoeff) {
            // these all read the dst
            case SkXfermode::kDC_Coeff:
            case SkXfermode::kIDC_Coeff:
            case SkXfermode::kDA_Coeff:
            case SkXfermode::kIDA_Coeff:
                *needDstValue = true;
                break;
            default:
                *needDstValue = false;
                break;
        }
    } else {
        *needDstValue = true;
    }
}

/**
 * Create a blend_coeff * value string to be used in shader code. Sets empty
 * string if result is trivially zero.
 */
static void blendTermString(GrStringBuilder* str, SkXfermode::Coeff coeff,
                             const char* src, const char* dst,
                             const char* value) {
    switch (coeff) {
    case SkXfermode::kZero_Coeff:    /** 0 */
        *str = "";
        break;
    case SkXfermode::kOne_Coeff:     /** 1 */
        *str = value;
        break;
    case SkXfermode::kSC_Coeff:
        str->printf("(%s * %s)", src, value);
        break;
    case SkXfermode::kISC_Coeff:
        str->printf("((%s - %s) * %s)", all_ones_vec(4), src, value);
        break;
    case SkXfermode::kDC_Coeff:
        str->printf("(%s * %s)", dst, value);
        break;
    case SkXfermode::kIDC_Coeff:
        str->printf("((%s - %s) * %s)", all_ones_vec(4), dst, value);
        break;
    case SkXfermode::kSA_Coeff:      /** src alpha */
        str->printf("(%s.a * %s)", src, value);
        break;
    case SkXfermode::kISA_Coeff:     /** inverse src alpha (i.e. 1 - sa) */
        str->printf("((1.0 - %s.a) * %s)", src, value);
        break;
    case SkXfermode::kDA_Coeff:      /** dst alpha */
        str->printf("(%s.a * %s)", dst, value);
        break;
    case SkXfermode::kIDA_Coeff:     /** inverse dst alpha (i.e. 1 - da) */
        str->printf("((1.0 - %s.a) * %s)", dst, value);
        break;
    default:
        GrCrash("Unexpected xfer coeff.");
        break;
    }
}
/**
 * Adds a line to the fragment shader code which modifies the color by
 * the specified color filter.
 */
static void addColorFilter(GrStringBuilder* fsCode, const char * outputVar,
                           SkXfermode::Coeff uniformCoeff,
                           SkXfermode::Coeff colorCoeff,
                           const char* inColor) {
    GrStringBuilder colorStr, constStr;
    blendTermString(&colorStr, colorCoeff, COL_FILTER_UNI_NAME,
                    inColor, inColor);
    blendTermString(&constStr, uniformCoeff, COL_FILTER_UNI_NAME,
                    inColor, COL_FILTER_UNI_NAME);

    add_helper(outputVar, colorStr.c_str(), constStr.c_str(), fsCode);
}

bool GrGLProgram::genProgram(GrGLProgram::CachedData* programData) const {

    ShaderCodeSegments segments;
    const uint32_t& layout = fProgramDesc.fVertexLayout;

    programData->fUniLocations.reset();

    SkXfermode::Coeff colorCoeff, uniformCoeff;
    // The rest of transfer mode color filters have not been implemented
    if (fProgramDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) {
        GR_DEBUGCODE(bool success =)
            SkXfermode::ModeAsCoeff(static_cast<SkXfermode::Mode>
                                    (fProgramDesc.fColorFilterXfermode),
                                    &uniformCoeff, &colorCoeff);
        GR_DEBUGASSERT(success);
    } else {
        colorCoeff = SkXfermode::kOne_Coeff;
        uniformCoeff = SkXfermode::kZero_Coeff;
    }

    bool needColorFilterUniform;
    bool needComputedColor;
    needBlendInputs(uniformCoeff, colorCoeff,
                    &needColorFilterUniform, &needComputedColor);

    // the dual source output has no canonical var name, have to
    // declare an output, which is incompatible with gl_FragColor/gl_FragData.
    const char* fsColorOutput;
    bool dualSourceOutputWritten = false;
    bool usingDeclaredOutputs = ProgramDesc::kNone_DualSrcOutput !=
                                fProgramDesc.fDualSrcOutput;
    if (usingDeclaredOutputs) {
        GrAssert(0 == segments.fHeader.size());
        segments.fHeader.printf("#version 150\n");
        fsColorOutput = declared_color_output_name();
        segments.fFSOutputs.appendf("out vec4 %s;\n", fsColorOutput);
    } else {
        fsColorOutput = "gl_FragColor";
    }

#if GR_GL_ATTRIBUTE_MATRICES
    segments.fVSAttrs += "attribute mat3 " VIEW_MATRIX_NAME ";\n";
    programData->fUniLocations.fViewMatrixUni = kSetAsAttribute;
#else
    segments.fVSUnis  += "uniform mat3 " VIEW_MATRIX_NAME ";\n";
    programData->fUniLocations.fViewMatrixUni = kUseUniform;
#endif
    segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n";

    segments.fVSCode.append(
        "void main() {\n"
            "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3("POS_ATTR_NAME", 1);\n"
            "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n");

    // incoming color to current stage being processed.
    GrStringBuilder inColor;

    if (needComputedColor) {
        switch (fProgramDesc.fColorType) {
            case ProgramDesc::kAttribute_ColorType:
                segments.fVSAttrs.append( "attribute vec4 " COL_ATTR_NAME ";\n");
                segments.fVaryings.append("varying vec4 vColor;\n");
                segments.fVSCode.append(    "\tvColor = " COL_ATTR_NAME ";\n");
                inColor = "vColor";
                break;
            case ProgramDesc::kUniform_ColorType:
                segments.fFSUnis.append(  "uniform vec4 " COL_UNI_NAME ";\n");
                programData->fUniLocations.fColorUni = kUseUniform;
                inColor = COL_UNI_NAME;
                break;
            default:
                GrAssert(ProgramDesc::kNone_ColorType == fProgramDesc.fColorType);
                break;
        }
    }

    if (fProgramDesc.fEmitsPointSize){
        segments.fVSCode.append("\tgl_PointSize = 1.0;\n");
    }

    segments.fFSCode.append("void main() {\n");

    // add texture coordinates that are used to the list of vertex attr decls
    GrStringBuilder texCoordAttrs[GrDrawTarget::kMaxTexCoords];
    for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
        if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
            tex_attr_name(t, texCoordAttrs + t);
            segments.fVSAttrs.appendf("attribute vec2 %s;\n", texCoordAttrs[t].c_str());
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // compute the final color

    // if we have color stages string them together, feeding the output color
    // of each to the next and generating code for each stage.
    if (needComputedColor) {
        GrStringBuilder outColor;
        for (int s = 0; s < fProgramDesc.fFirstCoverageStage; ++s) {
            if (fProgramDesc.fStages[s].isEnabled()) {
                // create var to hold stage result
                outColor = "color";
                outColor.appendS32(s);
                segments.fFSCode.appendf("\tvec4 %s;\n", outColor.c_str());

                const char* inCoords;
                // figure out what our input coords are
                if (GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s) &
                    layout) {
                    inCoords = POS_ATTR_NAME;
                } else {
                    int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout);
                     // we better have input tex coordinates if stage is enabled.
                    GrAssert(tcIdx >= 0);
                    GrAssert(texCoordAttrs[tcIdx].size());
                    inCoords = texCoordAttrs[tcIdx].c_str();
                }

                genStageCode(s,
                             fProgramDesc.fStages[s],
                             inColor.size() ? inColor.c_str() : NULL,
                             outColor.c_str(),
                             inCoords,
                             &segments,
                             &programData->fUniLocations.fStages[s]);
                inColor = outColor;
            }
        }
    }

    // if have all ones for the "dst" input to the color filter then we can make
    // additional optimizations.
    if (needColorFilterUniform && !inColor.size() &&
        (SkXfermode::kIDC_Coeff == uniformCoeff ||
         SkXfermode::kIDA_Coeff == uniformCoeff)) {
          uniformCoeff = SkXfermode::kZero_Coeff;
          bool bogus;
          needBlendInputs(SkXfermode::kZero_Coeff, colorCoeff,
                          &needColorFilterUniform, &bogus);
    }
    if (needColorFilterUniform) {
        segments.fFSUnis.append(  "uniform vec4 " COL_FILTER_UNI_NAME ";\n");
        programData->fUniLocations.fColorFilterUni = kUseUniform;
    }

    bool wroteFragColorZero = false;
    if (SkXfermode::kZero_Coeff == uniformCoeff &&
        SkXfermode::kZero_Coeff == colorCoeff) {
        segments.fFSCode.appendf("\t%s = %s;\n",
                                 fsColorOutput,
                                 all_zeros_vec(4));
        wroteFragColorZero = true;
    } else if (SkXfermode::kDst_Mode != fProgramDesc.fColorFilterXfermode) {
        segments.fFSCode.appendf("\tvec4 filteredColor;\n");
        const char* color = inColor.size() ? inColor.c_str() : all_ones_vec(4);
        addColorFilter(&segments.fFSCode, "filteredColor", uniformCoeff,
                       colorCoeff, color);
        inColor = "filteredColor";
    }

    ///////////////////////////////////////////////////////////////////////////
    // compute the partial coverage (coverage stages and edge aa)

    GrStringBuilder inCoverage;

    // we don't need to compute coverage at all if we know the final shader
    // output will be zero and we don't have a dual src blend output.
    if (!wroteFragColorZero ||
        ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) {
        if (fProgramDesc.fEdgeAANumEdges > 0) {
            segments.fFSUnis.append("uniform vec3 " EDGES_UNI_NAME "[");
            segments.fFSUnis.appendS32(fProgramDesc.fEdgeAANumEdges);
            segments.fFSUnis.append("];\n");
            programData->fUniLocations.fEdgesUni = kUseUniform;
            int count = fProgramDesc.fEdgeAANumEdges;
            segments.fFSCode.append(
                "\tvec3 pos = vec3(gl_FragCoord.xy, 1);\n");
            for (int i = 0; i < count; i++) {
                segments.fFSCode.append("\tfloat a");
                segments.fFSCode.appendS32(i);
                segments.fFSCode.append(" = clamp(dot(" EDGES_UNI_NAME "[");
                segments.fFSCode.appendS32(i);
                segments.fFSCode.append("], pos), 0.0, 1.0);\n");
            }
            segments.fFSCode.append("\tfloat edgeAlpha = ");
            for (int i = 0; i < count - 1; i++) {
                segments.fFSCode.append("min(a");
                segments.fFSCode.appendS32(i);
                segments.fFSCode.append(" * a");
                segments.fFSCode.appendS32(i + 1);
                segments.fFSCode.append(", ");
            }
            segments.fFSCode.append("a");
            segments.fFSCode.appendS32(count - 1);
            segments.fFSCode.append(" * a0");
            for (int i = 0; i < count - 1; i++) {
                segments.fFSCode.append(")");
            }
            segments.fFSCode.append(";\n");
            inCoverage = "edgeAlpha";
        }

        GrStringBuilder outCoverage;
        const int& startStage = fProgramDesc.fFirstCoverageStage;
        for (int s = startStage; s < GrDrawTarget::kNumStages; ++s) {
            if (fProgramDesc.fStages[s].isEnabled()) {
                // create var to hold stage output
                outCoverage = "coverage";
                outCoverage.appendS32(s);
                segments.fFSCode.appendf("\tvec4 %s;\n", outCoverage.c_str());

                const char* inCoords;
                // figure out what our input coords are
                if (GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s) & layout) {
                    inCoords = POS_ATTR_NAME;
                } else {
                    int tcIdx = GrDrawTarget::VertexTexCoordsForStage(s, layout);
                        // we better have input tex coordinates if stage is enabled.
                    GrAssert(tcIdx >= 0);
                    GrAssert(texCoordAttrs[tcIdx].size());
                    inCoords = texCoordAttrs[tcIdx].c_str();
                }

                genStageCode(s,
                             fProgramDesc.fStages[s],
                             inCoverage.size() ? inCoverage.c_str() : NULL,
                             outCoverage.c_str(),
                             inCoords,
                             &segments,
                             &programData->fUniLocations.fStages[s]);
                inCoverage = outCoverage;
            }
        }
        if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) {
            segments.fFSOutputs.appendf("out vec4 %s;\n",
                                        dual_source_output_name());
            bool outputIsZero = false;
            GrStringBuilder coeff;
            if (ProgramDesc::kCoverage_DualSrcOutput !=
                fProgramDesc.fDualSrcOutput && !wroteFragColorZero) {
                if (!inColor.size()) {
                    outputIsZero = true;
                } else {
                    if (fProgramDesc.fDualSrcOutput ==
                        ProgramDesc::kCoverageISA_DualSrcOutput) {
                        coeff.printf("(1 - %s.a)", inColor.c_str());
                    } else {
                        coeff.printf("(vec4(1,1,1,1) - %s)", inColor.c_str());
                    }
                }
            }
            if (outputIsZero) {
                segments.fFSCode.appendf("\t%s = %s;\n",
                                         dual_source_output_name(),
                                         all_zeros_vec(4));
            } else {
                modulate_helper(dual_source_output_name(),
                                coeff.c_str(),
                                inCoverage.c_str(),
                                &segments.fFSCode);
            }
            dualSourceOutputWritten = true;
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    // combine color and coverage as frag color

    if (!wroteFragColorZero) {
        modulate_helper(fsColorOutput,
                         inColor.c_str(),
                         inCoverage.c_str(),
                         &segments.fFSCode);
    }

    segments.fVSCode.append("}\n");
    segments.fFSCode.append("}\n");

    ///////////////////////////////////////////////////////////////////////////
    // compile and setup attribs and unis

    if (!CompileFSAndVS(segments, programData)) {
        return false;
    }

    if (!this->bindOutputsAttribsAndLinkProgram(texCoordAttrs,
                                                usingDeclaredOutputs,
                                                dualSourceOutputWritten,
                                                programData)) {
        return false;
    }

    this->getUniformLocationsAndInitCache(programData);

    return true;
}

bool GrGLProgram::CompileFSAndVS(const ShaderCodeSegments& segments,
                                 CachedData* programData) {

    static const int MAX_STRINGS = 6;
    const char* strings[MAX_STRINGS];
    int lengths[MAX_STRINGS];
    int stringCnt = 0;

    if (segments.fHeader.size()) {
        strings[stringCnt] = segments.fHeader.c_str();
        lengths[stringCnt] = segments.fHeader.size();
        ++stringCnt;
    }
    if (segments.fVSUnis.size()) {
        strings[stringCnt] = segments.fVSUnis.c_str();
        lengths[stringCnt] = segments.fVSUnis.size();
        ++stringCnt;
    }
    if (segments.fVSAttrs.size()) {
        strings[stringCnt] = segments.fVSAttrs.c_str();
        lengths[stringCnt] = segments.fVSAttrs.size();
        ++stringCnt;
    }
    if (segments.fVaryings.size()) {
        strings[stringCnt] = segments.fVaryings.c_str();
        lengths[stringCnt] = segments.fVaryings.size();
        ++stringCnt;
    }

    GrAssert(segments.fVSCode.size());
    strings[stringCnt] = segments.fVSCode.c_str();
    lengths[stringCnt] = segments.fVSCode.size();
    ++stringCnt;

#if PRINT_SHADERS
    GrPrintf(segments.fHeader.c_str());
    GrPrintf(segments.fVSUnis.c_str());
    GrPrintf(segments.fVSAttrs.c_str());
    GrPrintf(segments.fVaryings.c_str());
    GrPrintf(segments.fVSCode.c_str());
    GrPrintf("\n");
#endif
    GrAssert(stringCnt <= MAX_STRINGS);
    programData->fVShaderID = CompileShader(GR_GL_VERTEX_SHADER,
                                        stringCnt,
                                        strings,
                                        lengths);

    if (!programData->fVShaderID) {
        return false;
    }

    stringCnt = 0;

    if (segments.fHeader.size()) {
        strings[stringCnt] = segments.fHeader.c_str();
        lengths[stringCnt] = segments.fHeader.size();
        ++stringCnt;
    }
    if (strlen(GrShaderPrecision()) > 1) {
        strings[stringCnt] = GrShaderPrecision();
        lengths[stringCnt] = strlen(GrShaderPrecision());
        ++stringCnt;
    }
    if (segments.fFSUnis.size()) {
        strings[stringCnt] = segments.fFSUnis.c_str();
        lengths[stringCnt] = segments.fFSUnis.size();
        ++stringCnt;
    }
    if (segments.fVaryings.size()) {
        strings[stringCnt] = segments.fVaryings.c_str();
        lengths[stringCnt] = segments.fVaryings.size();
        ++stringCnt;
    }
    if (segments.fFSOutputs.size()) {
        strings[stringCnt] = segments.fFSOutputs.c_str();
        lengths[stringCnt] = segments.fFSOutputs.size();
        ++stringCnt;
    }

    GrAssert(segments.fFSCode.size());
    strings[stringCnt] = segments.fFSCode.c_str();
    lengths[stringCnt] = segments.fFSCode.size();
    ++stringCnt;

#if PRINT_SHADERS
    GrPrintf(segments.fHeader.c_str());
    GrPrintf(GrShaderPrecision());
    GrPrintf(segments.fFSUnis.c_str());
    GrPrintf(segments.fVaryings.c_str());
    GrPrintf(segments.fFSOutputs.c_str());
    GrPrintf(segments.fFSCode.c_str());
    GrPrintf("\n");
#endif
    GrAssert(stringCnt <= MAX_STRINGS);
    programData->fFShaderID = CompileShader(GR_GL_FRAGMENT_SHADER,
                                            stringCnt,
                                            strings,
                                            lengths);

    if (!programData->fFShaderID) {
        return false;
    }

    return true;
}

GrGLuint GrGLProgram::CompileShader(GrGLenum type,
                                      int stringCnt,
                                      const char** strings,
                                      int* stringLengths) {
    GrGLuint shader = GR_GL(CreateShader(type));
    if (0 == shader) {
        return 0;
    }

    GrGLint compiled = GR_GL_INIT_ZERO;
    GR_GL(ShaderSource(shader, stringCnt, strings, stringLengths));
    GR_GL(CompileShader(shader));
    GR_GL(GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled));

    if (!compiled) {
        GrGLint infoLen = GR_GL_INIT_ZERO;
        GR_GL(GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen));
        GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
        if (infoLen > 0) {
            GR_GL(GetShaderInfoLog(shader, infoLen+1, NULL, (char*)log.get()));
            for (int i = 0; i < stringCnt; ++i) {
                if (NULL == stringLengths || stringLengths[i] < 0) {
                    GrPrintf(strings[i]);
                } else {
                    GrPrintf("%.*s", stringLengths[i], strings[i]);
                }
            }
            GrPrintf("\n%s", log.get());
        }
        GrAssert(!"Shader compilation failed!");
        GR_GL(DeleteShader(shader));
        return 0;
    }
    return shader;
}

bool GrGLProgram::bindOutputsAttribsAndLinkProgram(
                                        GrStringBuilder texCoordAttrNames[],
                                        bool bindColorOut,
                                        bool bindDualSrcOut,
                                        CachedData* programData) const {
    programData->fProgramID = GR_GL(CreateProgram());
    if (!programData->fProgramID) {
        return false;
    }
    const GrGLint& progID = programData->fProgramID;

    GR_GL(AttachShader(progID, programData->fVShaderID));
    GR_GL(AttachShader(progID, programData->fFShaderID));

    if (bindColorOut) {
        GR_GL(BindFragDataLocationIndexed(programData->fProgramID,
                                          0, 0, declared_color_output_name()));
    }
    if (bindDualSrcOut) {
        GR_GL(BindFragDataLocationIndexed(programData->fProgramID,
                                          0, 1, dual_source_output_name()));
    }

    // Bind the attrib locations to same values for all shaders
    GR_GL(BindAttribLocation(progID, PositionAttributeIdx(), POS_ATTR_NAME));
    for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
        if (texCoordAttrNames[t].size()) {
            GR_GL(BindAttribLocation(progID,
                                     TexCoordAttributeIdx(t),
                                     texCoordAttrNames[t].c_str()));
        }
    }

    if (kSetAsAttribute == programData->fUniLocations.fViewMatrixUni) {
        GR_GL(BindAttribLocation(progID,
                             ViewMatrixAttributeIdx(),
                             VIEW_MATRIX_NAME));
    }

    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
        const StageUniLocations& unis = programData->fUniLocations.fStages[s];
        if (kSetAsAttribute == unis.fTextureMatrixUni) {
            GrStringBuilder matName;
            tex_matrix_name(s, &matName);
            GR_GL(BindAttribLocation(progID,
                                     TextureMatrixAttributeIdx(s),
                                     matName.c_str()));
        }
    }

    GR_GL(BindAttribLocation(progID, ColorAttributeIdx(), COL_ATTR_NAME));

    GR_GL(LinkProgram(progID));

    GrGLint linked = GR_GL_INIT_ZERO;
    GR_GL(GetProgramiv(progID, GR_GL_LINK_STATUS, &linked));
    if (!linked) {
        GrGLint infoLen = GR_GL_INIT_ZERO;
        GR_GL(GetProgramiv(progID, GR_GL_INFO_LOG_LENGTH, &infoLen));
        GrAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
        if (infoLen > 0) {
            GR_GL(GetProgramInfoLog(progID,
                                    infoLen+1,
                                    NULL,
                                    (char*)log.get()));
            GrPrintf((char*)log.get());
        }
        GrAssert(!"Error linking program");
        GR_GL(DeleteProgram(progID));
        programData->fProgramID = 0;
        return false;
    }
    return true;
}

void GrGLProgram::getUniformLocationsAndInitCache(CachedData* programData) const {
    const GrGLint& progID = programData->fProgramID;

    if (kUseUniform == programData->fUniLocations.fViewMatrixUni) {
        programData->fUniLocations.fViewMatrixUni =
                        GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME));
        GrAssert(kUnusedUniform != programData->fUniLocations.fViewMatrixUni);
    }
    if (kUseUniform == programData->fUniLocations.fColorUni) {
        programData->fUniLocations.fColorUni =
                                GR_GL(GetUniformLocation(progID, COL_UNI_NAME));
        GrAssert(kUnusedUniform != programData->fUniLocations.fColorUni);
    }
    if (kUseUniform == programData->fUniLocations.fColorFilterUni) {
        programData->fUniLocations.fColorFilterUni =
                        GR_GL(GetUniformLocation(progID, COL_FILTER_UNI_NAME));
        GrAssert(kUnusedUniform != programData->fUniLocations.fColorFilterUni);
    }

    if (kUseUniform == programData->fUniLocations.fEdgesUni) {
        programData->fUniLocations.fEdgesUni =
            GR_GL(GetUniformLocation(progID, EDGES_UNI_NAME));
        GrAssert(kUnusedUniform != programData->fUniLocations.fEdgesUni);
    } else {
        programData->fUniLocations.fEdgesUni = kUnusedUniform;
    }

    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
        StageUniLocations& locations = programData->fUniLocations.fStages[s];
        if (fProgramDesc.fStages[s].isEnabled()) {
            if (kUseUniform == locations.fTextureMatrixUni) {
                GrStringBuilder texMName;
                tex_matrix_name(s, &texMName);
                locations.fTextureMatrixUni = GR_GL(GetUniformLocation(
                                                progID,
                                                texMName.c_str()));
                GrAssert(kUnusedUniform != locations.fTextureMatrixUni);
            }

            if (kUseUniform == locations.fSamplerUni) {
                GrStringBuilder samplerName;
                sampler_name(s, &samplerName);
                locations.fSamplerUni = GR_GL(GetUniformLocation(
                                                     progID,
                                                     samplerName.c_str()));
                GrAssert(kUnusedUniform != locations.fSamplerUni);
            }

            if (kUseUniform == locations.fNormalizedTexelSizeUni) {
                GrStringBuilder texelSizeName;
                normalized_texel_size_name(s, &texelSizeName);
                locations.fNormalizedTexelSizeUni =
                   GR_GL(GetUniformLocation(progID, texelSizeName.c_str()));
                GrAssert(kUnusedUniform != locations.fNormalizedTexelSizeUni);
            }

            if (kUseUniform == locations.fRadial2Uni) {
                GrStringBuilder radial2ParamName;
                radial2_param_name(s, &radial2ParamName);
                locations.fRadial2Uni = GR_GL(GetUniformLocation(
                                             progID,
                                             radial2ParamName.c_str()));
                GrAssert(kUnusedUniform != locations.fRadial2Uni);
            }

            if (kUseUniform == locations.fTexDomUni) {
                GrStringBuilder texDomName;
                tex_domain_name(s, &texDomName);
                locations.fTexDomUni = GR_GL(GetUniformLocation(
                                             progID,
                                             texDomName.c_str()));
                GrAssert(kUnusedUniform != locations.fTexDomUni);
            }
        }
    }
    GR_GL(UseProgram(progID));

    // init sampler unis and set bogus values for state tracking
    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
        if (kUnusedUniform != programData->fUniLocations.fStages[s].fSamplerUni) {
            GR_GL(Uniform1i(programData->fUniLocations.fStages[s].fSamplerUni, s));
        }
        programData->fTextureMatrices[s] = GrMatrix::InvalidMatrix();
        programData->fRadial2CenterX1[s] = GR_ScalarMax;
        programData->fRadial2Radius0[s] = -GR_ScalarMax;
        programData->fTextureWidth[s] = -1;
        programData->fTextureHeight[s] = -1;
    }
    programData->fViewMatrix = GrMatrix::InvalidMatrix();
    programData->fColor = GrColor_ILLEGAL;
    programData->fColorFilterColor = GrColor_ILLEGAL;
}

//============================================================================
// Stage code generation
//============================================================================

void GrGLProgram::genStageCode(int stageNum,
                               const GrGLProgram::ProgramDesc::StageDesc& desc,
                               const char* fsInColor, // NULL means no incoming color
                               const char* fsOutColor,
                               const char* vsInCoord,
                               ShaderCodeSegments* segments,
                               StageUniLocations* locations) const {

    GrAssert(stageNum >= 0 && stageNum <= 9);

    GrStringBuilder varyingName;
    stage_varying_name(stageNum, &varyingName);

    // First decide how many coords are needed to access the texture
    // Right now it's always 2 but we could start using 1D textures for
    // gradients.
    static const int coordDims = 2;
    int varyingDims;
    /// Vertex Shader Stuff

    // decide whether we need a matrix to transform texture coords
    // and whether the varying needs a perspective coord.
    GrStringBuilder texMName;
    tex_matrix_name(stageNum, &texMName);
    if (desc.fOptFlags & ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit) {
        varyingDims = coordDims;
    } else {
    #if GR_GL_ATTRIBUTE_MATRICES
        segments->fVSAttrs.appendf("attribute mat3 %s;\n", texMName.c_str());
        locations->fTextureMatrixUni = kSetAsAttribute;
    #else
        segments->fVSUnis.appendf("uniform mat3 %s;\n", texMName.c_str());
        locations->fTextureMatrixUni = kUseUniform;
    #endif
        if (desc.fOptFlags & ProgramDesc::StageDesc::kNoPerspective_OptFlagBit) {
            varyingDims = coordDims;
        } else {
            varyingDims = coordDims + 1;
        }
    }

    GrStringBuilder samplerName;
    sampler_name(stageNum, &samplerName);
    segments->fFSUnis.appendf("uniform sampler2D %s;\n", samplerName.c_str());
    locations->fSamplerUni = kUseUniform;

    GrStringBuilder texelSizeName;
    if (ProgramDesc::StageDesc::k2x2_FetchMode == desc.fFetchMode) {
        normalized_texel_size_name(stageNum, &texelSizeName);
        segments->fFSUnis.appendf("uniform vec2 %s;\n", texelSizeName.c_str());
    }

    segments->fVaryings.appendf("varying %s %s;\n",
                                float_vector_type(varyingDims), varyingName.c_str());

    if (desc.fOptFlags & ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit) {
        GrAssert(varyingDims == coordDims);
        segments->fVSCode.appendf("\t%s = %s;\n", varyingName.c_str(), vsInCoord);
    } else {
        // varying = texMatrix * texCoord
        segments->fVSCode.appendf("\t%s = (%s * vec3(%s, 1))%s;\n",
                                  varyingName.c_str(), texMName.c_str(),
                                  vsInCoord, vector_all_coords(varyingDims));
    }

    GrStringBuilder radial2ParamsName;
    radial2_param_name(stageNum, &radial2ParamsName);
    // for radial grads without perspective we can pass the linear
    // part of the quadratic as a varying.
    GrStringBuilder radial2VaryingName;
    radial2_varying_name(stageNum, &radial2VaryingName);

    if (ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping) {

        segments->fVSUnis.appendf("uniform %s float %s[6];\n",
                                  GrPrecision(), radial2ParamsName.c_str());
        segments->fFSUnis.appendf("uniform float %s[6];\n",
                                  radial2ParamsName.c_str());
        locations->fRadial2Uni = kUseUniform;

        // if there is perspective we don't interpolate this
        if (varyingDims == coordDims) {
            GrAssert(2 == coordDims);
            segments->fVaryings.appendf("varying float %s;\n", radial2VaryingName.c_str());

            // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
            segments->fVSCode.appendf("\t%s = 2.0 *(%s[2] * %s.x - %s[3]);\n",
                                      radial2VaryingName.c_str(), radial2ParamsName.c_str(),
                                      varyingName.c_str(), radial2ParamsName.c_str());
        }
    }

    /// Fragment Shader Stuff
    GrStringBuilder fsCoordName;
    // function used to access the shader, may be made projective
    GrStringBuilder texFunc("texture2D");
    if (desc.fOptFlags & (ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit |
                          ProgramDesc::StageDesc::kNoPerspective_OptFlagBit)) {
        GrAssert(varyingDims == coordDims);
        fsCoordName = varyingName;
    } else {
        // if we have to do some special op on the varyings to get
        // our final tex coords then when in perspective we have to
        // do an explicit divide. Otherwise, we can use a Proj func.
        if  (ProgramDesc::StageDesc::kIdentity_CoordMapping == desc.fCoordMapping &&
             ProgramDesc::StageDesc::kSingle_FetchMode == desc.fFetchMode) {
            texFunc.append("Proj");
            fsCoordName = varyingName;
        } else {
            fsCoordName = "inCoord";
            fsCoordName.appendS32(stageNum);
            segments->fFSCode.appendf("\t%s %s = %s%s / %s%s;\n",
                                       float_vector_type(coordDims),
                                       fsCoordName.c_str(),
                                       varyingName.c_str(),
                                       vector_nonhomog_coords(varyingDims),
                                       varyingName.c_str(),
                                       vector_homog_coord(varyingDims));
        }
    }

    GrStringBuilder sampleCoords;
    bool complexCoord = false;
    switch (desc.fCoordMapping) {
    case ProgramDesc::StageDesc::kIdentity_CoordMapping:
        sampleCoords = fsCoordName;
        break;
    case ProgramDesc::StageDesc::kSweepGradient_CoordMapping:
        sampleCoords.printf("vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)", fsCoordName.c_str(), fsCoordName.c_str());
        complexCoord = true;
        break;
    case ProgramDesc::StageDesc::kRadialGradient_CoordMapping:
        sampleCoords.printf("vec2(length(%s.xy), 0.5)", fsCoordName.c_str());
        complexCoord = true;
        break;
    case ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping: {
        GrStringBuilder cName("c");
        GrStringBuilder ac4Name("ac4");
        GrStringBuilder rootName("root");

        cName.appendS32(stageNum);
        ac4Name.appendS32(stageNum);
        rootName.appendS32(stageNum);

        // if we were able to interpolate the linear component bVar is the varying
        // otherwise compute it
        GrStringBuilder bVar;
        if (coordDims == varyingDims) {
            bVar = radial2VaryingName;
            GrAssert(2 == varyingDims);
        } else {
            GrAssert(3 == varyingDims);
            bVar = "b";
            bVar.appendS32(stageNum);
            segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
                                        bVar.c_str(), radial2ParamsName.c_str(),
                                        fsCoordName.c_str(), radial2ParamsName.c_str());
        }

        // c = (x^2)+(y^2) - params[4]
        segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
                                  cName.c_str(), fsCoordName.c_str(),
                                  fsCoordName.c_str(),
                                  radial2ParamsName.c_str());
        // ac4 = 4.0 * params[0] * c
        segments->fFSCode.appendf("\tfloat %s = %s[0] * 4.0 * %s;\n",
                                  ac4Name.c_str(), radial2ParamsName.c_str(),
                                  cName.c_str());

        // root = sqrt(b^2-4ac)
        // (abs to avoid exception due to fp precision)
        segments->fFSCode.appendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
                                  rootName.c_str(), bVar.c_str(), bVar.c_str(),
                                  ac4Name.c_str());

        // x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
        // y coord is 0.5 (texture is effectively 1D)
        sampleCoords.printf("vec2((-%s + %s[5] * %s) * %s[1], 0.5)",
                            bVar.c_str(), radial2ParamsName.c_str(),
                            rootName.c_str(), radial2ParamsName.c_str());
        complexCoord = true;
        break;}
    };

    const char* smear;
    if (desc.fModulation == ProgramDesc::StageDesc::kAlpha_Modulation) {
        smear = ".aaaa";
    } else {
        smear = "";
    }
    GrStringBuilder modulate;
    if (NULL != fsInColor) {
        modulate.printf(" * %s", fsInColor);
    }

    if (desc.fOptFlags &
        ProgramDesc::StageDesc::kCustomTextureDomain_OptFlagBit) {
        GrStringBuilder texDomainName;
        tex_domain_name(stageNum, &texDomainName);
        segments->fFSUnis.appendf("uniform %s %s;\n",
                                  float_vector_type(4),
                                  texDomainName.c_str());
        GrStringBuilder coordVar("clampCoord");
        segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
                                  float_vector_type(coordDims),
                                  coordVar.c_str(),
                                  sampleCoords.c_str(),
                                  texDomainName.c_str(),
                                  texDomainName.c_str());
        sampleCoords = coordVar;
        locations->fTexDomUni = kUseUniform;
    }

    if (ProgramDesc::StageDesc::k2x2_FetchMode == desc.fFetchMode) {
        locations->fNormalizedTexelSizeUni = kUseUniform;
        if (complexCoord) {
            // assign the coord to a var rather than compute 4x.
            GrStringBuilder coordVar("tCoord");
            coordVar.appendS32(stageNum);
            segments->fFSCode.appendf("\t%s %s = %s;\n",
                                      float_vector_type(coordDims),
                                      coordVar.c_str(), sampleCoords.c_str());
            sampleCoords = coordVar;
        }
        GrAssert(2 == coordDims);
        GrStringBuilder accumVar("accum");
        accumVar.appendS32(stageNum);
        segments->fFSCode.appendf("\tvec4 %s  = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
        segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
        segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
        segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
        segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str());
    } else {
        segments->fFSCode.appendf("\t%s = %s(%s, %s)%s%s;\n", fsOutColor, texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), smear, modulate.c_str());
    }
}
