blob: dc7d52b3a75f35cf684930deeebfa157ae081461 [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
bsalomon@google.com96399942012-02-13 14:39:16 +000012#include "GrGLContextInfo.h"
tomhudson@google.com086e5352011-12-08 14:44:10 +000013#include "GrGLSL.h"
tomhudson@google.comdd182cb2012-02-10 21:01:00 +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,
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +000030 kMat44f_Type,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000031 kSampler2D_Type,
32 };
33
34 /**
tomhudson@google.com086e5352011-12-08 14:44:10 +000035 * Early versions of GLSL have Varying and Attribute; those are later
36 * deprecated, but we still need to know whether a Varying variable
37 * should be treated as In or Out.
38 */
39 enum TypeModifier {
40 kNone_TypeModifier,
41 kOut_TypeModifier,
42 kIn_TypeModifier,
43 kUniform_TypeModifier,
44 kAttribute_TypeModifier
45 };
46
47 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +000048 * Defaults to a float with no precision specifier
49 */
50 GrGLShaderVar() {
51 fType = kFloat_Type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000052 fTypeModifier = kNone_TypeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000053 fCount = kNonArray;
54 fEmitPrecision = false;
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)
tomhudson@google.comda668982011-12-07 15:06:29 +000063 , fEmitPrecision(var.fEmitPrecision)
64 , 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 */
77 void set(Type type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000078 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000079 const GrStringBuilder& name,
tomhudson@google.comda668982011-12-07 15:06:29 +000080 bool emitPrecision = false,
81 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;
86 fEmitPrecision = emitPrecision;
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 */
93 void set(Type type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000094 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000095 const char* name,
tomhudson@google.comda668982011-12-07 15:06:29 +000096 bool specifyPrecision = false,
97 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;
102 fEmitPrecision = specifyPrecision;
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 */
109 void set(Type type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000110 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000111 const GrStringBuilder& name,
112 int count,
tomhudson@google.comda668982011-12-07 15:06:29 +0000113 bool specifyPrecision = false,
114 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;
119 fEmitPrecision = specifyPrecision;
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 */
126 void set(Type 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,
tomhudson@google.comda668982011-12-07 15:06:29 +0000130 bool specifyPrecision = false,
131 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;
136 fEmitPrecision = specifyPrecision;
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 */
168 GrStringBuilder* accessName() { return &fName; }
169 /**
170 * Set the var name
171 */
172 void setName(const GrStringBuilder& n) { fName = n; }
173 void setName(const char* n) { fName = n; }
174 /**
175 * Get the var name.
176 */
177 const GrStringBuilder& getName() const { return fName; }
178
179 /**
180 * Get the type of the var
181 */
182 Type getType() const { return fType; }
183 /**
184 * Set the type of the var
185 */
186 void setType(Type type) { fType = type; }
187
tomhudson@google.com086e5352011-12-08 14:44:10 +0000188 TypeModifier getTypeModifier() const { return fTypeModifier; }
189 void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
190
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000191 /**
192 * Must the variable declaration emit a precision specifier
193 */
194 bool emitsPrecision() const { return fEmitPrecision; }
195 /**
196 * Specify whether the declaration should specify precision
197 */
198 void setEmitPrecision(bool p) { fEmitPrecision = p; }
199
200 /**
201 * Write a declaration of this variable to out.
202 */
bsalomon@google.com96399942012-02-13 14:39:16 +0000203 void appendDecl(const GrGLContextInfo& gl, GrStringBuilder* out) const {
tomhudson@google.com086e5352011-12-08 14:44:10 +0000204 if (this->getTypeModifier() != kNone_TypeModifier) {
bsalomon@google.com96399942012-02-13 14:39:16 +0000205 out->append(TypeModifierString(this->getTypeModifier(),
206 gl.glslGeneration()));
tomhudson@google.com086e5352011-12-08 14:44:10 +0000207 out->append(" ");
208 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000209 if (this->emitsPrecision()) {
bsalomon@google.com96399942012-02-13 14:39:16 +0000210 out->append(GrGetGLSLVarPrecisionDeclType(gl.binding()));
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000211 out->append(" ");
212 }
tomhudson@google.comda668982011-12-07 15:06:29 +0000213 Type effectiveType = this->getType();
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000214 if (this->isArray()) {
215 if (this->isUnsizedArray()) {
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 } else {
220 GrAssert(this->getArrayCount() > 0);
221 out->appendf("%s %s[%d]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000222 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000223 this->getName().c_str(),
224 this->getArrayCount());
225 }
226 } else {
227 out->appendf("%s %s",
tomhudson@google.comda668982011-12-07 15:06:29 +0000228 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000229 this->getName().c_str());
230 }
tomhudson@google.com086e5352011-12-08 14:44:10 +0000231 out->append(";\n");
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000232 }
233
234 static const char* TypeString(Type t) {
235 switch (t) {
236 case kFloat_Type:
237 return "float";
238 case kVec2f_Type:
239 return "vec2";
240 case kVec3f_Type:
241 return "vec3";
242 case kVec4f_Type:
243 return "vec4";
244 case kMat33f_Type:
245 return "mat3";
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000246 case kMat44f_Type:
247 return "mat4";
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000248 case kSampler2D_Type:
249 return "sampler2D";
250 default:
251 GrCrash("Unknown shader var type.");
252 return ""; // suppress warning
253 }
254 }
255
tomhudson@google.comda668982011-12-07 15:06:29 +0000256 void appendArrayAccess(int index, GrStringBuilder* out) {
257 out->appendf("%s[%d]%s",
258 this->getName().c_str(),
259 index,
260 fUseUniformFloatArrays ? "" : ".x");
261 }
262
263 void appendArrayAccess(const char* indexName, GrStringBuilder* out) {
264 out->appendf("%s[%s]%s",
265 this->getName().c_str(),
266 indexName,
267 fUseUniformFloatArrays ? "" : ".x");
268 }
269
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000270private:
tomhudson@google.com086e5352011-12-08 14:44:10 +0000271 static const char* TypeModifierString(TypeModifier t,
272 GrGLSLGeneration gen) {
273 switch (t) {
274 case kNone_TypeModifier:
275 return "";
276 case kOut_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000277 return k110_GrGLSLGeneration == gen ? "varying" : "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000278 case kIn_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000279 return k110_GrGLSLGeneration == gen ? "varying" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000280 case kUniform_TypeModifier:
281 return "uniform";
282 case kAttribute_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000283 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000284 default:
285 GrCrash("Unknown shader variable type modifier.");
286 return ""; // suppress warning
287 }
288 }
289
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000290 Type fType;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000291 TypeModifier fTypeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000292 GrStringBuilder fName;
293 int fCount;
294 bool fEmitPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000295 /// Work around driver bugs on some hardware that don't correctly
296 /// support uniform float []
297 bool fUseUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000298};
299
300#endif