1 /*
2  * Copyright 2016 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 #ifndef GrShaderVar_DEFINED
9 #define GrShaderVar_DEFINED
10 
11 #include "include/core/SkString.h"
12 #include "include/private/GrTypesPriv.h"
13 
14 class GrShaderCaps;
15 
16 #define USE_UNIFORM_FLOAT_ARRAYS true
17 
18 /**
19  * Represents a variable in a shader
20  */
21 class GrShaderVar {
22 public:
23     enum TypeModifier {
24         kNone_TypeModifier,
25         kOut_TypeModifier,
26         kIn_TypeModifier,
27         kInOut_TypeModifier,
28         kUniform_TypeModifier,
29     };
30 
31     /**
32      * Values for array count that have special meaning. We allow 1-sized arrays.git
33      */
34     enum {
35         kNonArray     =  0, // not an array
36         kUnsizedArray = -1, // an unsized array (declared with [])
37     };
38 
39     /**
40      * Defaults to a non-arry half with no type modifier or layout qualifier.
41      */
GrShaderVar()42     GrShaderVar()
43         : fType(kHalf_GrSLType)
44         , fTypeModifier(kNone_TypeModifier)
45         , fCount(kNonArray)
46         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
47     }
48 
49     GrShaderVar(const SkString& name, GrSLType type, int arrayCount = kNonArray)
fType(type)50         : fType(type)
51         , fTypeModifier(kNone_TypeModifier)
52         , fCount(arrayCount)
53         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
54         , fName(name) {
55         SkASSERT(kVoid_GrSLType != type);
56         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
57     }
58 
59     GrShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray)
fType(type)60         : fType(type)
61         , fTypeModifier(kNone_TypeModifier)
62         , fCount(arrayCount)
63         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
64         , fName(name) {
65         SkASSERT(kVoid_GrSLType != type);
66         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
67     }
68 
GrShaderVar(const char * name,GrSLType type,TypeModifier typeModifier)69     GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier)
70         : fType(type)
71         , fTypeModifier(typeModifier)
72         , fCount(kNonArray)
73         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
74         , fName(name) {
75         SkASSERT(kVoid_GrSLType != type);
76     }
77 
GrShaderVar(const char * name,GrSLType type,TypeModifier typeModifier,int arrayCount)78     GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier, int arrayCount)
79         : fType(type)
80         , fTypeModifier(typeModifier)
81         , fCount(arrayCount)
82         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
83         , fName(name) {
84         SkASSERT(kVoid_GrSLType != type);
85     }
86 
GrShaderVar(const GrShaderVar & that)87     GrShaderVar(const GrShaderVar& that)
88         : fType(that.fType)
89         , fTypeModifier(that.fTypeModifier)
90         , fCount(that.fCount)
91         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
92         , fName(that.fName)
93         , fLayoutQualifier(that.fLayoutQualifier)
94         , fExtraModifiers(that.fExtraModifiers) {
95         SkASSERT(kVoid_GrSLType != that.getType());
96     }
97 
98     /**
99      * Sets as a non-array.
100      */
101     void set(GrSLType type,
102              const SkString& name,
103              TypeModifier typeModifier = kNone_TypeModifier,
104              const char* layoutQualifier = nullptr,
105              const char* extraModifiers = nullptr,
106              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
107         SkASSERT(kVoid_GrSLType != type);
108         fType = type;
109         fTypeModifier = typeModifier;
110         fName = name;
111         fCount = kNonArray;
112         fLayoutQualifier = layoutQualifier;
113         if (extraModifiers) {
114             fExtraModifiers.printf("%s ", extraModifiers);
115         }
116         fUseUniformFloatArrays = useUniformFloatArrays;
117     }
118 
119     /**
120      * Sets as a non-array.
121      */
122     void set(GrSLType type,
123              const char* name,
124              TypeModifier typeModifier = kNone_TypeModifier,
125              const char* layoutQualifier = nullptr,
126              const char* extraModifiers = nullptr,
127              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
128         SkASSERT(kVoid_GrSLType != type);
129         fType = type;
130         fTypeModifier = typeModifier;
131         fName = name;
132         fCount = kNonArray;
133         fLayoutQualifier = layoutQualifier;
134         if (extraModifiers) {
135             fExtraModifiers.printf("%s ", extraModifiers);
136         }
137         fUseUniformFloatArrays = useUniformFloatArrays;
138     }
139 
140     /**
141      * Set all var options
142      */
143     void set(GrSLType type,
144              const SkString& name,
145              int count,
146              TypeModifier typeModifier,
147              const char* layoutQualifier = nullptr,
148              const char* extraModifiers = nullptr,
149              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
150         SkASSERT(kVoid_GrSLType != type);
151         fType = type;
152         fTypeModifier = typeModifier;
153         fName = name;
154         fCount = count;
155         fLayoutQualifier = layoutQualifier;
156         if (extraModifiers) {
157             fExtraModifiers.printf("%s ", extraModifiers);
158         }
159         fUseUniformFloatArrays = useUniformFloatArrays;
160     }
161 
162     /**
163      * Set all var options
164      */
165     void set(GrSLType type,
166              const char* name,
167              int count,
168              TypeModifier typeModifier,
169              const char* layoutQualifier = nullptr,
170              const char* extraModifiers = nullptr,
171              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
172         SkASSERT(kVoid_GrSLType != type);
173         fType = type;
174         fTypeModifier = typeModifier;
175         fName = name;
176         fCount = count;
177         fLayoutQualifier = layoutQualifier;
178         if (extraModifiers) {
179             fExtraModifiers.printf("%s ", extraModifiers);
180         }
181         fUseUniformFloatArrays = useUniformFloatArrays;
182     }
183 
184     /**
185      * Is the var an array.
186      */
isArray()187     bool isArray() const { return kNonArray != fCount; }
188     /**
189      * Is this an unsized array, (i.e. declared with []).
190      */
isUnsizedArray()191     bool isUnsizedArray() const { return kUnsizedArray == fCount; }
192     /**
193      * Get the array length of the var.
194      */
getArrayCount()195     int getArrayCount() const { return fCount; }
196     /**
197      * Set the array length of the var
198      */
setArrayCount(int count)199     void setArrayCount(int count) { fCount = count; }
200     /**
201      * Set to be a non-array.
202      */
setNonArray()203     void setNonArray() { fCount = kNonArray; }
204     /**
205      * Set to be an unsized array.
206      */
setUnsizedArray()207     void setUnsizedArray() { fCount = kUnsizedArray; }
208 
209     /**
210      * Access the var name as a writable string
211      */
accessName()212     SkString* accessName() { return &fName; }
213     /**
214      * Set the var name
215      */
setName(const SkString & n)216     void setName(const SkString& n) { fName = n; }
setName(const char * n)217     void setName(const char* n) { fName = n; }
218 
219     /**
220      * Get the var name.
221      */
getName()222     const SkString& getName() const { return fName; }
223 
224     /**
225      * Shortcut for this->getName().c_str();
226      */
c_str()227     const char* c_str() const { return this->getName().c_str(); }
228 
229     /**
230      * Get the type of the var
231      */
getType()232     GrSLType getType() const { return fType; }
233     /**
234      * Set the type of the var
235      */
setType(GrSLType type)236     void setType(GrSLType type) { fType = type; }
237 
getTypeModifier()238     TypeModifier getTypeModifier() const { return fTypeModifier; }
setTypeModifier(TypeModifier type)239     void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
240 
241     /**
242      * Appends to the layout qualifier
243      */
addLayoutQualifier(const char * layoutQualifier)244     void addLayoutQualifier(const char* layoutQualifier) {
245         if (!layoutQualifier || !strlen(layoutQualifier)) {
246             return;
247         }
248         if (fLayoutQualifier.isEmpty()) {
249             fLayoutQualifier = layoutQualifier;
250         } else {
251             fLayoutQualifier.appendf(", %s", layoutQualifier);
252         }
253     }
254 
255     void setIOType(GrIOType);
256 
addModifier(const char * modifier)257     void addModifier(const char* modifier) {
258         if (modifier) {
259             fExtraModifiers.appendf("%s ", modifier);
260         }
261     }
262 
263     /**
264      * Write a declaration of this variable to out.
265      */
266     void appendDecl(const GrShaderCaps*, SkString* out) const;
267 
appendArrayAccess(int index,SkString * out)268     void appendArrayAccess(int index, SkString* out) const {
269         out->appendf("%s[%d]%s",
270                      this->getName().c_str(),
271                      index,
272                      fUseUniformFloatArrays ? "" : ".x");
273     }
274 
appendArrayAccess(const char * indexName,SkString * out)275     void appendArrayAccess(const char* indexName, SkString* out) const {
276         out->appendf("%s[%s]%s",
277                      this->getName().c_str(),
278                      indexName,
279                      fUseUniformFloatArrays ? "" : ".x");
280     }
281 
282 private:
283     GrSLType        fType;
284     TypeModifier    fTypeModifier;
285     int             fCount;
286     /// Work around driver bugs on some hardware that don't correctly
287     /// support uniform float []
288     bool            fUseUniformFloatArrays;
289 
290     SkString        fName;
291     SkString        fLayoutQualifier;
292     SkString        fExtraModifiers;
293 };
294 
295 #endif
296