• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #ifndef GrGLShaderVar_DEFINED
10 #define GrGLShaderVar_DEFINED
11 
12 #include "GrGLContextInfo.h"
13 #include "GrGLSL.h"
14 #include "../GrStringBuilder.h"
15 
16 #define USE_UNIFORM_FLOAT_ARRAYS true
17 
18 /**
19  * Represents a variable in a shader
20  */
21 class GrGLShaderVar {
22 public:
23 
24     enum Type {
25         kFloat_Type,
26         kVec2f_Type,
27         kVec3f_Type,
28         kVec4f_Type,
29         kMat33f_Type,
30         kMat44f_Type,
31         kSampler2D_Type,
32     };
33 
34     /**
35      * Early versions of GLSL have Varying and Attribute; those are later
36      * deprecated, but we still need to know whether a Varying variable
37      * should be treated as In or Out.
38      */
39     enum TypeModifier {
40         kNone_TypeModifier,
41         kOut_TypeModifier,
42         kIn_TypeModifier,
43         kUniform_TypeModifier,
44         kAttribute_TypeModifier
45     };
46 
47     /**
48      * Defaults to a float with no precision specifier
49      */
GrGLShaderVar()50     GrGLShaderVar() {
51         fType = kFloat_Type;
52         fTypeModifier = kNone_TypeModifier;
53         fCount = kNonArray;
54         fEmitPrecision = false;
55         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
56     }
57 
GrGLShaderVar(const GrGLShaderVar & var)58     GrGLShaderVar(const GrGLShaderVar& var)
59         : fType(var.fType)
60         , fTypeModifier(var.fTypeModifier)
61         , fName(var.fName)
62         , fCount(var.fCount)
63         , fEmitPrecision(var.fEmitPrecision)
64         , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
65 
66     /**
67      * Values for array count that have special meaning. We allow 1-sized arrays.
68      */
69     enum {
70         kNonArray     =  0, // not an array
71         kUnsizedArray = -1, // an unsized array (declared with [])
72     };
73 
74     /**
75      * Sets as a non-array.
76      */
77     void set(Type type,
78              TypeModifier typeModifier,
79              const GrStringBuilder& name,
80              bool emitPrecision = false,
81              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
82         fType = type;
83         fTypeModifier = typeModifier;
84         fName = name;
85         fCount = kNonArray;
86         fEmitPrecision = emitPrecision;
87         fUseUniformFloatArrays = useUniformFloatArrays;
88     }
89 
90     /**
91      * Sets as a non-array.
92      */
93     void set(Type type,
94              TypeModifier typeModifier,
95              const char* name,
96              bool specifyPrecision = false,
97              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
98         fType = type;
99         fTypeModifier = typeModifier;
100         fName = name;
101         fCount = kNonArray;
102         fEmitPrecision = specifyPrecision;
103         fUseUniformFloatArrays = useUniformFloatArrays;
104     }
105 
106     /**
107      * Set all var options
108      */
109     void set(Type type,
110              TypeModifier typeModifier,
111              const GrStringBuilder& name,
112              int count,
113              bool specifyPrecision = false,
114              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
115         fType = type;
116         fTypeModifier = typeModifier;
117         fName = name;
118         fCount = count;
119         fEmitPrecision = specifyPrecision;
120         fUseUniformFloatArrays = useUniformFloatArrays;
121     }
122 
123     /**
124      * Set all var options
125      */
126     void set(Type type,
127              TypeModifier typeModifier,
128              const char* name,
129              int count,
130              bool specifyPrecision = false,
131              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
132         fType = type;
133         fTypeModifier = typeModifier;
134         fName = name;
135         fCount = count;
136         fEmitPrecision = specifyPrecision;
137         fUseUniformFloatArrays = useUniformFloatArrays;
138     }
139 
140     /**
141      * Is the var an array.
142      */
isArray()143     bool isArray() const { return kNonArray != fCount; }
144     /**
145      * Is this an unsized array, (i.e. declared with []).
146      */
isUnsizedArray()147     bool isUnsizedArray() const { return kUnsizedArray == fCount; }
148     /**
149      * Get the array length of the var.
150      */
getArrayCount()151     int getArrayCount() const { return fCount; }
152     /**
153      * Set the array length of the var
154      */
setArrayCount(int count)155     void setArrayCount(int count) { fCount = count; }
156     /**
157      * Set to be a non-array.
158      */
setNonArray()159     void setNonArray() { fCount = kNonArray; }
160     /**
161      * Set to be an unsized array.
162      */
setUnsizedArray()163     void setUnsizedArray() { fCount = kUnsizedArray; }
164 
165     /**
166      * Access the var name as a writable string
167      */
accessName()168     GrStringBuilder* accessName() { return &fName; }
169     /**
170      * Set the var name
171      */
setName(const GrStringBuilder & n)172     void setName(const GrStringBuilder& n) { fName = n; }
setName(const char * n)173     void setName(const char* n) { fName = n; }
174     /**
175      * Get the var name.
176      */
getName()177     const GrStringBuilder& getName() const { return fName; }
178 
179     /**
180      * Get the type of the var
181      */
getType()182     Type getType() const { return fType; }
183     /**
184      * Set the type of the var
185      */
setType(Type type)186     void setType(Type type) { fType = type; }
187 
getTypeModifier()188     TypeModifier getTypeModifier() const { return fTypeModifier; }
setTypeModifier(TypeModifier type)189     void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
190 
191     /**
192      * Must the variable declaration emit a precision specifier
193      */
emitsPrecision()194     bool emitsPrecision() const { return fEmitPrecision; }
195     /**
196      * Specify whether the declaration should specify precision
197      */
setEmitPrecision(bool p)198     void setEmitPrecision(bool p) { fEmitPrecision = p; }
199 
200     /**
201      * Write a declaration of this variable to out.
202      */
appendDecl(const GrGLContextInfo & gl,GrStringBuilder * out)203     void appendDecl(const GrGLContextInfo& gl, GrStringBuilder* out) const {
204         if (this->getTypeModifier() != kNone_TypeModifier) {
205            out->append(TypeModifierString(this->getTypeModifier(),
206                                           gl.glslGeneration()));
207            out->append(" ");
208         }
209         if (this->emitsPrecision()) {
210             out->append(GrGetGLSLVarPrecisionDeclType(gl.binding()));
211             out->append(" ");
212         }
213         Type effectiveType = this->getType();
214         if (this->isArray()) {
215             if (this->isUnsizedArray()) {
216                 out->appendf("%s %s[]",
217                              TypeString(effectiveType),
218                              this->getName().c_str());
219             } else {
220                 GrAssert(this->getArrayCount() > 0);
221                 out->appendf("%s %s[%d]",
222                              TypeString(effectiveType),
223                              this->getName().c_str(),
224                              this->getArrayCount());
225             }
226         } else {
227             out->appendf("%s %s",
228                          TypeString(effectiveType),
229                          this->getName().c_str());
230         }
231         out->append(";\n");
232     }
233 
TypeString(Type t)234     static const char* TypeString(Type t) {
235         switch (t) {
236             case kFloat_Type:
237                 return "float";
238             case kVec2f_Type:
239                 return "vec2";
240             case kVec3f_Type:
241                 return "vec3";
242             case kVec4f_Type:
243                 return "vec4";
244             case kMat33f_Type:
245                 return "mat3";
246             case kMat44f_Type:
247                 return "mat4";
248             case kSampler2D_Type:
249                 return "sampler2D";
250             default:
251                 GrCrash("Unknown shader var type.");
252                 return ""; // suppress warning
253         }
254     }
255 
appendArrayAccess(int index,GrStringBuilder * out)256     void appendArrayAccess(int index, GrStringBuilder* out) {
257         out->appendf("%s[%d]%s",
258                      this->getName().c_str(),
259                      index,
260                      fUseUniformFloatArrays ? "" : ".x");
261     }
262 
appendArrayAccess(const char * indexName,GrStringBuilder * out)263     void appendArrayAccess(const char* indexName, GrStringBuilder* out) {
264         out->appendf("%s[%s]%s",
265                      this->getName().c_str(),
266                      indexName,
267                      fUseUniformFloatArrays ? "" : ".x");
268     }
269 
270 private:
TypeModifierString(TypeModifier t,GrGLSLGeneration gen)271     static const char* TypeModifierString(TypeModifier t,
272                                           GrGLSLGeneration gen) {
273         switch (t) {
274             case kNone_TypeModifier:
275                 return "";
276             case kOut_TypeModifier:
277                 return k110_GrGLSLGeneration == gen ? "varying" : "out";
278             case kIn_TypeModifier:
279                 return k110_GrGLSLGeneration == gen ? "varying" : "in";
280             case kUniform_TypeModifier:
281                 return "uniform";
282             case kAttribute_TypeModifier:
283                 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
284             default:
285                 GrCrash("Unknown shader variable type modifier.");
286                 return ""; // suppress warning
287         }
288     }
289 
290     Type            fType;
291     TypeModifier    fTypeModifier;
292     GrStringBuilder fName;
293     int             fCount;
294     bool            fEmitPrecision;
295     /// Work around driver bugs on some hardware that don't correctly
296     /// support uniform float []
297     bool            fUseUniformFloatArrays;
298 };
299 
300 #endif
301