blob: 0231d214d340fd3f92c5b51be477f466634b26b2 [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
58 GrGLShaderVar(const GrGLShaderVar& var)
59 : fType(var.fType)
tomhudson@google.com086e5352011-12-08 14:44:10 +000060 , fTypeModifier(var.fTypeModifier)
bsalomon@google.com4fa66942011-09-20 19:06:12 +000061 , fName(var.fName)
62 , fCount(var.fCount)
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000063 , fPrecision(var.fPrecision)
tomhudson@google.comda668982011-12-07 15:06:29 +000064 , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
bsalomon@google.com4fa66942011-09-20 19:06:12 +000065
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 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000077 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000078 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +000079 const SkString& name,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000080 Precision precision = kDefault_Precision,
tomhudson@google.comda668982011-12-07 15:06:29 +000081 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000082 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000083 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000084 fName = name;
85 fCount = kNonArray;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000086 fPrecision = precision;
tomhudson@google.comda668982011-12-07 15:06:29 +000087 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000088 }
89
90 /**
91 * Sets as a non-array.
92 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000093 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000094 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000095 const char* name,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000096 Precision precision = kDefault_Precision,
tomhudson@google.comda668982011-12-07 15:06:29 +000097 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000098 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000099 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000100 fName = name;
101 fCount = kNonArray;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000102 fPrecision = precision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000103 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000104 }
105
106 /**
107 * Set all var options
108 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000109 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000110 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000111 const SkString& name,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000112 int count,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000113 Precision precision = kDefault_Precision,
tomhudson@google.comda668982011-12-07 15:06:29 +0000114 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000115 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000116 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000117 fName = name;
118 fCount = count;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000119 fPrecision = precision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000120 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000121 }
122
123 /**
124 * Set all var options
125 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000126 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000127 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000128 const char* name,
129 int count,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000130 Precision precision = kDefault_Precision,
tomhudson@google.comda668982011-12-07 15:06:29 +0000131 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000132 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000133 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000134 fName = name;
135 fCount = count;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000136 fPrecision = precision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000137 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000138 }
139
140 /**
141 * Is the var an array.
142 */
143 bool isArray() const { return kNonArray != fCount; }
144 /**
145 * Is this an unsized array, (i.e. declared with []).
146 */
147 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
148 /**
149 * Get the array length of the var.
150 */
151 int getArrayCount() const { return fCount; }
152 /**
153 * Set the array length of the var
154 */
155 void setArrayCount(int count) { fCount = count; }
156 /**
157 * Set to be a non-array.
158 */
159 void setNonArray() { fCount = kNonArray; }
160 /**
161 * Set to be an unsized array.
162 */
163 void setUnsizedArray() { fCount = kUnsizedArray; }
164
165 /**
166 * Access the var name as a writable string
167 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000168 SkString* accessName() { return &fName; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000169 /**
170 * Set the var name
171 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000172 void setName(const SkString& n) { fName = n; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000173 void setName(const char* n) { fName = n; }
bsalomon@google.com032b2212012-07-16 13:36:18 +0000174
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000175 /**
176 * Get the var name.
177 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000178 const SkString& getName() const { return fName; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000179
180 /**
bsalomon@google.com032b2212012-07-16 13:36:18 +0000181 * Shortcut for this->getName().c_str();
182 */
183 const char* c_str() const { return this->getName().c_str(); }
184
185 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000186 * Get the type of the var
187 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000188 GrSLType getType() const { return fType; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000189 /**
190 * Set the type of the var
191 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000192 void setType(GrSLType type) { fType = type; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000193
tomhudson@google.com086e5352011-12-08 14:44:10 +0000194 TypeModifier getTypeModifier() const { return fTypeModifier; }
195 void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
196
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000197 /**
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000198 * Get the precision of the var
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000199 */
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000200 Precision getPrecision() const { return fPrecision; }
201
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000202 /**
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000203 * Set the precision of the var
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000204 */
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000205 void setPrecision(Precision p) { fPrecision = p; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000206
207 /**
208 * Write a declaration of this variable to out.
209 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000210 void appendDecl(const GrGLContextInfo& gl, SkString* out) const {
tomhudson@google.com086e5352011-12-08 14:44:10 +0000211 if (this->getTypeModifier() != kNone_TypeModifier) {
bsalomon@google.com96399942012-02-13 14:39:16 +0000212 out->append(TypeModifierString(this->getTypeModifier(),
213 gl.glslGeneration()));
tomhudson@google.com086e5352011-12-08 14:44:10 +0000214 out->append(" ");
215 }
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000216 out->append(PrecisionString(fPrecision, gl.binding()));
tomhudson@google.com168e6342012-04-18 17:49:20 +0000217 GrSLType effectiveType = this->getType();
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000218 if (this->isArray()) {
219 if (this->isUnsizedArray()) {
220 out->appendf("%s %s[]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000221 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000222 this->getName().c_str());
223 } else {
224 GrAssert(this->getArrayCount() > 0);
225 out->appendf("%s %s[%d]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000226 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000227 this->getName().c_str(),
228 this->getArrayCount());
229 }
230 } else {
231 out->appendf("%s %s",
tomhudson@google.comda668982011-12-07 15:06:29 +0000232 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000233 this->getName().c_str());
234 }
tomhudson@google.com086e5352011-12-08 14:44:10 +0000235 out->append(";\n");
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000236 }
237
tomhudson@google.com168e6342012-04-18 17:49:20 +0000238 static const char* TypeString(GrSLType t) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000239 switch (t) {
tomhudson@google.com168e6342012-04-18 17:49:20 +0000240 case kFloat_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000241 return "float";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000242 case kVec2f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000243 return "vec2";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000244 case kVec3f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000245 return "vec3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000246 case kVec4f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000247 return "vec4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000248 case kMat33f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000249 return "mat3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000250 case kMat44f_GrSLType:
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000251 return "mat4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000252 case kSampler2D_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000253 return "sampler2D";
254 default:
255 GrCrash("Unknown shader var type.");
256 return ""; // suppress warning
257 }
258 }
259
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000260 void appendArrayAccess(int index, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000261 out->appendf("%s[%d]%s",
262 this->getName().c_str(),
263 index,
264 fUseUniformFloatArrays ? "" : ".x");
265 }
266
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000267 void appendArrayAccess(const char* indexName, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000268 out->appendf("%s[%s]%s",
269 this->getName().c_str(),
270 indexName,
271 fUseUniformFloatArrays ? "" : ".x");
272 }
273
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000274private:
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000275 static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
tomhudson@google.com086e5352011-12-08 14:44:10 +0000276 switch (t) {
277 case kNone_TypeModifier:
278 return "";
279 case kOut_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000280 return k110_GrGLSLGeneration == gen ? "varying" : "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000281 case kIn_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000282 return k110_GrGLSLGeneration == gen ? "varying" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000283 case kUniform_TypeModifier:
284 return "uniform";
285 case kAttribute_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000286 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000287 default:
288 GrCrash("Unknown shader variable type modifier.");
289 return ""; // suppress warning
290 }
291 }
292
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000293 static const char* PrecisionString(Precision p, GrGLBinding binding) {
294 // Desktop GLSL has added precision qualifiers but they don't do anything.
295 if (kES2_GrGLBinding == binding) {
296 switch (p) {
297 case kLow_Precision:
298 return "lowp ";
299 case kMedium_Precision:
300 return "mediump ";
301 case kHigh_Precision:
302 return "highp ";
303 case kDefault_Precision:
304 return "";
305 default:
306 GrCrash("Unexpected precision type.");
307 }
308 }
309 return "";
310 }
311
312 GrSLType fType;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000313 TypeModifier fTypeModifier;
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000314 SkString fName;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000315 int fCount;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000316 Precision fPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000317 /// Work around driver bugs on some hardware that don't correctly
318 /// support uniform float []
319 bool fUseUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000320};
321
322#endif