180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrGLSL.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrGLShaderVar.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkString.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding, const GrGLInterface* gl) {
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLSLVersion ver = GrGLGetGLSLVersion(gl);
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (binding) {
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case kDesktop_GrGLBinding:
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(ver >= GR_GLSL_VER(1,10));
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (ver >= GR_GLSL_VER(1,50)) {
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return k150_GrGLSLGeneration;
19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            } else if (ver >= GR_GLSL_VER(1,40)) {
20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                return k140_GrGLSLGeneration;
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else if (ver >= GR_GLSL_VER(1,30)) {
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return k130_GrGLSLGeneration;
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else {
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return k110_GrGLSLGeneration;
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case kES2_GrGLBinding:
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // version 1.00 of ES GLSL based on ver 1.20 of desktop GLSL
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(ver >= GR_GL_VER(1,00));
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return k110_GrGLSLGeneration;
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        default:
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrCrash("Unknown GL Binding");
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return k110_GrGLSLGeneration; // suppress warning
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerconst char* GrGetGLSLVersionDecl(GrGLBinding binding, GrGLSLGeneration gen) {
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (gen) {
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case k110_GrGLSLGeneration:
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (kES2_GrGLBinding == binding) {
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // ES2s shader language is based on version 1.20 but is version
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                // 1.00 of the ES language.
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return "#version 100\n";
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else {
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                GrAssert(kDesktop_GrGLBinding == binding);
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return "#version 110\n";
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case k130_GrGLSLGeneration:
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(kDesktop_GrGLBinding == binding);
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return "#version 130\n";
50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        case k140_GrGLSLGeneration:
51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            GrAssert(kDesktop_GrGLBinding == binding);
52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            return "#version 140\n";
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        case k150_GrGLSLGeneration:
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(kDesktop_GrGLBinding == binding);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return "#version 150\n";
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        default:
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrCrash("Unknown GL version.");
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return ""; // suppress warning
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen, const char* nameIfDeclared, GrGLShaderVar* var) {
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool declaredOutput = k110_GrGLSLGeneration != gen;
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    var->set(kVec4f_GrSLType,
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             GrGLShaderVar::kOut_TypeModifier,
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             declaredOutput ? nameIfDeclared : "gl_FragColor");
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return declaredOutput;
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* GrGLSLVectorHomogCoord(int count) {
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS));
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return HOMOGS[count];
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* GrGLSLVectorHomogCoord(GrSLType type) {
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return GrGLSLVectorHomogCoord(GrSLTypeToVecLength(type));
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* GrGLSLVectorNonhomogCoords(int count) {
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return NONHOMOGS[count];
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* GrGLSLVectorNonhomogCoords(GrSLType type) {
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return GrGLSLVectorNonhomogCoords(GrSLTypeToVecLength(type));
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace {
917839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void append_tabs(SkString* outAppend, int tabCnt) {
927839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        static const char kTabs[] = "\t\t\t\t\t\t\t\t";
937839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        while (tabCnt) {
947839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            int cnt = GrMin((int)GR_ARRAY_COUNT(kTabs), tabCnt);
957839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            outAppend->append(kTabs, cnt);
967839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            tabCnt -= cnt;
977839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrSLConstantVec GrGLSLMulVarBy4f(SkString* outAppend,
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                 int tabCnt,
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                 const char* vec4VarName,
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                 const char* mulFactor,
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                 GrSLConstantVec mulFactorDefault) {
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool haveFactor = NULL != mulFactor && '\0' != *mulFactor;
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAssert(NULL != outAppend);
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAssert(NULL != vec4VarName);
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAssert(kNone_GrSLConstantVec != mulFactorDefault || haveFactor);
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!haveFactor) {
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (kOnes_GrSLConstantVec == mulFactorDefault) {
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return kNone_GrSLConstantVec;
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(kZeros_GrSLConstantVec == mulFactorDefault);
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            append_tabs(outAppend, tabCnt);
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            outAppend->appendf("%s = vec4(0, 0, 0, 0);\n", vec4VarName);
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return kZeros_GrSLConstantVec;
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    append_tabs(outAppend, tabCnt);
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    outAppend->appendf("%s *= %s;\n", vec4VarName, mulFactor);
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return kNone_GrSLConstantVec;
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1277839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrSLConstantVec GrGLSLGetComponent4f(SkString* outAppend,
1287839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     const char* expr,
1297839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     GrColorComponentFlags component,
1307839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     GrSLConstantVec defaultExpr,
1317839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                     bool omitIfConst) {
1327839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    if (NULL == expr || '\0' == *expr) {
1337839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrAssert(defaultExpr != kNone_GrSLConstantVec);
1347839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        if (!omitIfConst) {
1357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            if (kOnes_GrSLConstantVec == defaultExpr) {
1367839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                outAppend->append("1.0");
1377839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            } else {
1387839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                GrAssert(kZeros_GrSLConstantVec == defaultExpr);
1397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                outAppend->append("0.0");
1407839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger            }
1417839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
1427839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        return defaultExpr;
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
1447839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        outAppend->appendf("(%s).%c", expr, GrColorComponentFlagToChar(component));
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return kNone_GrSLConstantVec;
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
148