Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /*
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 */
8 #ifndef GrGLShaderVar_DEFINED
9 #define GrGLShaderVar_DEFINED
11 #include "GrGLContext.h"
12 #include "GrGLSL.h"
13 #include "SkString.h"
15 #define USE_UNIFORM_FLOAT_ARRAYS true
17 /**
18 * Represents a variable in a shader
19 */
20 class GrGLShaderVar {
21 public:
23 /**
24 * 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 kInOut_TypeModifier,
33 kUniform_TypeModifier,
34 kAttribute_TypeModifier,
35 kVaryingIn_TypeModifier,
36 kVaryingOut_TypeModifier
37 };
39 enum Precision {
40 kLow_Precision, // lowp
41 kMedium_Precision, // mediump
42 kHigh_Precision, // highp
43 kDefault_Precision, // Default for the current context. We make
44 // fragment shaders default to mediump on ES2
45 // because highp support is not guaranteed (and
46 // we haven't been motivated to test for it).
47 // Otherwise, highp.
48 };
50 /**
51 * See GL_ARB_fragment_coord_conventions.
52 */
53 enum Origin {
54 kDefault_Origin, // when set to kDefault the origin field is ignored.
55 kUpperLeft_Origin, // only used to declare vec4 in gl_FragCoord.
56 };
58 /**
59 * Defaults to a float with no precision specifier
60 */
61 GrGLShaderVar() {
62 fType = kFloat_GrSLType;
63 fTypeModifier = kNone_TypeModifier;
64 fCount = kNonArray;
65 fPrecision = kDefault_Precision;
66 fOrigin = kDefault_Origin;
67 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
68 }
70 GrGLShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
71 Precision precision = kDefault_Precision) {
72 SkASSERT(kVoid_GrSLType != type);
73 fType = type;
74 fTypeModifier = kNone_TypeModifier;
75 fCount = arrayCount;
76 fPrecision = precision;
77 fOrigin = kDefault_Origin;
78 fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
79 fName = name;
80 }
82 GrGLShaderVar(const GrGLShaderVar& var)
83 : fType(var.fType)
84 , fTypeModifier(var.fTypeModifier)
85 , fName(var.fName)
86 , fCount(var.fCount)
87 , fPrecision(var.fPrecision)
88 , fOrigin(var.fOrigin)
89 , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {
90 SkASSERT(kVoid_GrSLType != var.fType);
91 }
93 /**
94 * Values for array count that have special meaning. We allow 1-sized arrays.
95 */
96 enum {
97 kNonArray = 0, // not an array
98 kUnsizedArray = -1, // an unsized array (declared with [])
99 };
101 /**
102 * Sets as a non-array.
103 */
104 void set(GrSLType type,
105 TypeModifier typeModifier,
106 const SkString& name,
107 Precision precision = kDefault_Precision,
108 Origin origin = kDefault_Origin,
109 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
110 SkASSERT(kVoid_GrSLType != type);
111 fType = type;
112 fTypeModifier = typeModifier;
113 fName = name;
114 fCount = kNonArray;
115 fPrecision = precision;
116 fOrigin = origin;
117 fUseUniformFloatArrays = useUniformFloatArrays;
118 }
120 /**
121 * Sets as a non-array.
122 */
123 void set(GrSLType type,
124 TypeModifier typeModifier,
125 const char* name,
126 Precision precision = kDefault_Precision,
127 Origin origin = kDefault_Origin,
128 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
129 SkASSERT(kVoid_GrSLType != type);
130 fType = type;
131 fTypeModifier = typeModifier;
132 fName = name;
133 fCount = kNonArray;
134 fPrecision = precision;
135 fOrigin = origin;
136 fUseUniformFloatArrays = useUniformFloatArrays;
137 }
139 /**
140 * Set all var options
141 */
142 void set(GrSLType type,
143 TypeModifier typeModifier,
144 const SkString& name,
145 int count,
146 Precision precision = kDefault_Precision,
147 Origin origin = kDefault_Origin,
148 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
149 SkASSERT(kVoid_GrSLType != type);
150 fType = type;
151 fTypeModifier = typeModifier;
152 fName = name;
153 fCount = count;
154 fPrecision = precision;
155 fOrigin = origin;
156 fUseUniformFloatArrays = useUniformFloatArrays;
157 }
159 /**
160 * Set all var options
161 */
162 void set(GrSLType type,
163 TypeModifier typeModifier,
164 const char* name,
165 int count,
166 Precision precision = kDefault_Precision,
167 Origin origin = kDefault_Origin,
168 bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
169 SkASSERT(kVoid_GrSLType != type);
170 fType = type;
171 fTypeModifier = typeModifier;
172 fName = name;
173 fCount = count;
174 fPrecision = precision;
175 fOrigin = origin;
176 fUseUniformFloatArrays = useUniformFloatArrays;
177 }
179 /**
180 * Is the var an array.
181 */
182 bool isArray() const { return kNonArray != fCount; }
183 /**
184 * Is this an unsized array, (i.e. declared with []).
185 */
186 bool isUnsizedArray() const { return kUnsizedArray == fCount; }
187 /**
188 * Get the array length of the var.
189 */
190 int getArrayCount() const { return fCount; }
191 /**
192 * Set the array length of the var
193 */
194 void setArrayCount(int count) { fCount = count; }
195 /**
196 * Set to be a non-array.
197 */
198 void setNonArray() { fCount = kNonArray; }
199 /**
200 * Set to be an unsized array.
201 */
202 void setUnsizedArray() { fCount = kUnsizedArray; }
204 /**
205 * Access the var name as a writable string
206 */
207 SkString* accessName() { return &fName; }
208 /**
209 * Set the var name
210 */
211 void setName(const SkString& n) { fName = n; }
212 void setName(const char* n) { fName = n; }
214 /**
215 * Get the var name.
216 */
217 const SkString& getName() const { return fName; }
219 /**
220 * Shortcut for this->getName().c_str();
221 */
222 const char* c_str() const { return this->getName().c_str(); }
224 /**
225 * Get the type of the var
226 */
227 GrSLType getType() const { return fType; }
228 /**
229 * Set the type of the var
230 */
231 void setType(GrSLType type) { fType = type; }
233 TypeModifier getTypeModifier() const { return fTypeModifier; }
234 void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
236 /**
237 * Get the precision of the var
238 */
239 Precision getPrecision() const { return fPrecision; }
241 /**
242 * Set the precision of the var
243 */
244 void setPrecision(Precision p) { fPrecision = p; }
246 /**
247 * Get the origin of the var
248 */
249 Origin getOrigin() const { return fOrigin; }
251 /**
252 * Set the origin of the var
253 */
254 void setOrigin(Origin origin) { fOrigin = origin; }
256 /**
257 * Write a declaration of this variable to out.
258 */
259 void appendDecl(const GrGLContextInfo& ctxInfo, SkString* out) const {
260 if (kUpperLeft_Origin == fOrigin) {
261 // this is the only place where we specify a layout modifier. If we use other layout
262 // modifiers in the future then they should be placed in a list.
263 out->append("layout(origin_upper_left) ");
264 }
265 if (this->getTypeModifier() != kNone_TypeModifier) {
266 out->append(TypeModifierString(this->getTypeModifier(),
267 ctxInfo.glslGeneration()));
268 out->append(" ");
269 }
270 out->append(PrecisionString(fPrecision, ctxInfo.standard()));
271 GrSLType effectiveType = this->getType();
272 if (this->isArray()) {
273 if (this->isUnsizedArray()) {
274 out->appendf("%s %s[]",
275 GrGLSLTypeString(effectiveType),
276 this->getName().c_str());
277 } else {
278 SkASSERT(this->getArrayCount() > 0);
279 out->appendf("%s %s[%d]",
280 GrGLSLTypeString(effectiveType),
281 this->getName().c_str(),
282 this->getArrayCount());
283 }
284 } else {
285 out->appendf("%s %s",
286 GrGLSLTypeString(effectiveType),
287 this->getName().c_str());
288 }
289 }
291 void appendArrayAccess(int index, SkString* out) const {
292 out->appendf("%s[%d]%s",
293 this->getName().c_str(),
294 index,
295 fUseUniformFloatArrays ? "" : ".x");
296 }
298 void appendArrayAccess(const char* indexName, SkString* out) const {
299 out->appendf("%s[%s]%s",
300 this->getName().c_str(),
301 indexName,
302 fUseUniformFloatArrays ? "" : ".x");
303 }
305 static const char* PrecisionString(Precision p, GrGLStandard standard) {
306 // Desktop GLSL has added precision qualifiers but they don't do anything.
307 if (kGLES_GrGLStandard == standard) {
308 switch (p) {
309 case kLow_Precision:
310 return "lowp ";
311 case kMedium_Precision:
312 return "mediump ";
313 case kHigh_Precision:
314 return "highp ";
315 case kDefault_Precision:
316 return "";
317 default:
318 GrCrash("Unexpected precision type.");
319 }
320 }
321 return "";
322 }
324 private:
325 static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
326 switch (t) {
327 case kNone_TypeModifier:
328 return "";
329 case kIn_TypeModifier:
330 return "in";
331 case kInOut_TypeModifier:
332 return "inout";
333 case kOut_TypeModifier:
334 return "out";
335 case kUniform_TypeModifier:
336 return "uniform";
337 case kAttribute_TypeModifier:
338 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
339 case kVaryingIn_TypeModifier:
340 return k110_GrGLSLGeneration == gen ? "varying" : "in";
341 case kVaryingOut_TypeModifier:
342 return k110_GrGLSLGeneration == gen ? "varying" : "out";
343 default:
344 GrCrash("Unknown shader variable type modifier.");
345 return ""; // suppress warning
346 }
347 }
349 GrSLType fType;
350 TypeModifier fTypeModifier;
351 SkString fName;
352 int fCount;
353 Precision fPrecision;
354 Origin fOrigin;
355 /// Work around driver bugs on some hardware that don't correctly
356 /// support uniform float []
357 bool fUseUniformFloatArrays;
358 };
360 #endif