blob: 7be417dec335c3d8a7f8a5ef3c475e96db9f7986 [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
36 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +000037 * Defaults to a float with no precision specifier
38 */
39 GrGLShaderVar() {
tomhudson@google.com168e6342012-04-18 17:49:20 +000040 fType = kFloat_GrSLType;
tomhudson@google.com086e5352011-12-08 14:44:10 +000041 fTypeModifier = kNone_TypeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000042 fCount = kNonArray;
43 fEmitPrecision = false;
tomhudson@google.comda668982011-12-07 15:06:29 +000044 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000045 }
46
47 GrGLShaderVar(const GrGLShaderVar& var)
48 : fType(var.fType)
tomhudson@google.com086e5352011-12-08 14:44:10 +000049 , fTypeModifier(var.fTypeModifier)
bsalomon@google.com4fa66942011-09-20 19:06:12 +000050 , fName(var.fName)
51 , fCount(var.fCount)
tomhudson@google.comda668982011-12-07 15:06:29 +000052 , fEmitPrecision(var.fEmitPrecision)
53 , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
bsalomon@google.com4fa66942011-09-20 19:06:12 +000054
55 /**
56 * Values for array count that have special meaning. We allow 1-sized arrays.
57 */
58 enum {
59 kNonArray = 0, // not an array
60 kUnsizedArray = -1, // an unsized array (declared with [])
61 };
62
63 /**
64 * Sets as a non-array.
65 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000066 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000067 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +000068 const SkString& name,
tomhudson@google.comda668982011-12-07 15:06:29 +000069 bool emitPrecision = false,
70 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000071 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000072 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000073 fName = name;
74 fCount = kNonArray;
75 fEmitPrecision = emitPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +000076 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000077 }
78
79 /**
80 * Sets as a non-array.
81 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000082 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000083 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000084 const char* name,
tomhudson@google.comda668982011-12-07 15:06:29 +000085 bool specifyPrecision = false,
86 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000087 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000088 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000089 fName = name;
90 fCount = kNonArray;
91 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +000092 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000093 }
94
95 /**
96 * Set all var options
97 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000098 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000099 TypeModifier typeModifier,
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000100 const SkString& name,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000101 int count,
tomhudson@google.comda668982011-12-07 15:06:29 +0000102 bool specifyPrecision = false,
103 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000104 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000105 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000106 fName = name;
107 fCount = count;
108 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000109 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000110 }
111
112 /**
113 * Set all var options
114 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000115 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000116 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000117 const char* name,
118 int count,
tomhudson@google.comda668982011-12-07 15:06:29 +0000119 bool specifyPrecision = false,
120 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000121 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000122 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000123 fName = name;
124 fCount = count;
125 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000126 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000127 }
128
129 /**
130 * Is the var an array.
131 */
132 bool isArray() const { return kNonArray != fCount; }
133 /**
134 * Is this an unsized array, (i.e. declared with []).
135 */
136 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
137 /**
138 * Get the array length of the var.
139 */
140 int getArrayCount() const { return fCount; }
141 /**
142 * Set the array length of the var
143 */
144 void setArrayCount(int count) { fCount = count; }
145 /**
146 * Set to be a non-array.
147 */
148 void setNonArray() { fCount = kNonArray; }
149 /**
150 * Set to be an unsized array.
151 */
152 void setUnsizedArray() { fCount = kUnsizedArray; }
153
154 /**
155 * Access the var name as a writable string
156 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000157 SkString* accessName() { return &fName; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000158 /**
159 * Set the var name
160 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000161 void setName(const SkString& n) { fName = n; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000162 void setName(const char* n) { fName = n; }
163 /**
164 * Get the var name.
165 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000166 const SkString& getName() const { return fName; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000167
168 /**
169 * Get the type of the var
170 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000171 GrSLType getType() const { return fType; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000172 /**
173 * Set the type of the var
174 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000175 void setType(GrSLType type) { fType = type; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000176
tomhudson@google.com086e5352011-12-08 14:44:10 +0000177 TypeModifier getTypeModifier() const { return fTypeModifier; }
178 void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
179
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000180 /**
181 * Must the variable declaration emit a precision specifier
182 */
183 bool emitsPrecision() const { return fEmitPrecision; }
184 /**
185 * Specify whether the declaration should specify precision
186 */
187 void setEmitPrecision(bool p) { fEmitPrecision = p; }
188
189 /**
190 * Write a declaration of this variable to out.
191 */
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000192 void appendDecl(const GrGLContextInfo& gl, SkString* out) const {
tomhudson@google.com086e5352011-12-08 14:44:10 +0000193 if (this->getTypeModifier() != kNone_TypeModifier) {
bsalomon@google.com96399942012-02-13 14:39:16 +0000194 out->append(TypeModifierString(this->getTypeModifier(),
195 gl.glslGeneration()));
tomhudson@google.com086e5352011-12-08 14:44:10 +0000196 out->append(" ");
197 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000198 if (this->emitsPrecision()) {
bsalomon@google.com96399942012-02-13 14:39:16 +0000199 out->append(GrGetGLSLVarPrecisionDeclType(gl.binding()));
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000200 out->append(" ");
201 }
tomhudson@google.com168e6342012-04-18 17:49:20 +0000202 GrSLType effectiveType = this->getType();
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000203 if (this->isArray()) {
204 if (this->isUnsizedArray()) {
205 out->appendf("%s %s[]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000206 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000207 this->getName().c_str());
208 } else {
209 GrAssert(this->getArrayCount() > 0);
210 out->appendf("%s %s[%d]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000211 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000212 this->getName().c_str(),
213 this->getArrayCount());
214 }
215 } else {
216 out->appendf("%s %s",
tomhudson@google.comda668982011-12-07 15:06:29 +0000217 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000218 this->getName().c_str());
219 }
tomhudson@google.com086e5352011-12-08 14:44:10 +0000220 out->append(";\n");
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000221 }
222
tomhudson@google.com168e6342012-04-18 17:49:20 +0000223 static const char* TypeString(GrSLType t) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000224 switch (t) {
tomhudson@google.com168e6342012-04-18 17:49:20 +0000225 case kFloat_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000226 return "float";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000227 case kVec2f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000228 return "vec2";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000229 case kVec3f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000230 return "vec3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000231 case kVec4f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000232 return "vec4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000233 case kMat33f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000234 return "mat3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000235 case kMat44f_GrSLType:
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000236 return "mat4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000237 case kSampler2D_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000238 return "sampler2D";
239 default:
240 GrCrash("Unknown shader var type.");
241 return ""; // suppress warning
242 }
243 }
244
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000245 void appendArrayAccess(int index, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000246 out->appendf("%s[%d]%s",
247 this->getName().c_str(),
248 index,
249 fUseUniformFloatArrays ? "" : ".x");
250 }
251
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000252 void appendArrayAccess(const char* indexName, SkString* out) const {
tomhudson@google.comda668982011-12-07 15:06:29 +0000253 out->appendf("%s[%s]%s",
254 this->getName().c_str(),
255 indexName,
256 fUseUniformFloatArrays ? "" : ".x");
257 }
258
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000259private:
tomhudson@google.com086e5352011-12-08 14:44:10 +0000260 static const char* TypeModifierString(TypeModifier t,
261 GrGLSLGeneration gen) {
262 switch (t) {
263 case kNone_TypeModifier:
264 return "";
265 case kOut_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000266 return k110_GrGLSLGeneration == gen ? "varying" : "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000267 case kIn_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000268 return k110_GrGLSLGeneration == gen ? "varying" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000269 case kUniform_TypeModifier:
270 return "uniform";
271 case kAttribute_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000272 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000273 default:
274 GrCrash("Unknown shader variable type modifier.");
275 return ""; // suppress warning
276 }
277 }
278
tomhudson@google.com168e6342012-04-18 17:49:20 +0000279 GrSLType fType;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000280 TypeModifier fTypeModifier;
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000281 SkString fName;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000282 int fCount;
283 bool fEmitPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000284 /// Work around driver bugs on some hardware that don't correctly
285 /// support uniform float []
286 bool fUseUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000287};
288
289#endif