blob: 1e278c292b81879b3ce0d78f531ed24cae6582cb [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"
bsalomon@google.comffa11bb2011-10-20 13:43:13 +000013#include "GrStringBuilder.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
23 enum Type {
24 kFloat_Type,
25 kVec2f_Type,
26 kVec3f_Type,
27 kVec4f_Type,
28 kMat33f_Type,
29 kSampler2D_Type,
30 };
31
32 /**
33 * Defaults to a float with no precision specifier
34 */
35 GrGLShaderVar() {
36 fType = kFloat_Type;
37 fCount = kNonArray;
38 fEmitPrecision = false;
tomhudson@google.comda668982011-12-07 15:06:29 +000039 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000040 }
41
42 GrGLShaderVar(const GrGLShaderVar& var)
43 : fType(var.fType)
44 , fName(var.fName)
45 , fCount(var.fCount)
tomhudson@google.comda668982011-12-07 15:06:29 +000046 , fEmitPrecision(var.fEmitPrecision)
47 , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
bsalomon@google.com4fa66942011-09-20 19:06:12 +000048
49 /**
50 * Values for array count that have special meaning. We allow 1-sized arrays.
51 */
52 enum {
53 kNonArray = 0, // not an array
54 kUnsizedArray = -1, // an unsized array (declared with [])
55 };
56
57 /**
58 * Sets as a non-array.
59 */
60 void set(Type type,
61 const GrStringBuilder& name,
tomhudson@google.comda668982011-12-07 15:06:29 +000062 bool emitPrecision = false,
63 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000064 fType = type;
65 fName = name;
66 fCount = kNonArray;
67 fEmitPrecision = emitPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +000068 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000069 }
70
71 /**
72 * Sets as a non-array.
73 */
74 void set(Type type,
75 const char* name,
tomhudson@google.comda668982011-12-07 15:06:29 +000076 bool specifyPrecision = false,
77 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000078 fType = type;
79 fName = name;
80 fCount = kNonArray;
81 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +000082 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000083 }
84
85 /**
86 * Set all var options
87 */
88 void set(Type type,
89 const GrStringBuilder& name,
90 int count,
tomhudson@google.comda668982011-12-07 15:06:29 +000091 bool specifyPrecision = false,
92 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +000093 fType = type;
94 fName = name;
95 fCount = count;
96 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +000097 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +000098 }
99
100 /**
101 * Set all var options
102 */
103 void set(Type type,
104 const char* name,
105 int count,
tomhudson@google.comda668982011-12-07 15:06:29 +0000106 bool specifyPrecision = false,
107 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000108 fType = type;
109 fName = name;
110 fCount = count;
111 fEmitPrecision = specifyPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000112 fUseUniformFloatArrays = useUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000113 }
114
115 /**
116 * Is the var an array.
117 */
118 bool isArray() const { return kNonArray != fCount; }
119 /**
120 * Is this an unsized array, (i.e. declared with []).
121 */
122 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
123 /**
124 * Get the array length of the var.
125 */
126 int getArrayCount() const { return fCount; }
127 /**
128 * Set the array length of the var
129 */
130 void setArrayCount(int count) { fCount = count; }
131 /**
132 * Set to be a non-array.
133 */
134 void setNonArray() { fCount = kNonArray; }
135 /**
136 * Set to be an unsized array.
137 */
138 void setUnsizedArray() { fCount = kUnsizedArray; }
139
140 /**
141 * Access the var name as a writable string
142 */
143 GrStringBuilder* accessName() { return &fName; }
144 /**
145 * Set the var name
146 */
147 void setName(const GrStringBuilder& n) { fName = n; }
148 void setName(const char* n) { fName = n; }
149 /**
150 * Get the var name.
151 */
152 const GrStringBuilder& getName() const { return fName; }
153
154 /**
155 * Get the type of the var
156 */
157 Type getType() const { return fType; }
158 /**
159 * Set the type of the var
160 */
161 void setType(Type type) { fType = type; }
162
163 /**
164 * Must the variable declaration emit a precision specifier
165 */
166 bool emitsPrecision() const { return fEmitPrecision; }
167 /**
168 * Specify whether the declaration should specify precision
169 */
170 void setEmitPrecision(bool p) { fEmitPrecision = p; }
171
172 /**
173 * Write a declaration of this variable to out.
174 */
175 void appendDecl(const GrGLInterface* gl, GrStringBuilder* out) const {
176 if (this->emitsPrecision()) {
177 out->append(PrecisionString(gl));
178 out->append(" ");
179 }
tomhudson@google.comda668982011-12-07 15:06:29 +0000180 Type effectiveType = this->getType();
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000181 if (this->isArray()) {
182 if (this->isUnsizedArray()) {
183 out->appendf("%s %s[]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000184 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000185 this->getName().c_str());
186 } else {
187 GrAssert(this->getArrayCount() > 0);
188 out->appendf("%s %s[%d]",
tomhudson@google.comda668982011-12-07 15:06:29 +0000189 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000190 this->getName().c_str(),
191 this->getArrayCount());
192 }
193 } else {
194 out->appendf("%s %s",
tomhudson@google.comda668982011-12-07 15:06:29 +0000195 TypeString(effectiveType),
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000196 this->getName().c_str());
197 }
198 }
199
200 static const char* TypeString(Type t) {
201 switch (t) {
202 case kFloat_Type:
203 return "float";
204 case kVec2f_Type:
205 return "vec2";
206 case kVec3f_Type:
207 return "vec3";
208 case kVec4f_Type:
209 return "vec4";
210 case kMat33f_Type:
211 return "mat3";
212 case kSampler2D_Type:
213 return "sampler2D";
214 default:
215 GrCrash("Unknown shader var type.");
216 return ""; // suppress warning
217 }
218 }
219
tomhudson@google.comda668982011-12-07 15:06:29 +0000220 void appendArrayAccess(int index, GrStringBuilder* out) {
221 out->appendf("%s[%d]%s",
222 this->getName().c_str(),
223 index,
224 fUseUniformFloatArrays ? "" : ".x");
225 }
226
227 void appendArrayAccess(const char* indexName, GrStringBuilder* out) {
228 out->appendf("%s[%s]%s",
229 this->getName().c_str(),
230 indexName,
231 fUseUniformFloatArrays ? "" : ".x");
232 }
233
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000234private:
235 static const char* PrecisionString(const GrGLInterface* gl) {
236 return gl->supportsDesktop() ? "" : "mediump";
237 }
238
239 Type fType;
240 GrStringBuilder fName;
241 int fCount;
242 bool fEmitPrecision;
tomhudson@google.comda668982011-12-07 15:06:29 +0000243 /// Work around driver bugs on some hardware that don't correctly
244 /// support uniform float []
245 bool fUseUniformFloatArrays;
bsalomon@google.com4fa66942011-09-20 19:06:12 +0000246};
247
248#endif