• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkString.h"
12 #include "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 float with no precision specifier, type modifier, or layout qualifier.
41      */
GrShaderVar()42     GrShaderVar()
43         : fType(kFloat_GrSLType)
44         , fTypeModifier(kNone_TypeModifier)
45         , fCount(kNonArray)
46         , fPrecision(kDefault_GrSLPrecision)
47         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
48     }
49 
50     GrShaderVar(const SkString& name, GrSLType type, int arrayCount = kNonArray,
51                 GrSLPrecision precision = kDefault_GrSLPrecision)
fType(type)52         : fType(type)
53         , fTypeModifier(kNone_TypeModifier)
54         , fCount(arrayCount)
55         , fPrecision(precision)
56         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
57         , fName(name) {
58         SkASSERT(kVoid_GrSLType != type);
59         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
60     }
61 
62     GrShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
63                 GrSLPrecision precision = kDefault_GrSLPrecision)
fType(type)64         : fType(type)
65         , fTypeModifier(kNone_TypeModifier)
66         , fCount(arrayCount)
67         , fPrecision(precision)
68         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
69         , fName(name) {
70         SkASSERT(kVoid_GrSLType != type);
71         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
72     }
73 
74     GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
75                 GrSLPrecision precision = kDefault_GrSLPrecision)
fType(type)76         : fType(type)
77         , fTypeModifier(typeModifier)
78         , fCount(kNonArray)
79         , fPrecision(precision)
80         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
81         , fName(name) {
82         SkASSERT(kVoid_GrSLType != type);
83     }
84 
85     GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
86                 int arrayCount, GrSLPrecision precision = kDefault_GrSLPrecision)
fType(type)87         : fType(type)
88         , fTypeModifier(typeModifier)
89         , fCount(arrayCount)
90         , fPrecision(precision)
91         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
92         , fName(name) {
93         SkASSERT(kVoid_GrSLType != type);
94     }
95 
GrShaderVar(const GrShaderVar & that)96     GrShaderVar(const GrShaderVar& that)
97         : fType(that.fType)
98         , fTypeModifier(that.fTypeModifier)
99         , fCount(that.fCount)
100         , fPrecision(that.fPrecision)
101         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
102         , fName(that.fName)
103         , fLayoutQualifier(that.fLayoutQualifier)
104         , fExtraModifiers(that.fExtraModifiers) {
105         SkASSERT(kVoid_GrSLType != that.getType());
106     }
107 
108     /**
109      * Sets as a non-array.
110      */
111     void set(GrSLType type,
112              const SkString& name,
113              TypeModifier typeModifier = kNone_TypeModifier,
114              GrSLPrecision precision = kDefault_GrSLPrecision,
115              const char* layoutQualifier = nullptr,
116              const char* extraModifiers = nullptr,
117              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
118         SkASSERT(kVoid_GrSLType != type);
119         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type));
120         fType = type;
121         fTypeModifier = typeModifier;
122         fName = name;
123         fCount = kNonArray;
124         fPrecision = precision;
125         fLayoutQualifier = layoutQualifier;
126         if (extraModifiers) {
127             fExtraModifiers.printf("%s ", extraModifiers);
128         }
129         fUseUniformFloatArrays = useUniformFloatArrays;
130     }
131 
132     /**
133      * Sets as a non-array.
134      */
135     void set(GrSLType type,
136              const char* name,
137              TypeModifier typeModifier = kNone_TypeModifier,
138              GrSLPrecision precision = kDefault_GrSLPrecision,
139              const char* layoutQualifier = nullptr,
140              const char* extraModifiers = nullptr,
141              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
142         SkASSERT(kVoid_GrSLType != type);
143         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type));
144         fType = type;
145         fTypeModifier = typeModifier;
146         fName = name;
147         fCount = kNonArray;
148         fPrecision = precision;
149         fLayoutQualifier = layoutQualifier;
150         if (extraModifiers) {
151             fExtraModifiers.printf("%s ", extraModifiers);
152         }
153         fUseUniformFloatArrays = useUniformFloatArrays;
154     }
155 
156     /**
157      * Set all var options
158      */
159     void set(GrSLType type,
160              const SkString& name,
161              int count,
162              TypeModifier typeModifier,
163              GrSLPrecision precision = kDefault_GrSLPrecision,
164              const char* layoutQualifier = nullptr,
165              const char* extraModifiers = nullptr,
166              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
167         SkASSERT(kVoid_GrSLType != type);
168         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type));
169         fType = type;
170         fTypeModifier = typeModifier;
171         fName = name;
172         fCount = count;
173         fPrecision = precision;
174         fLayoutQualifier = layoutQualifier;
175         if (extraModifiers) {
176             fExtraModifiers.printf("%s ", extraModifiers);
177         }
178         fUseUniformFloatArrays = useUniformFloatArrays;
179     }
180 
181     /**
182      * Set all var options
183      */
184     void set(GrSLType type,
185              const char* name,
186              int count,
187              TypeModifier typeModifier,
188              GrSLPrecision precision = kDefault_GrSLPrecision,
189              const char* layoutQualifier = nullptr,
190              const char* extraModifiers = nullptr,
191              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
192         SkASSERT(kVoid_GrSLType != type);
193         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type));
194         fType = type;
195         fTypeModifier = typeModifier;
196         fName = name;
197         fCount = count;
198         fPrecision = precision;
199         fLayoutQualifier = layoutQualifier;
200         if (extraModifiers) {
201             fExtraModifiers.printf("%s ", extraModifiers);
202         }
203         fUseUniformFloatArrays = useUniformFloatArrays;
204     }
205 
206     /**
207      * Is the var an array.
208      */
isArray()209     bool isArray() const { return kNonArray != fCount; }
210     /**
211      * Is this an unsized array, (i.e. declared with []).
212      */
isUnsizedArray()213     bool isUnsizedArray() const { return kUnsizedArray == fCount; }
214     /**
215      * Get the array length of the var.
216      */
getArrayCount()217     int getArrayCount() const { return fCount; }
218     /**
219      * Set the array length of the var
220      */
setArrayCount(int count)221     void setArrayCount(int count) { fCount = count; }
222     /**
223      * Set to be a non-array.
224      */
setNonArray()225     void setNonArray() { fCount = kNonArray; }
226     /**
227      * Set to be an unsized array.
228      */
setUnsizedArray()229     void setUnsizedArray() { fCount = kUnsizedArray; }
230 
231     /**
232      * Access the var name as a writable string
233      */
accessName()234     SkString* accessName() { return &fName; }
235     /**
236      * Set the var name
237      */
setName(const SkString & n)238     void setName(const SkString& n) { fName = n; }
setName(const char * n)239     void setName(const char* n) { fName = n; }
240 
241     /**
242      * Get the var name.
243      */
getName()244     const SkString& getName() const { return fName; }
245 
246     /**
247      * Shortcut for this->getName().c_str();
248      */
c_str()249     const char* c_str() const { return this->getName().c_str(); }
250 
251     /**
252      * Get the type of the var
253      */
getType()254     GrSLType getType() const { return fType; }
255     /**
256      * Set the type of the var
257      */
setType(GrSLType type)258     void setType(GrSLType type) { fType = type; }
259 
getTypeModifier()260     TypeModifier getTypeModifier() const { return fTypeModifier; }
setTypeModifier(TypeModifier type)261     void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
262 
263     /**
264      * Get the precision of the var
265      */
getPrecision()266     GrSLPrecision getPrecision() const { return fPrecision; }
267 
268     /**
269      * Set the precision of the var
270      */
setPrecision(GrSLPrecision p)271     void setPrecision(GrSLPrecision p) { fPrecision = p; }
272 
273     /**
274      * Appends to the layout qualifier
275      */
addLayoutQualifier(const char * layoutQualifier)276     void addLayoutQualifier(const char* layoutQualifier) {
277         if (!layoutQualifier || !strlen(layoutQualifier)) {
278             return;
279         }
280         if (fLayoutQualifier.isEmpty()) {
281             fLayoutQualifier = layoutQualifier;
282         } else {
283             fLayoutQualifier.appendf(", %s", layoutQualifier);
284         }
285     }
286 
287     void setImageStorageFormat(GrImageStorageFormat format);
288 
289     void setMemoryModel(GrSLMemoryModel);
290 
291     void setRestrict(GrSLRestrict);
292 
293     void setIOType(GrIOType);
294 
addModifier(const char * modifier)295     void addModifier(const char* modifier) {
296         if (modifier) {
297             fExtraModifiers.appendf("%s ", modifier);
298         }
299     }
300 
301     /**
302      * Write a declaration of this variable to out.
303      */
304     void appendDecl(const GrShaderCaps*, SkString* out) const;
305 
appendArrayAccess(int index,SkString * out)306     void appendArrayAccess(int index, SkString* out) const {
307         out->appendf("%s[%d]%s",
308                      this->getName().c_str(),
309                      index,
310                      fUseUniformFloatArrays ? "" : ".x");
311     }
312 
appendArrayAccess(const char * indexName,SkString * out)313     void appendArrayAccess(const char* indexName, SkString* out) const {
314         out->appendf("%s[%s]%s",
315                      this->getName().c_str(),
316                      indexName,
317                      fUseUniformFloatArrays ? "" : ".x");
318     }
319 
320 private:
321     GrSLType        fType;
322     TypeModifier    fTypeModifier;
323     int             fCount;
324     GrSLPrecision   fPrecision;
325     /// Work around driver bugs on some hardware that don't correctly
326     /// support uniform float []
327     bool            fUseUniformFloatArrays;
328 
329     SkString        fName;
330     SkString        fLayoutQualifier;
331     SkString        fExtraModifiers;
332 };
333 
334 #endif
335