blob: ecf0b479ae778f6b43f13c4d6e94ac9080d12e62 [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
robertphillips@google.com6177e692013-02-28 20:16:25 +000011#include "GrGLContext.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.com5fa21072012-10-25 14:57:46 +000048 * See GL_ARB_fragment_coord_conventions.
49 */
50 enum Origin {
51 kDefault_Origin, // when set to kDefault the origin field is ignored.
52 kUpperLeft_Origin, // only used to declare vec4 in gl_FragCoord.
53 };
54
55 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +000056 * Defaults to a float with no precision specifier
57 */
58 GrGLShaderVar() {
tomhudson@google.com168e6342012-04-18 17:49:20 +000059 fType = kFloat_GrSLType;
tomhudson@google.com086e5352011-12-08 14:44:10 +000060 fTypeModifier = kNone_TypeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000061 fCount = kNonArray;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000062 fPrecision = kDefault_Precision;
bsalomon@google.com5fa21072012-10-25 14:57:46 +000063 fOrigin = kDefault_Origin;
tomhudson@google.comda668982011-12-07 15:06:29 +000064 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000065 }
66
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000067 GrGLShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray) {
68 GrAssert(kVoid_GrSLType != type);
69 fType = type;
70 fTypeModifier = kNone_TypeModifier;
71 fCount = arrayCount;
72 fPrecision = kDefault_Precision;
bsalomon@google.com5fa21072012-10-25 14:57:46 +000073 fOrigin = kDefault_Origin;
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000074 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
75 fName = name;
76 }
77
bsalomon@google.com4fa66942011-09-20 19:06:12 +000078 GrGLShaderVar(const GrGLShaderVar& var)
79 : fType(var.fType)
tomhudson@google.com086e5352011-12-08 14:44:10 +000080 , fTypeModifier(var.fTypeModifier)
bsalomon@google.com4fa66942011-09-20 19:06:12 +000081 , fName(var.fName)
82 , fCount(var.fCount)
bsalomon@google.comd7727ce2012-07-12 16:40:03 +000083 , fPrecision(var.fPrecision)
bsalomon@google.comb7f9a862012-10-25 19:35:05 +000084 , fOrigin(var.fOrigin)
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +000085 , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {
86 GrAssert(kVoid_GrSLType != var.fType);
87 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +000088
89 /**
90 * Values for array count that have special meaning. We allow 1-sized arrays.
91 */
92 enum {
93 kNonArray = 0, // not an array
94 kUnsizedArray = -1, // an unsized array (declared with [])
95 };
96
97 /**
98 * Sets as a non-array.
99 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000100 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000101 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000102 const SkString& name,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000103 Precision precision = kDefault_Precision,
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000104 Origin origin = kDefault_Origin,
tomhudson@google.comda668982011-12-07 15:06:29 +0000105 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000106 GrAssert(kVoid_GrSLType != type);
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000107 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000108 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000109 fName = name;
110 fCount = kNonArray;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000111 fPrecision = precision;
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000112 fOrigin = origin;
tomhudson@google.comda668982011-12-07 15:06:29 +0000113 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000114 }
115
116 /**
117 * Sets as a non-array.
118 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000119 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000120 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000121 const char* name,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000122 Precision precision = kDefault_Precision,
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000123 Origin origin = kDefault_Origin,
tomhudson@google.comda668982011-12-07 15:06:29 +0000124 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000125 GrAssert(kVoid_GrSLType != type);
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000126 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000127 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000128 fName = name;
129 fCount = kNonArray;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000130 fPrecision = precision;
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000131 fOrigin = origin;
tomhudson@google.comda668982011-12-07 15:06:29 +0000132 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000133 }
134
135 /**
136 * Set all var options
137 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000138 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000139 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000140 const SkString& name,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000141 int count,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000142 Precision precision = kDefault_Precision,
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000143 Origin origin = kDefault_Origin,
tomhudson@google.comda668982011-12-07 15:06:29 +0000144 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000145 GrAssert(kVoid_GrSLType != type);
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000146 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000147 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000148 fName = name;
149 fCount = count;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000150 fPrecision = precision;
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000151 fOrigin = origin;
tomhudson@google.comda668982011-12-07 15:06:29 +0000152 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000153 }
154
155 /**
156 * Set all var options
157 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000158 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000159 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000160 const char* name,
161 int count,
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000162 Precision precision = kDefault_Precision,
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000163 Origin origin = kDefault_Origin,
tomhudson@google.comda668982011-12-07 15:06:29 +0000164 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000165 GrAssert(kVoid_GrSLType != type);
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000166 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000167 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000168 fName = name;
169 fCount = count;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000170 fPrecision = precision;
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000171 fOrigin = origin;
tomhudson@google.comda668982011-12-07 15:06:29 +0000172 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000173 }
174
175 /**
176 * Is the var an array.
177 */
178 bool isArray() const { return kNonArray != fCount; }
179 /**
180 * Is this an unsized array, (i.e. declared with []).
181 */
182 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
183 /**
184 * Get the array length of the var.
185 */
186 int getArrayCount() const { return fCount; }
187 /**
188 * Set the array length of the var
189 */
190 void setArrayCount(int count) { fCount = count; }
191 /**
192 * Set to be a non-array.
193 */
194 void setNonArray() { fCount = kNonArray; }
195 /**
196 * Set to be an unsized array.
197 */
198 void setUnsizedArray() { fCount = kUnsizedArray; }
199
200 /**
201 * Access the var name as a writable string
202 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000203 SkString* accessName() { return &fName; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000204 /**
205 * Set the var name
206 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000207 void setName(const SkString& n) { fName = n; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000208 void setName(const char* n) { fName = n; }
bsalomon@google.com032b2212012-07-16 13:36:18 +0000209
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000210 /**
211 * Get the var name.
212 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000213 const SkString& getName() const { return fName; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000214
215 /**
bsalomon@google.com032b2212012-07-16 13:36:18 +0000216 * Shortcut for this->getName().c_str();
217 */
218 const char* c_str() const { return this->getName().c_str(); }
219
220 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000221 * Get the type of the var
222 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000223 GrSLType getType() const { return fType; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000224 /**
225 * Set the type of the var
226 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000227 void setType(GrSLType type) { fType = type; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000228
tomhudson@google.com086e5352011-12-08 14:44:10 +0000229 TypeModifier getTypeModifier() const { return fTypeModifier; }
230 void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
231
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000232 /**
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000233 * Get the precision of the var
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000234 */
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000235 Precision getPrecision() const { return fPrecision; }
236
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000237 /**
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000238 * Set the precision of the var
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000239 */
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000240 void setPrecision(Precision p) { fPrecision = p; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000241
242 /**
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000243 * Get the origin of the var
244 */
245 Origin getOrigin() const { return fOrigin; }
246
247 /**
248 * Set the origin of the var
249 */
250 void setOrigin(Origin origin) { fOrigin = origin; }
251
252 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000253 * Write a declaration of this variable to out.
254 */
robertphillips@google.com6177e692013-02-28 20:16:25 +0000255 void appendDecl(const GrGLContextInfo& ctxInfo, SkString* out) const {
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000256 if (kUpperLeft_Origin == fOrigin) {
257 // this is the only place where we specify a layout modifier. If we use other layout
258 // modifiers in the future then they should be placed in a list.
259 out->append("layout(origin_upper_left) ");
260 }
tomhudson@google.com086e5352011-12-08 14:44:10 +0000261 if (this->getTypeModifier() != kNone_TypeModifier) {
bsalomon@google.com96399942012-02-13 14:39:16 +0000262 out->append(TypeModifierString(this->getTypeModifier(),
robertphillips@google.com6177e692013-02-28 20:16:25 +0000263 ctxInfo.glslGeneration()));
tomhudson@google.com086e5352011-12-08 14:44:10 +0000264 out->append(" ");
265 }
robertphillips@google.com6177e692013-02-28 20:16:25 +0000266 out->append(PrecisionString(fPrecision, ctxInfo.binding()));
tomhudson@google.com168e6342012-04-18 17:49:20 +0000267 GrSLType effectiveType = this->getType();
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000268 if (this->isArray()) {
269 if (this->isUnsizedArray()) {
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000270 out->appendf("%s %s[]",
271 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000272 this->getName().c_str());
273 } else {
274 GrAssert(this->getArrayCount() > 0);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000275 out->appendf("%s %s[%d]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000276 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000277 this->getName().c_str(),
278 this->getArrayCount());
279 }
280 } else {
281 out->appendf("%s %s",
tomhudson@google.comda668982011-12-07 15:06:29 +0000282 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000283 this->getName().c_str());
284 }
285 }
286
tomhudson@google.com168e6342012-04-18 17:49:20 +0000287 static const char* TypeString(GrSLType t) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000288 switch (t) {
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000289 case kVoid_GrSLType:
290 return "void";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000291 case kFloat_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000292 return "float";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000293 case kVec2f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000294 return "vec2";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000295 case kVec3f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000296 return "vec3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000297 case kVec4f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000298 return "vec4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000299 case kMat33f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000300 return "mat3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000301 case kMat44f_GrSLType:
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000302 return "mat4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000303 case kSampler2D_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000304 return "sampler2D";
305 default:
306 GrCrash("Unknown shader var type.");
307 return ""; // suppress warning
308 }
309 }
310
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000311 void appendArrayAccess(int index, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000312 out->appendf("%s[%d]%s",
313 this->getName().c_str(),
314 index,
315 fUseUniformFloatArrays ? "" : ".x");
316 }
317
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000318 void appendArrayAccess(const char* indexName, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000319 out->appendf("%s[%s]%s",
320 this->getName().c_str(),
321 indexName,
322 fUseUniformFloatArrays ? "" : ".x");
323 }
324
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000325private:
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000326 static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
tomhudson@google.com086e5352011-12-08 14:44:10 +0000327 switch (t) {
328 case kNone_TypeModifier:
329 return "";
330 case kOut_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000331 return k110_GrGLSLGeneration == gen ? "varying" : "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000332 case kIn_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000333 return k110_GrGLSLGeneration == gen ? "varying" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000334 case kUniform_TypeModifier:
335 return "uniform";
336 case kAttribute_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000337 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000338 default:
339 GrCrash("Unknown shader variable type modifier.");
340 return ""; // suppress warning
341 }
342 }
343
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000344 static const char* PrecisionString(Precision p, GrGLBinding binding) {
345 // Desktop GLSL has added precision qualifiers but they don't do anything.
346 if (kES2_GrGLBinding == binding) {
347 switch (p) {
348 case kLow_Precision:
349 return "lowp ";
350 case kMedium_Precision:
351 return "mediump ";
352 case kHigh_Precision:
353 return "highp ";
354 case kDefault_Precision:
355 return "";
356 default:
357 GrCrash("Unexpected precision type.");
358 }
359 }
360 return "";
361 }
362
363 GrSLType fType;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000364 TypeModifier fTypeModifier;
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000365 SkString fName;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000366 int fCount;
bsalomon@google.comd7727ce2012-07-12 16:40:03 +0000367 Precision fPrecision;
bsalomon@google.com5fa21072012-10-25 14:57:46 +0000368 Origin fOrigin;
tomhudson@google.comda668982011-12-07 15:06:29 +0000369 /// Work around driver bugs on some hardware that don't correctly
370 /// support uniform float []
371 bool fUseUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000372};
373
374#endif