blob: aaae107c19cafc0754d5c4e05de3c9b673797515 [file] [log] [blame]
joshualitt249af152014-09-15 11:41:13 -07001/*
Brian Salomon99938a82016-11-21 13:41:08 -05002 * Copyright 2016 Google Inc.
joshualitt249af152014-09-15 11:41:13 -07003 *
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
joshualitt249af152014-09-15 11:41:13 -070011#include "SkString.h"
Brian Salomon99938a82016-11-21 13:41:08 -050012#include "GrTypesPriv.h"
joshualitt249af152014-09-15 11:41:13 -070013
Brian Salomon99938a82016-11-21 13:41:08 -050014class GrGLSLCaps;
15
16#define USE_UNIFORM_FLOAT_ARRAYS true
17
18/**
19 * Represents a variable in a shader
20 */
joshualitt249af152014-09-15 11:41:13 -070021class GrShaderVar {
22public:
joshualitt249af152014-09-15 11:41:13 -070023 enum TypeModifier {
24 kNone_TypeModifier,
25 kOut_TypeModifier,
26 kIn_TypeModifier,
27 kInOut_TypeModifier,
28 kUniform_TypeModifier,
joshualitt249af152014-09-15 11:41:13 -070029 };
30
joshualitt249af152014-09-15 11:41:13 -070031 /**
Brian Salomon99938a82016-11-21 13:41:08 -050032 * Values for array count that have special meaning. We allow 1-sized arrays.git
joshualitt249af152014-09-15 11:41:13 -070033 */
34 enum {
35 kNonArray = 0, // not an array
36 kUnsizedArray = -1, // an unsized array (declared with [])
37 };
38
Brian Salomon99938a82016-11-21 13:41:08 -050039 /**
40 * Defaults to a non-arry float with no precision specifier, type modifier, or layout qualifier.
41 */
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)
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)
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)
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)
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
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 */
joshualitt249af152014-09-15 11:41:13 -0700111 void set(GrSLType type,
joshualitt249af152014-09-15 11:41:13 -0700112 const SkString& name,
robertphillips46d36f02015-01-18 08:14:14 -0800113 TypeModifier typeModifier = kNone_TypeModifier,
114 GrSLPrecision precision = kDefault_GrSLPrecision,
Brian Salomon99938a82016-11-21 13:41:08 -0500115 const char* layoutQualifier = nullptr,
116 const char* extraModifiers = nullptr,
117 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
joshualitt249af152014-09-15 11:41:13 -0700118 SkASSERT(kVoid_GrSLType != type);
Brian Salomon99938a82016-11-21 13:41:08 -0500119 SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeAcceptsPrecision(type));
joshualitt249af152014-09-15 11:41:13 -0700120 fType = type;
121 fTypeModifier = typeModifier;
122 fName = name;
Brian Salomon99938a82016-11-21 13:41:08 -0500123 fCount = kNonArray;
joshualitt249af152014-09-15 11:41:13 -0700124 fPrecision = precision;
Brian Salomon99938a82016-11-21 13:41:08 -0500125 fLayoutQualifier = layoutQualifier;
126 if (extraModifiers) {
127 fExtraModifiers.printf("%s ", extraModifiers);
128 }
129 fUseUniformFloatArrays = useUniformFloatArrays;
joshualitt249af152014-09-15 11:41:13 -0700130 }
131
Brian Salomon99938a82016-11-21 13:41:08 -0500132 /**
133 * Sets as a non-array.
134 */
joshualitt249af152014-09-15 11:41:13 -0700135 void set(GrSLType type,
joshualitt249af152014-09-15 11:41:13 -0700136 const char* name,
robertphillips46d36f02015-01-18 08:14:14 -0800137 TypeModifier typeModifier = kNone_TypeModifier,
138 GrSLPrecision precision = kDefault_GrSLPrecision,
Brian Salomon99938a82016-11-21 13:41:08 -0500139 const char* layoutQualifier = nullptr,
140 const char* extraModifiers = nullptr,
141 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
joshualitt249af152014-09-15 11:41:13 -0700142 SkASSERT(kVoid_GrSLType != type);
Brian Salomon99938a82016-11-21 13:41:08 -0500143 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));
joshualitt249af152014-09-15 11:41:13 -0700169 fType = type;
170 fTypeModifier = typeModifier;
171 fName = name;
172 fCount = count;
173 fPrecision = precision;
Brian Salomon99938a82016-11-21 13:41:08 -0500174 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;
joshualitt249af152014-09-15 11:41:13 -0700204 }
205
206 /**
207 * Is the var an array.
208 */
209 bool isArray() const { return kNonArray != fCount; }
210 /**
211 * Is this an unsized array, (i.e. declared with []).
212 */
213 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
214 /**
215 * Get the array length of the var.
216 */
217 int getArrayCount() const { return fCount; }
218 /**
219 * Set the array length of the var
220 */
221 void setArrayCount(int count) { fCount = count; }
222 /**
223 * Set to be a non-array.
224 */
225 void setNonArray() { fCount = kNonArray; }
226 /**
227 * Set to be an unsized array.
228 */
229 void setUnsizedArray() { fCount = kUnsizedArray; }
230
231 /**
232 * Access the var name as a writable string
233 */
234 SkString* accessName() { return &fName; }
235 /**
236 * Set the var name
237 */
238 void setName(const SkString& n) { fName = n; }
239 void setName(const char* n) { fName = n; }
240
241 /**
242 * Get the var name.
243 */
244 const SkString& getName() const { return fName; }
245
246 /**
247 * Shortcut for this->getName().c_str();
248 */
249 const char* c_str() const { return this->getName().c_str(); }
250
251 /**
252 * Get the type of the var
253 */
254 GrSLType getType() const { return fType; }
255 /**
256 * Set the type of the var
257 */
258 void setType(GrSLType type) { fType = type; }
259
260 TypeModifier getTypeModifier() const { return fTypeModifier; }
261 void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
262
263 /**
264 * Get the precision of the var
265 */
bsalomonc0bd6482014-12-09 10:04:14 -0800266 GrSLPrecision getPrecision() const { return fPrecision; }
joshualitt249af152014-09-15 11:41:13 -0700267
268 /**
269 * Set the precision of the var
270 */
bsalomonc0bd6482014-12-09 10:04:14 -0800271 void setPrecision(GrSLPrecision p) { fPrecision = p; }
joshualitt249af152014-09-15 11:41:13 -0700272
Brian Salomon99938a82016-11-21 13:41:08 -0500273 /**
Brian Salomon60397682016-11-22 15:06:46 -0500274 * Appends to the layout qualifier
Brian Salomon99938a82016-11-21 13:41:08 -0500275 */
Brian Salomon60397682016-11-22 15:06:46 -0500276 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 }
Brian Salomon99938a82016-11-21 13:41:08 -0500285 }
286
287 void addModifier(const char* modifier) {
288 if (modifier) {
289 fExtraModifiers.appendf("%s ", modifier);
290 }
291 }
292
293 /**
294 * Write a declaration of this variable to out.
295 */
296 void appendDecl(const GrGLSLCaps* glslCaps, SkString* out) const;
297
298 void appendArrayAccess(int index, SkString* out) const {
299 out->appendf("%s[%d]%s",
300 this->getName().c_str(),
301 index,
302 fUseUniformFloatArrays ? "" : ".x");
303 }
304
305 void appendArrayAccess(const char* indexName, SkString* out) const {
306 out->appendf("%s[%s]%s",
307 this->getName().c_str(),
308 indexName,
309 fUseUniformFloatArrays ? "" : ".x");
310 }
311
312private:
313 static const char* TypeModifierString(TypeModifier t) {
314 switch (t) {
315 case kNone_TypeModifier:
316 return "";
317 case kIn_TypeModifier:
318 return "in";
319 case kInOut_TypeModifier:
320 return "inout";
321 case kOut_TypeModifier:
322 return "out";
323 case kUniform_TypeModifier:
324 return "uniform";
325 }
326 SkFAIL("Unknown shader variable type modifier.");
327 return ""; // suppress warning
328 }
329
joshualitt249af152014-09-15 11:41:13 -0700330 GrSLType fType;
331 TypeModifier fTypeModifier;
joshualitt249af152014-09-15 11:41:13 -0700332 int fCount;
bsalomonc0bd6482014-12-09 10:04:14 -0800333 GrSLPrecision fPrecision;
Brian Salomon99938a82016-11-21 13:41:08 -0500334 /// Work around driver bugs on some hardware that don't correctly
335 /// support uniform float []
336 bool fUseUniformFloatArrays;
337
338 SkString fName;
339 SkString fLayoutQualifier;
340 SkString fExtraModifiers;
joshualitt249af152014-09-15 11:41:13 -0700341};
342
Brian Salomon99938a82016-11-21 13:41:08 -0500343 #endif