• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GrGetGLSLGeneration(GrGLBinding binding,const GrGLInterface * gl)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 
GrGetGLSLVersionDecl(GrGLBinding binding,GrGLSLGeneration gen)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 
GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,const char * nameIfDeclared,GrGLShaderVar * var)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 
GrSLFloatVectorType(int count)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 
GrGLSLVectorHomogCoord(int count)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 
GrGLSLVectorHomogCoord(GrSLType type)89 const char* GrGLSLVectorHomogCoord(GrSLType type) {
90     return GrGLSLVectorHomogCoord(GrSLTypeToVecLength(type));
91 }
92 
GrGLSLVectorNonhomogCoords(int count)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 
GrGLSLVectorNonhomogCoords(GrSLType type)99 const char* GrGLSLVectorNonhomogCoords(GrSLType type) {
100     return GrGLSLVectorNonhomogCoords(GrSLTypeToVecLength(type));
101 }
102 
GrGLSLModulate4f(SkString * outAppend,const char * in0,const char * in1,GrSLConstantVec default0,GrSLConstantVec default1)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 {
append_tabs(SkString * outAppend,int tabCnt)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 
GrGLSLMulVarBy4f(SkString * outAppend,int tabCnt,const char * vec4VarName,const char * mulFactor,GrSLConstantVec mulFactorDefault)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 
GrGLSLAdd4f(SkString * outAppend,const char * in0,const char * in1,GrSLConstantVec default0,GrSLConstantVec default1)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