blob: e8f491c5115758359cad928e03b0adb2f8c76658 [file] [log] [blame]
bsalomon@google.com4fa66942011-09-20 19:06:12 +00001/*
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#ifndef GrGLShaderVar_DEFINED
9#define GrGLShaderVar_DEFINED
10
bsalomon@google.com96399942012-02-13 14:39:16 +000011#include "GrGLContextInfo.h"
tomhudson@google.com086e5352011-12-08 14:44:10 +000012#include "GrGLSL.h"
bsalomon@google.comf0a104e2012-07-10 17:51:07 +000013#include "SkString.h"
bsalomon@google.com4fa66942011-09-20 19:06:12 +000014
tomhudson@google.comda668982011-12-07 15:06:29 +000015#define USE_UNIFORM_FLOAT_ARRAYS true
16
bsalomon@google.com4fa66942011-09-20 19:06:12 +000017/**
18 * Represents a variable in a shader
19 */
20class GrGLShaderVar {
21public:
22
bsalomon@google.com4fa66942011-09-20 19:06:12 +000023 /**
tomhudson@google.com086e5352011-12-08 14:44:10 +000024 * Early versions of GLSL have Varying and Attribute; those are later
25 * deprecated, but we still need to know whether a Varying variable
26 * should be treated as In or Out.
27 */
28 enum TypeModifier {
29 kNone_TypeModifier,
30 kOut_TypeModifier,
31 kIn_TypeModifier,
32 kUniform_TypeModifier,
33 kAttribute_TypeModifier
34 };
35
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000036 enum Precision {
37 kLow_Precision, // lowp
38 kMedium_Precision, // mediump
39 kHigh_Precision, // highp
40 kDefault_Precision, // Default for the current context. We make
41 // fragment shaders default to mediump on ES2
42 // because highp support is not guaranteed (and
43 // we haven't been motivated to test for it).
44 // Otherwise, highp.
45 };
46
tomhudson@google.com086e5352011-12-08 14:44:10 +000047 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +000048 * Defaults to a float with no precision specifier
49 */
50 GrGLShaderVar() {
tomhudson@google.com168e6342012-04-18 17:49:20 +000051 fType = kFloat_GrSLType;
tomhudson@google.com086e5352011-12-08 14:44:10 +000052 fTypeModifier = kNone_TypeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000053 fCount = kNonArray;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000054 fPrecision = kDefault_Precision;
tomhudson@google.comda668982011-12-07 15:06:29 +000055 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000056 }
57
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000058 GrGLShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray) {
59 GrAssert(kVoid_GrSLType != type);
60 fType = type;
61 fTypeModifier = kNone_TypeModifier;
62 fCount = arrayCount;
63 fPrecision = kDefault_Precision;
64 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
65 fName = name;
66 }
67
bsalomon@google.com4fa66942011-09-20 19:06:12 +000068 GrGLShaderVar(const GrGLShaderVar& var)
69 : fType(var.fType)
tomhudson@google.com086e5352011-12-08 14:44:10 +000070 , fTypeModifier(var.fTypeModifier)
bsalomon@google.com4fa66942011-09-20 19:06:12 +000071 , fName(var.fName)
72 , fCount(var.fCount)
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000073 , fPrecision(var.fPrecision)
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000074 , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {
75 GrAssert(kVoid_GrSLType != var.fType);
76 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +000077
78 /**
79 * Values for array count that have special meaning. We allow 1-sized arrays.
80 */
81 enum {
82 kNonArray = 0, // not an array
83 kUnsizedArray = -1, // an unsized array (declared with [])
84 };
85
86 /**
87 * Sets as a non-array.
88 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000089 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000090 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +000091 const SkString& name,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000092 Precision precision = kDefault_Precision,
tomhudson@google.comda668982011-12-07 15:06:29 +000093 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000094 GrAssert(kVoid_GrSLType != type);
bsalomon@google.com4fa66942011-09-20 19:06:12 +000095 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000096 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000097 fName = name;
98 fCount = kNonArray;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000099 fPrecision = precision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000100 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000101 }
102
103 /**
104 * Sets as a non-array.
105 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000106 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000107 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000108 const char* name,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000109 Precision precision = kDefault_Precision,
tomhudson@google.comda668982011-12-07 15:06:29 +0000110 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000111 GrAssert(kVoid_GrSLType != type);
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000112 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000113 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000114 fName = name;
115 fCount = kNonArray;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000116 fPrecision = precision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000117 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000118 }
119
120 /**
121 * Set all var options
122 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000123 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000124 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000125 const SkString& name,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000126 int count,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000127 Precision precision = kDefault_Precision,
tomhudson@google.comda668982011-12-07 15:06:29 +0000128 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000129 GrAssert(kVoid_GrSLType != type);
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000130 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000131 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000132 fName = name;
133 fCount = count;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000134 fPrecision = precision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000135 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000136 }
137
138 /**
139 * Set all var options
140 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000141 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000142 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000143 const char* name,
144 int count,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000145 Precision precision = kDefault_Precision,
tomhudson@google.comda668982011-12-07 15:06:29 +0000146 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000147 GrAssert(kVoid_GrSLType != type);
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000148 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000149 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000150 fName = name;
151 fCount = count;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000152 fPrecision = precision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000153 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000154 }
155
156 /**
157 * Is the var an array.
158 */
159 bool isArray() const { return kNonArray != fCount; }
160 /**
161 * Is this an unsized array, (i.e. declared with []).
162 */
163 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
164 /**
165 * Get the array length of the var.
166 */
167 int getArrayCount() const { return fCount; }
168 /**
169 * Set the array length of the var
170 */
171 void setArrayCount(int count) { fCount = count; }
172 /**
173 * Set to be a non-array.
174 */
175 void setNonArray() { fCount = kNonArray; }
176 /**
177 * Set to be an unsized array.
178 */
179 void setUnsizedArray() { fCount = kUnsizedArray; }
180
181 /**
182 * Access the var name as a writable string
183 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000184 SkString* accessName() { return &fName; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000185 /**
186 * Set the var name
187 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000188 void setName(const SkString& n) { fName = n; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000189 void setName(const char* n) { fName = n; }
bsalomon@google.com032b2212012-07-16 13:36:18 +0000190
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000191 /**
192 * Get the var name.
193 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000194 const SkString& getName() const { return fName; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000195
196 /**
bsalomon@google.com032b2212012-07-16 13:36:18 +0000197 * Shortcut for this->getName().c_str();
198 */
199 const char* c_str() const { return this->getName().c_str(); }
200
201 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000202 * Get the type of the var
203 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000204 GrSLType getType() const { return fType; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000205 /**
206 * Set the type of the var
207 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000208 void setType(GrSLType type) { fType = type; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000209
tomhudson@google.com086e5352011-12-08 14:44:10 +0000210 TypeModifier getTypeModifier() const { return fTypeModifier; }
211 void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
212
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000213 /**
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000214 * Get the precision of the var
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000215 */
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000216 Precision getPrecision() const { return fPrecision; }
217
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000218 /**
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000219 * Set the precision of the var
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000220 */
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000221 void setPrecision(Precision p) { fPrecision = p; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000222
223 /**
224 * Write a declaration of this variable to out.
225 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000226 void appendDecl(const GrGLContextInfo& gl, SkString* out) const {
tomhudson@google.com086e5352011-12-08 14:44:10 +0000227 if (this->getTypeModifier() != kNone_TypeModifier) {
bsalomon@google.com96399942012-02-13 14:39:16 +0000228 out->append(TypeModifierString(this->getTypeModifier(),
229 gl.glslGeneration()));
tomhudson@google.com086e5352011-12-08 14:44:10 +0000230 out->append(" ");
231 }
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000232 out->append(PrecisionString(fPrecision, gl.binding()));
tomhudson@google.com168e6342012-04-18 17:49:20 +0000233 GrSLType effectiveType = this->getType();
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000234 if (this->isArray()) {
235 if (this->isUnsizedArray()) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000236 out->appendf("%s %s[]",
237 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000238 this->getName().c_str());
239 } else {
240 GrAssert(this->getArrayCount() > 0);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000241 out->appendf("%s %s[%d]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000242 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000243 this->getName().c_str(),
244 this->getArrayCount());
245 }
246 } else {
247 out->appendf("%s %s",
tomhudson@google.comda668982011-12-07 15:06:29 +0000248 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000249 this->getName().c_str());
250 }
251 }
252
tomhudson@google.com168e6342012-04-18 17:49:20 +0000253 static const char* TypeString(GrSLType t) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000254 switch (t) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000255 case kVoid_GrSLType:
256 return "void";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000257 case kFloat_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000258 return "float";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000259 case kVec2f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000260 return "vec2";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000261 case kVec3f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000262 return "vec3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000263 case kVec4f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000264 return "vec4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000265 case kMat33f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000266 return "mat3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000267 case kMat44f_GrSLType:
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000268 return "mat4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000269 case kSampler2D_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000270 return "sampler2D";
271 default:
272 GrCrash("Unknown shader var type.");
273 return ""; // suppress warning
274 }
275 }
276
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000277 void appendArrayAccess(int index, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000278 out->appendf("%s[%d]%s",
279 this->getName().c_str(),
280 index,
281 fUseUniformFloatArrays ? "" : ".x");
282 }
283
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000284 void appendArrayAccess(const char* indexName, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000285 out->appendf("%s[%s]%s",
286 this->getName().c_str(),
287 indexName,
288 fUseUniformFloatArrays ? "" : ".x");
289 }
290
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000291private:
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000292 static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
tomhudson@google.com086e5352011-12-08 14:44:10 +0000293 switch (t) {
294 case kNone_TypeModifier:
295 return "";
296 case kOut_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000297 return k110_GrGLSLGeneration == gen ? "varying" : "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000298 case kIn_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000299 return k110_GrGLSLGeneration == gen ? "varying" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000300 case kUniform_TypeModifier:
301 return "uniform";
302 case kAttribute_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000303 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000304 default:
305 GrCrash("Unknown shader variable type modifier.");
306 return ""; // suppress warning
307 }
308 }
309
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000310 static const char* PrecisionString(Precision p, GrGLBinding binding) {
311 // Desktop GLSL has added precision qualifiers but they don't do anything.
312 if (kES2_GrGLBinding == binding) {
313 switch (p) {
314 case kLow_Precision:
315 return "lowp ";
316 case kMedium_Precision:
317 return "mediump ";
318 case kHigh_Precision:
319 return "highp ";
320 case kDefault_Precision:
321 return "";
322 default:
323 GrCrash("Unexpected precision type.");
324 }
325 }
326 return "";
327 }
328
329 GrSLType fType;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000330 TypeModifier fTypeModifier;
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000331 SkString fName;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000332 int fCount;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000333 Precision fPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000334 /// Work around driver bugs on some hardware that don't correctly
335 /// support uniform float []
336 bool fUseUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000337};
338
339#endif