Home | History | Annotate | Download | only in gl
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "GrGLSL.h"
      9 #include "GrGLShaderVar.h"
     10 #include "SkString.h"
     11 
     12 GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding,
     13                                    const GrGLInterface* gl) {
     14     GrGLSLVersion ver = GrGLGetGLSLVersion(gl);
     15     switch (binding) {
     16         case kDesktop_GrGLBinding:
     17             GrAssert(ver >= GR_GLSL_VER(1,10));
     18             if (ver >= GR_GLSL_VER(1,50)) {
     19                 return k150_GrGLSLGeneration;
     20             } else if (ver >= GR_GLSL_VER(1,40)) {
     21                 return k140_GrGLSLGeneration;
     22             } else if (ver >= GR_GLSL_VER(1,30)) {
     23                 return k130_GrGLSLGeneration;
     24             } else {
     25                 return k110_GrGLSLGeneration;
     26             }
     27         case kES2_GrGLBinding:
     28             // version 1.00 of ES GLSL based on ver 1.20 of desktop GLSL
     29             GrAssert(ver >= GR_GL_VER(1,00));
     30             return k110_GrGLSLGeneration;
     31         default:
     32             GrCrash("Unknown GL Binding");
     33             return k110_GrGLSLGeneration; // suppress warning
     34     }
     35 }
     36 
     37 const char* GrGetGLSLVersionDecl(GrGLBinding binding,
     38                                    GrGLSLGeneration gen) {
     39     switch (gen) {
     40         case k110_GrGLSLGeneration:
     41             if (kES2_GrGLBinding == binding) {
     42                 // ES2s shader language is based on version 1.20 but is version
     43                 // 1.00 of the ES language.
     44                 return "#version 100\n";
     45             } else {
     46                 GrAssert(kDesktop_GrGLBinding == binding);
     47                 return "#version 110\n";
     48             }
     49         case k130_GrGLSLGeneration:
     50             GrAssert(kDesktop_GrGLBinding == binding);
     51             return "#version 130\n";
     52         case k140_GrGLSLGeneration:
     53             GrAssert(kDesktop_GrGLBinding == binding);
     54             return "#version 140\n";
     55         case k150_GrGLSLGeneration:
     56             GrAssert(kDesktop_GrGLBinding == binding);
     57             return "#version 150\n";
     58         default:
     59             GrCrash("Unknown GL version.");
     60             return ""; // suppress warning
     61     }
     62 }
     63 
     64 bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
     65                              const char* nameIfDeclared,
     66                              GrGLShaderVar* var) {
     67     bool declaredOutput = k110_GrGLSLGeneration != gen;
     68     var->set(kVec4f_GrSLType,
     69              GrGLShaderVar::kOut_TypeModifier,
     70              declaredOutput ? nameIfDeclared : "gl_FragColor");
     71     return declaredOutput;
     72 }
     73 
     74 GrSLType GrSLFloatVectorType (int count) {
     75     GR_STATIC_ASSERT(kFloat_GrSLType == 1);
     76     GR_STATIC_ASSERT(kVec2f_GrSLType == 2);
     77     GR_STATIC_ASSERT(kVec3f_GrSLType == 3);
     78     GR_STATIC_ASSERT(kVec4f_GrSLType == 4);
     79     GrAssert(count > 0 && count <= 4);
     80     return (GrSLType)(count);
     81 }
     82 
     83 const char* GrGLSLVectorHomogCoord(int count) {
     84     static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
     85     GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS));
     86     return HOMOGS[count];
     87 }
     88 
     89 const char* GrGLSLVectorHomogCoord(GrSLType type) {
     90     return GrGLSLVectorHomogCoord(GrSLTypeToVecLength(type));
     91 }
     92 
     93 const char* GrGLSLVectorNonhomogCoords(int count) {
     94     static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
     95     GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
     96     return NONHOMOGS[count];
     97 }
     98 
     99 const char* GrGLSLVectorNonhomogCoords(GrSLType type) {
    100     return GrGLSLVectorNonhomogCoords(GrSLTypeToVecLength(type));
    101 }
    102 
    103 GrSLConstantVec GrGLSLModulate4f(SkString* outAppend,
    104                                  const char* in0,
    105                                  const char* in1,
    106                                  GrSLConstantVec default0,
    107                                  GrSLConstantVec default1) {
    108     GrAssert(NULL != outAppend);
    109 
    110     bool has0 = NULL != in0 && '\0' != *in0;
    111     bool has1 = NULL != in1 && '\0' != *in1;
    112 
    113     GrAssert(has0 || kNone_GrSLConstantVec != default0);
    114     GrAssert(has1 || kNone_GrSLConstantVec != default1);
    115 
    116     if (!has0 && !has1) {
    117         GrAssert(kZeros_GrSLConstantVec == default0 || kOnes_GrSLConstantVec == default0);
    118         GrAssert(kZeros_GrSLConstantVec == default1 || kOnes_GrSLConstantVec == default1);
    119         if (kZeros_GrSLConstantVec == default0 || kZeros_GrSLConstantVec == default1) {
    120             outAppend->append(GrGLSLZerosVecf(4));
    121             return kZeros_GrSLConstantVec;
    122         } else {
    123             // both inputs are ones vectors
    124             outAppend->append(GrGLSLOnesVecf(4));
    125             return kOnes_GrSLConstantVec;
    126         }
    127     } else if (!has0) {
    128         GrAssert(kZeros_GrSLConstantVec == default0 || kOnes_GrSLConstantVec == default0);
    129         if (kZeros_GrSLConstantVec == default0) {
    130             outAppend->append(GrGLSLZerosVecf(4));
    131             return kZeros_GrSLConstantVec;
    132         } else {
    133             outAppend->appendf("vec4(%s)", in1);
    134             return kNone_GrSLConstantVec;
    135         }
    136     } else if (!has1) {
    137         GrAssert(kZeros_GrSLConstantVec == default1 || kOnes_GrSLConstantVec == default1);
    138         if (kZeros_GrSLConstantVec == default1) {
    139             outAppend->append(GrGLSLZerosVecf(4));
    140             return kZeros_GrSLConstantVec;
    141         } else {
    142             outAppend->appendf("vec4(%s)", in0);
    143             return kNone_GrSLConstantVec;
    144         }
    145     } else {
    146         outAppend->appendf("vec4(%s * %s)", in0, in1);
    147         return kNone_GrSLConstantVec;
    148     }
    149 }
    150 
    151 namespace {
    152 void append_tabs(SkString* outAppend, int tabCnt) {
    153     static const char kTabs[] = "\t\t\t\t\t\t\t\t";
    154     while (tabCnt) {
    155         int cnt = GrMin((int)GR_ARRAY_COUNT(kTabs), tabCnt);
    156         outAppend->append(kTabs, cnt);
    157         tabCnt -= cnt;
    158     }
    159 }
    160 }
    161 
    162 GrSLConstantVec GrGLSLMulVarBy4f(SkString* outAppend,
    163                                  int tabCnt,
    164                                  const char* vec4VarName,
    165                                  const char* mulFactor,
    166                                  GrSLConstantVec mulFactorDefault) {
    167     bool haveFactor = NULL != mulFactor && '\0' != *mulFactor;
    168 
    169     GrAssert(NULL != outAppend);
    170     GrAssert(NULL != vec4VarName);
    171     GrAssert(kNone_GrSLConstantVec != mulFactorDefault || haveFactor);
    172 
    173     if (!haveFactor) {
    174         if (kOnes_GrSLConstantVec == mulFactorDefault) {
    175             return kNone_GrSLConstantVec;
    176         } else {
    177             GrAssert(kZeros_GrSLConstantVec == mulFactorDefault);
    178             append_tabs(outAppend, tabCnt);
    179             outAppend->appendf("%s = vec4(0, 0, 0, 0);\n", vec4VarName);
    180             return kZeros_GrSLConstantVec;
    181         }
    182     }
    183     append_tabs(outAppend, tabCnt);
    184     outAppend->appendf("%s *= %s;\n", vec4VarName, mulFactor);
    185     return kNone_GrSLConstantVec;
    186 }
    187 
    188 GrSLConstantVec GrGLSLAdd4f(SkString* outAppend,
    189                             const char* in0,
    190                             const char* in1,
    191                             GrSLConstantVec default0,
    192                             GrSLConstantVec default1) {
    193     GrAssert(NULL != outAppend);
    194 
    195     bool has0 = NULL != in0 && '\0' != *in0;
    196     bool has1 = NULL != in1 && '\0' != *in1;
    197 
    198     if (!has0 && !has1) {
    199         GrAssert(kZeros_GrSLConstantVec == default0);
    200         GrAssert(kZeros_GrSLConstantVec == default1);
    201         outAppend->append(GrGLSLZerosVecf(4));
    202         return kZeros_GrSLConstantVec;
    203     } else if (!has0) {
    204         GrAssert(kZeros_GrSLConstantVec == default0);
    205         outAppend->appendf("vec4(%s)", in1);
    206         return kNone_GrSLConstantVec;
    207     } else if (!has1) {
    208         GrAssert(kZeros_GrSLConstantVec == default1);
    209         outAppend->appendf("vec4(%s)", in0);
    210         return kNone_GrSLConstantVec;
    211     } else {
    212         outAppend->appendf("(vec4(%s) + vec4(%s))", in0, in1);
    213         return kNone_GrSLConstantVec;
    214     }
    215 }
    216