blob: 149214e33ffdaa878045126baaff54f7ce6f1460 [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
bsalomon@google.com4fa66942011-09-20 19:06:12 +000024 /**
tomhudson@google.com086e5352011-12-08 14:44:10 +000025 * Early versions of GLSL have Varying and Attribute; those are later
26 * deprecated, but we still need to know whether a Varying variable
27 * should be treated as In or Out.
28 */
29 enum TypeModifier {
30 kNone_TypeModifier,
31 kOut_TypeModifier,
32 kIn_TypeModifier,
33 kUniform_TypeModifier,
34 kAttribute_TypeModifier
35 };
36
37 /**
bsalomon@google.com4fa66942011-09-20 19:06:12 +000038 * Defaults to a float with no precision specifier
39 */
40 GrGLShaderVar() {
tomhudson@google.com168e6342012-04-18 17:49:20 +000041 fType = kFloat_GrSLType;
tomhudson@google.com086e5352011-12-08 14:44:10 +000042 fTypeModifier = kNone_TypeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000043 fCount = kNonArray;
44 fEmitPrecision = false;
tomhudson@google.comda668982011-12-07 15:06:29 +000045 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000046 }
47
48 GrGLShaderVar(const GrGLShaderVar& var)
49 : fType(var.fType)
tomhudson@google.com086e5352011-12-08 14:44:10 +000050 , fTypeModifier(var.fTypeModifier)
bsalomon@google.com4fa66942011-09-20 19:06:12 +000051 , fName(var.fName)
52 , fCount(var.fCount)
tomhudson@google.comda668982011-12-07 15:06:29 +000053 , fEmitPrecision(var.fEmitPrecision)
54 , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
bsalomon@google.com4fa66942011-09-20 19:06:12 +000055
56 /**
57 * Values for array count that have special meaning. We allow 1-sized arrays.
58 */
59 enum {
60 kNonArray = 0, // not an array
61 kUnsizedArray = -1, // an unsized array (declared with [])
62 };
63
64 /**
65 * Sets as a non-array.
66 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000067 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000068 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000069 const GrStringBuilder& name,
tomhudson@google.comda668982011-12-07 15:06:29 +000070 bool emitPrecision = false,
71 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000072 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000073 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000074 fName = name;
75 fCount = kNonArray;
76 fEmitPrecision = emitPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +000077 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000078 }
79
80 /**
81 * Sets as a non-array.
82 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000083 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +000084 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +000085 const char* name,
tomhudson@google.comda668982011-12-07 15:06:29 +000086 bool specifyPrecision = false,
87 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000088 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +000089 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000090 fName = name;
91 fCount = kNonArray;
92 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +000093 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000094 }
95
96 /**
97 * Set all var options
98 */
tomhudson@google.com168e6342012-04-18 17:49:20 +000099 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000100 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000101 const GrStringBuilder& name,
102 int count,
tomhudson@google.comda668982011-12-07 15:06:29 +0000103 bool specifyPrecision = false,
104 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000105 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000106 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000107 fName = name;
108 fCount = count;
109 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000110 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000111 }
112
113 /**
114 * Set all var options
115 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000116 void set(GrSLType type,
tomhudson@google.com086e5352011-12-08 14:44:10 +0000117 TypeModifier typeModifier,
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000118 const char* name,
119 int count,
tomhudson@google.comda668982011-12-07 15:06:29 +0000120 bool specifyPrecision = false,
121 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000122 fType = type;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000123 fTypeModifier = typeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000124 fName = name;
125 fCount = count;
126 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000127 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000128 }
129
130 /**
131 * Is the var an array.
132 */
133 bool isArray() const { return kNonArray != fCount; }
134 /**
135 * Is this an unsized array, (i.e. declared with []).
136 */
137 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
138 /**
139 * Get the array length of the var.
140 */
141 int getArrayCount() const { return fCount; }
142 /**
143 * Set the array length of the var
144 */
145 void setArrayCount(int count) { fCount = count; }
146 /**
147 * Set to be a non-array.
148 */
149 void setNonArray() { fCount = kNonArray; }
150 /**
151 * Set to be an unsized array.
152 */
153 void setUnsizedArray() { fCount = kUnsizedArray; }
154
155 /**
156 * Access the var name as a writable string
157 */
158 GrStringBuilder* accessName() { return &fName; }
159 /**
160 * Set the var name
161 */
162 void setName(const GrStringBuilder& n) { fName = n; }
163 void setName(const char* n) { fName = n; }
164 /**
165 * Get the var name.
166 */
167 const GrStringBuilder& getName() const { return fName; }
168
169 /**
170 * Get the type of the var
171 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000172 GrSLType getType() const { return fType; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000173 /**
174 * Set the type of the var
175 */
tomhudson@google.com168e6342012-04-18 17:49:20 +0000176 void setType(GrSLType type) { fType = type; }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000177
tomhudson@google.com086e5352011-12-08 14:44:10 +0000178 TypeModifier getTypeModifier() const { return fTypeModifier; }
179 void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
180
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000181 /**
182 * Must the variable declaration emit a precision specifier
183 */
184 bool emitsPrecision() const { return fEmitPrecision; }
185 /**
186 * Specify whether the declaration should specify precision
187 */
188 void setEmitPrecision(bool p) { fEmitPrecision = p; }
189
190 /**
191 * Write a declaration of this variable to out.
192 */
bsalomon@google.com96399942012-02-13 14:39:16 +0000193 void appendDecl(const GrGLContextInfo& gl, GrStringBuilder* out) const {
tomhudson@google.com086e5352011-12-08 14:44:10 +0000194 if (this->getTypeModifier() != kNone_TypeModifier) {
bsalomon@google.com96399942012-02-13 14:39:16 +0000195 out->append(TypeModifierString(this->getTypeModifier(),
196 gl.glslGeneration()));
tomhudson@google.com086e5352011-12-08 14:44:10 +0000197 out->append(" ");
198 }
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000199 if (this->emitsPrecision()) {
bsalomon@google.com96399942012-02-13 14:39:16 +0000200 out->append(GrGetGLSLVarPrecisionDeclType(gl.binding()));
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000201 out->append(" ");
202 }
tomhudson@google.com168e6342012-04-18 17:49:20 +0000203 GrSLType effectiveType = this->getType();
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000204 if (this->isArray()) {
205 if (this->isUnsizedArray()) {
206 out->appendf("%s %s[]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000207 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000208 this->getName().c_str());
209 } else {
210 GrAssert(this->getArrayCount() > 0);
211 out->appendf("%s %s[%d]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000212 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000213 this->getName().c_str(),
214 this->getArrayCount());
215 }
216 } else {
217 out->appendf("%s %s",
tomhudson@google.comda668982011-12-07 15:06:29 +0000218 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000219 this->getName().c_str());
220 }
tomhudson@google.com086e5352011-12-08 14:44:10 +0000221 out->append(";\n");
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000222 }
223
tomhudson@google.com168e6342012-04-18 17:49:20 +0000224 static const char* TypeString(GrSLType t) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000225 switch (t) {
tomhudson@google.com168e6342012-04-18 17:49:20 +0000226 case kFloat_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000227 return "float";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000228 case kVec2f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000229 return "vec2";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000230 case kVec3f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000231 return "vec3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000232 case kVec4f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000233 return "vec4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000234 case kMat33f_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000235 return "mat3";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000236 case kMat44f_GrSLType:
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000237 return "mat4";
tomhudson@google.com168e6342012-04-18 17:49:20 +0000238 case kSampler2D_GrSLType:
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000239 return "sampler2D";
240 default:
241 GrCrash("Unknown shader var type.");
242 return ""; // suppress warning
243 }
244 }
245
tomhudson@google.comda668982011-12-07 15:06:29 +0000246 void appendArrayAccess(int index, GrStringBuilder* out) {
247 out->appendf("%s[%d]%s",
248 this->getName().c_str(),
249 index,
250 fUseUniformFloatArrays ? "" : ".x");
251 }
252
253 void appendArrayAccess(const char* indexName, GrStringBuilder* out) {
254 out->appendf("%s[%s]%s",
255 this->getName().c_str(),
256 indexName,
257 fUseUniformFloatArrays ? "" : ".x");
258 }
259
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000260private:
tomhudson@google.com086e5352011-12-08 14:44:10 +0000261 static const char* TypeModifierString(TypeModifier t,
262 GrGLSLGeneration gen) {
263 switch (t) {
264 case kNone_TypeModifier:
265 return "";
266 case kOut_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000267 return k110_GrGLSLGeneration == gen ? "varying" : "out";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000268 case kIn_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000269 return k110_GrGLSLGeneration == gen ? "varying" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000270 case kUniform_TypeModifier:
271 return "uniform";
272 case kAttribute_TypeModifier:
bsalomon@google.come55fd0f2012-02-10 15:56:06 +0000273 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
tomhudson@google.com086e5352011-12-08 14:44:10 +0000274 default:
275 GrCrash("Unknown shader variable type modifier.");
276 return ""; // suppress warning
277 }
278 }
279
tomhudson@google.com168e6342012-04-18 17:49:20 +0000280 GrSLType fType;
tomhudson@google.com086e5352011-12-08 14:44:10 +0000281 TypeModifier fTypeModifier;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000282 GrStringBuilder fName;
283 int fCount;
284 bool fEmitPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000285 /// Work around driver bugs on some hardware that don't correctly
286 /// support uniform float []
287 bool fUseUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000288};
289
290#endif