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