blob: 5f1ba03efb7b8ca4c120d03f0ea03a276da22a5f [file] [log] [blame]
bsalomon@google.com4fa66942011-09-20 19:06:12 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#ifndef GrGLShaderVar_DEFINED
10#define GrGLShaderVar_DEFINED
11
12#include "GrGLInterface.h"
tomhudson@google.com086e5352011-12-08 14:44:10 +000013#include "GrGLSL.h"
bsalomon@google.comffa11bb2011-10-20 13:43:13 +000014#include "GrStringBuilder.h"
bsalomon@google.com4fa66942011-09-20 19:06:12 +000015
tomhudson@google.comda668982011-12-07 15:06:29 +000016#define USE_UNIFORM_FLOAT_ARRAYS true
17
bsalomon@google.com4fa66942011-09-20 19:06:12 +000018/**
19 * Represents a variable in a shader
20 */
21class GrGLShaderVar {
22public:
23
24 enum Type {
25 kFloat_Type,
26 kVec2f_Type,
27 kVec3f_Type,
28 kVec4f_Type,
29 kMat33f_Type,
30 kSampler2D_Type,
31 };
32
33 /**
tomhudson@google.com086e5352011-12-08 14:44:10 +000034 * Early versions of GLSL have Varying and Attribute; those are later
35 * deprecated, but we still need to know whether a Varying variable
36 * should be treated as In or Out.
37 */
38 enum TypeModifier {
39 kNone_TypeModifier,
40 kOut_TypeModifier,
41 kIn_TypeModifier,
42 kUniform_TypeModifier,
43 kAttribute_TypeModifier
44 };
45
46 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +000047 * Defaults to a float with no precision specifier
48 */
49 GrGLShaderVar() {
50 fType = kFloat_Type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000051 fTypeModifier = kNone_TypeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000052 fCount = kNonArray;
53 fEmitPrecision = false;
tomhudson@google.comda668982011-12-07 15:06:29 +000054 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000055 }
56
57 GrGLShaderVar(const GrGLShaderVar& var)
58 : fType(var.fType)
tomhudson@google.com086e5352011-12-08 14:44:10 +000059 , fTypeModifier(var.fTypeModifier)
bsalomon@google.com4fa66942011-09-20 19:06:12 +000060 , fName(var.fName)
61 , fCount(var.fCount)
tomhudson@google.comda668982011-12-07 15:06:29 +000062 , fEmitPrecision(var.fEmitPrecision)
63 , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
bsalomon@google.com4fa66942011-09-20 19:06:12 +000064
65 /**
66 * Values for array count that have special meaning. We allow 1-sized arrays.
67 */
68 enum {
69 kNonArray = 0, // not an array
70 kUnsizedArray = -1, // an unsized array (declared with [])
71 };
72
73 /**
74 * Sets as a non-array.
75 */
76 void set(Type type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000077 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000078 const GrStringBuilder& name,
tomhudson@google.comda668982011-12-07 15:06:29 +000079 bool emitPrecision = false,
80 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000081 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000082 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000083 fName = name;
84 fCount = kNonArray;
85 fEmitPrecision = emitPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +000086 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000087 }
88
89 /**
90 * Sets as a non-array.
91 */
92 void set(Type type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000093 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000094 const char* name,
tomhudson@google.comda668982011-12-07 15:06:29 +000095 bool specifyPrecision = false,
96 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000097 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000098 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000099 fName = name;
100 fCount = kNonArray;
101 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000102 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000103 }
104
105 /**
106 * Set all var options
107 */
108 void set(Type type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000109 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000110 const GrStringBuilder& name,
111 int count,
tomhudson@google.comda668982011-12-07 15:06:29 +0000112 bool specifyPrecision = false,
113 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000114 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000115 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000116 fName = name;
117 fCount = count;
118 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000119 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000120 }
121
122 /**
123 * Set all var options
124 */
125 void set(Type type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000126 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000127 const char* name,
128 int count,
tomhudson@google.comda668982011-12-07 15:06:29 +0000129 bool specifyPrecision = false,
130 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000131 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000132 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000133 fName = name;
134 fCount = count;
135 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000136 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000137 }
138
139 /**
140 * Is the var an array.
141 */
142 bool isArray() const { return kNonArray != fCount; }
143 /**
144 * Is this an unsized array, (i.e. declared with []).
145 */
146 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
147 /**
148 * Get the array length of the var.
149 */
150 int getArrayCount() const { return fCount; }
151 /**
152 * Set the array length of the var
153 */
154 void setArrayCount(int count) { fCount = count; }
155 /**
156 * Set to be a non-array.
157 */
158 void setNonArray() { fCount = kNonArray; }
159 /**
160 * Set to be an unsized array.
161 */
162 void setUnsizedArray() { fCount = kUnsizedArray; }
163
164 /**
165 * Access the var name as a writable string
166 */
167 GrStringBuilder* accessName() { return &fName; }
168 /**
169 * Set the var name
170 */
171 void setName(const GrStringBuilder& n) { fName = n; }
172 void setName(const char* n) { fName = n; }
173 /**
174 * Get the var name.
175 */
176 const GrStringBuilder& getName() const { return fName; }
177
178 /**
179 * Get the type of the var
180 */
181 Type getType() const { return fType; }
182 /**
183 * Set the type of the var
184 */
185 void setType(Type type) { fType = type; }
186
tomhudson@google.com086e5352011-12-08 14:44:10 +0000187 TypeModifier getTypeModifier() const { return fTypeModifier; }
188 void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
189
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000190 /**
191 * Must the variable declaration emit a precision specifier
192 */
193 bool emitsPrecision() const { return fEmitPrecision; }
194 /**
195 * Specify whether the declaration should specify precision
196 */
197 void setEmitPrecision(bool p) { fEmitPrecision = p; }
198
199 /**
200 * Write a declaration of this variable to out.
201 */
tomhudson@google.com086e5352011-12-08 14:44:10 +0000202 void appendDecl(const GrGLInterface* gl, GrStringBuilder* out,
203 GrGLSLGeneration gen) const {
204 if (this->getTypeModifier() != kNone_TypeModifier) {
205 out->append(TypeModifierString(this->getTypeModifier(), gen));
206 out->append(" ");
207 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000208 if (this->emitsPrecision()) {
209 out->append(PrecisionString(gl));
210 out->append(" ");
211 }
tomhudson@google.comda668982011-12-07 15:06:29 +0000212 Type effectiveType = this->getType();
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000213 if (this->isArray()) {
214 if (this->isUnsizedArray()) {
215 out->appendf("%s %s[]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000216 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000217 this->getName().c_str());
218 } else {
219 GrAssert(this->getArrayCount() > 0);
220 out->appendf("%s %s[%d]",
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 this->getArrayCount());
224 }
225 } else {
226 out->appendf("%s %s",
tomhudson@google.comda668982011-12-07 15:06:29 +0000227 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000228 this->getName().c_str());
229 }
tomhudson@google.com086e5352011-12-08 14:44:10 +0000230 out->append(";\n");
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000231 }
232
233 static const char* TypeString(Type t) {
234 switch (t) {
235 case kFloat_Type:
236 return "float";
237 case kVec2f_Type:
238 return "vec2";
239 case kVec3f_Type:
240 return "vec3";
241 case kVec4f_Type:
242 return "vec4";
243 case kMat33f_Type:
244 return "mat3";
245 case kSampler2D_Type:
246 return "sampler2D";
247 default:
248 GrCrash("Unknown shader var type.");
249 return ""; // suppress warning
250 }
251 }
252
tomhudson@google.comda668982011-12-07 15:06:29 +0000253 void appendArrayAccess(int index, GrStringBuilder* out) {
254 out->appendf("%s[%d]%s",
255 this->getName().c_str(),
256 index,
257 fUseUniformFloatArrays ? "" : ".x");
258 }
259
260 void appendArrayAccess(const char* indexName, GrStringBuilder* out) {
261 out->appendf("%s[%s]%s",
262 this->getName().c_str(),
263 indexName,
264 fUseUniformFloatArrays ? "" : ".x");
265 }
266
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000267private:
268 static const char* PrecisionString(const GrGLInterface* gl) {
269 return gl->supportsDesktop() ? "" : "mediump";
270 }
271
tomhudson@google.com086e5352011-12-08 14:44:10 +0000272 static const char* TypeModifierString(TypeModifier t,
273 GrGLSLGeneration gen) {
274 switch (t) {
275 case kNone_TypeModifier:
276 return "";
277 case kOut_TypeModifier:
278 return k110_GLSLGeneration == gen ? "varying" : "out";
279 case kIn_TypeModifier:
280 return k110_GLSLGeneration == gen ? "varying" : "in";
281 case kUniform_TypeModifier:
282 return "uniform";
283 case kAttribute_TypeModifier:
284 return k110_GLSLGeneration == gen ? "attribute" : "in";
285 default:
286 GrCrash("Unknown shader variable type modifier.");
287 return ""; // suppress warning
288 }
289 }
290
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000291 Type fType;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000292 TypeModifier fTypeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000293 GrStringBuilder fName;
294 int fCount;
295 bool fEmitPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000296 /// Work around driver bugs on some hardware that don't correctly
297 /// support uniform float []
298 bool fUseUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000299};
300
301#endif