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 */
7
8 #ifndef GrGLSL_DEFINED
9 #define GrGLSL_DEFINED
10
11 #include "GrTypesPriv.h"
12 #include "SkString.h"
13
14 class GrGLSLCaps;
15
16 // Limited set of GLSL versions we build shaders for. Caller should round
17 // down the GLSL version to one of these enums.
18 enum GrGLSLGeneration {
19 /**
20 * Desktop GLSL 1.10 and ES2 shading language (based on desktop GLSL 1.20)
21 */
22 k110_GrGLSLGeneration,
23 /**
24 * Desktop GLSL 1.30
25 */
26 k130_GrGLSLGeneration,
27 /**
28 * Desktop GLSL 1.40
29 */
30 k140_GrGLSLGeneration,
31 /**
32 * Desktop GLSL 1.50
33 */
34 k150_GrGLSLGeneration,
35 /**
36 * Desktop GLSL 3.30, and ES GLSL 3.00
37 */
38 k330_GrGLSLGeneration,
39 /**
40 * Desktop GLSL 4.00
41 */
42 k400_GrGLSLGeneration,
43 /**
44 * ES GLSL 3.10 only TODO Make GLSLCap objects to make this more granular
45 */
46 k310es_GrGLSLGeneration,
47 /**
48 * ES GLSL 3.20
49 */
50 k320es_GrGLSLGeneration,
51 };
52
53 bool GrGLSLSupportsNamedFragmentShaderOutputs(GrGLSLGeneration);
54
55 /**
56 * Gets the name of the function that should be used to sample a 2D texture. Coord type is used
57 * to indicate whether the texture is sampled using projective textured (kVec3f) or not (kVec2f).
58 */
GrGLSLTexture2DFunctionName(GrSLType coordType,GrSLType samplerType,GrGLSLGeneration glslGen)59 inline const char* GrGLSLTexture2DFunctionName(GrSLType coordType, GrSLType samplerType,
60 GrGLSLGeneration glslGen) {
61 SkASSERT(GrSLTypeIsSamplerType(samplerType));
62 SkASSERT(kVec2f_GrSLType == coordType || kVec3f_GrSLType == coordType);
63 // GL_TEXTURE_RECTANGLE_ARB is written against OpenGL 2.0/GLSL 1.10. At that time there were
64 // separate texture*() functions. In OpenGL 3.0/GLSL 1.30 the different texture*() functions
65 // were deprecated in favor or the unified texture() function. RECTANGLE textures became
66 // standard in OpenGL 3.2/GLSL 1.50 and use texture(). It isn't completely clear what function
67 // should be used for RECTANGLE textures in GLSL versions >= 1.30 && < 1.50. We're going with
68 // using texture().
69 if (glslGen >= k130_GrGLSLGeneration) {
70 return (kVec2f_GrSLType == coordType) ? "texture" : "textureProj";
71 }
72 if (kVec2f_GrSLType == coordType) {
73 return (samplerType == kSampler2DRect_GrSLType) ? "texture2DRect" : "texture2D";
74 } else {
75 return (samplerType == kSampler2DRect_GrSLType) ? "texture2DRectProj" : "texture2DProj";
76 }
77 }
78
79 /**
80 * Adds a line of GLSL code to declare the default precision for float types.
81 */
82 void GrGLSLAppendDefaultFloatPrecisionDeclaration(GrSLPrecision,
83 const GrGLSLCaps& glslCaps,
84 SkString* out);
85
86 /**
87 * Converts a GrSLType to a string containing the name of the equivalent GLSL type.
88 */
GrGLSLTypeString(GrSLType t)89 static inline const char* GrGLSLTypeString(GrSLType t) {
90 switch (t) {
91 case kVoid_GrSLType:
92 return "void";
93 case kFloat_GrSLType:
94 return "float";
95 case kVec2f_GrSLType:
96 return "vec2";
97 case kVec3f_GrSLType:
98 return "vec3";
99 case kVec4f_GrSLType:
100 return "vec4";
101 case kMat33f_GrSLType:
102 return "mat3";
103 case kMat44f_GrSLType:
104 return "mat4";
105 case kSampler2D_GrSLType:
106 return "sampler2D";
107 case kSamplerExternal_GrSLType:
108 return "samplerExternalOES";
109 case kSampler2DRect_GrSLType:
110 return "sampler2DRect";
111 case kBool_GrSLType:
112 return "bool";
113 case kInt_GrSLType:
114 return "int";
115 case kUint_GrSLType:
116 return "uint";
117 default:
118 SkFAIL("Unknown shader var type.");
119 return ""; // suppress warning
120 }
121 }
122
123 /** A generic base-class representing a GLSL expression.
124 * The instance can be a variable name, expression or vecN(0) or vecN(1). Does simple constant
125 * folding with help of 1 and 0.
126 *
127 * Clients should not use this class, rather the specific instantiations defined
128 * later, for example GrGLSLExpr4.
129 */
130 template <typename Self>
131 class GrGLSLExpr {
132 public:
isOnes()133 bool isOnes() const { return kOnes_ExprType == fType; }
isZeros()134 bool isZeros() const { return kZeros_ExprType == fType; }
135
c_str()136 const char* c_str() const {
137 if (kZeros_ExprType == fType) {
138 return Self::ZerosStr();
139 } else if (kOnes_ExprType == fType) {
140 return Self::OnesStr();
141 }
142 SkASSERT(!fExpr.isEmpty()); // Empty expressions should not be used.
143 return fExpr.c_str();
144 }
145
isValid()146 bool isValid() const {
147 return kFullExpr_ExprType != fType || !fExpr.isEmpty();
148 }
149
150 protected:
151 /** Constructs an invalid expression.
152 * Useful only as a return value from functions that never actually return
153 * this and instances that will be assigned to later. */
GrGLSLExpr()154 GrGLSLExpr()
155 : fType(kFullExpr_ExprType) {
156 // The only constructor that is allowed to build an empty expression.
157 SkASSERT(!this->isValid());
158 }
159
160 /** Constructs an expression with all components as value v */
GrGLSLExpr(int v)161 explicit GrGLSLExpr(int v) {
162 if (v == 0) {
163 fType = kZeros_ExprType;
164 } else if (v == 1) {
165 fType = kOnes_ExprType;
166 } else {
167 fType = kFullExpr_ExprType;
168 fExpr.appendf(Self::CastIntStr(), v);
169 }
170 }
171
172 /** Constructs an expression from a string.
173 * Argument expr is a simple expression or a parenthesized expression. */
174 // TODO: make explicit once effects input Exprs.
GrGLSLExpr(const char expr[])175 GrGLSLExpr(const char expr[]) {
176 if (nullptr == expr) { // TODO: remove this once effects input Exprs.
177 fType = kOnes_ExprType;
178 } else {
179 fType = kFullExpr_ExprType;
180 fExpr = expr;
181 }
182 SkASSERT(this->isValid());
183 }
184
185 /** Constructs an expression from a string.
186 * Argument expr is a simple expression or a parenthesized expression. */
187 // TODO: make explicit once effects input Exprs.
GrGLSLExpr(const SkString & expr)188 GrGLSLExpr(const SkString& expr) {
189 if (expr.isEmpty()) { // TODO: remove this once effects input Exprs.
190 fType = kOnes_ExprType;
191 } else {
192 fType = kFullExpr_ExprType;
193 fExpr = expr;
194 }
195 SkASSERT(this->isValid());
196 }
197
198 /** Constructs an expression from a string with one substitution. */
GrGLSLExpr(const char format[],const char in0[])199 GrGLSLExpr(const char format[], const char in0[])
200 : fType(kFullExpr_ExprType) {
201 fExpr.appendf(format, in0);
202 }
203
204 /** Constructs an expression from a string with two substitutions. */
GrGLSLExpr(const char format[],const char in0[],const char in1[])205 GrGLSLExpr(const char format[], const char in0[], const char in1[])
206 : fType(kFullExpr_ExprType) {
207 fExpr.appendf(format, in0, in1);
208 }
209
210 /** Returns expression casted to another type.
211 * Generic implementation that is called for non-trivial cases of casts. */
212 template <typename T>
213 static Self VectorCastImpl(const T& other);
214
215 /** Returns a GLSL multiplication: component-wise or component-by-scalar.
216 * The multiplication will be component-wise or multiply each component by a scalar.
217 *
218 * The returned expression will compute the value of:
219 * vecN(in0.x * in1.x, ...) if dim(T0) == dim(T1) (component-wise)
220 * vecN(in0.x * in1, ...) if dim(T1) == 1 (vector by scalar)
221 * vecN(in0 * in1.x, ...) if dim(T0) == 1 (scalar by vector)
222 */
223 template <typename T0, typename T1>
224 static Self Mul(T0 in0, T1 in1);
225
226 /** Returns a GLSL addition: component-wise or add a scalar to each component.
227 * Return value computes:
228 * vecN(in0.x + in1.x, ...) or vecN(in0.x + in1, ...) or vecN(in0 + in1.x, ...).
229 */
230 template <typename T0, typename T1>
231 static Self Add(T0 in0, T1 in1);
232
233 /** Returns a GLSL subtraction: component-wise or subtract compoments by a scalar.
234 * Return value computes
235 * vecN(in0.x - in1.x, ...) or vecN(in0.x - in1, ...) or vecN(in0 - in1.x, ...).
236 */
237 template <typename T0, typename T1>
238 static Self Sub(T0 in0, T1 in1);
239
240 /** Returns expression that accesses component(s) of the expression.
241 * format should be the form "%s.x" where 'x' is the component(s) to access.
242 * Caller is responsible for making sure the amount of components in the
243 * format string is equal to dim(T).
244 */
245 template <typename T>
246 T extractComponents(const char format[]) const;
247
248 private:
249 enum ExprType {
250 kZeros_ExprType,
251 kOnes_ExprType,
252 kFullExpr_ExprType,
253 };
254 ExprType fType;
255 SkString fExpr;
256 };
257
258 class GrGLSLExpr1;
259 class GrGLSLExpr4;
260
261 /** Class representing a float GLSL expression. */
262 class GrGLSLExpr1 : public GrGLSLExpr<GrGLSLExpr1> {
263 public:
GrGLSLExpr1()264 GrGLSLExpr1()
265 : INHERITED() {
266 }
GrGLSLExpr1(int v)267 explicit GrGLSLExpr1(int v)
268 : INHERITED(v) {
269 }
GrGLSLExpr1(const char * expr)270 GrGLSLExpr1(const char* expr)
271 : INHERITED(expr) {
272 }
GrGLSLExpr1(const SkString & expr)273 GrGLSLExpr1(const SkString& expr)
274 : INHERITED(expr) {
275 }
276
277 static GrGLSLExpr1 VectorCast(const GrGLSLExpr1& expr);
278
279 private:
GrGLSLExpr1(const char format[],const char in0[])280 GrGLSLExpr1(const char format[], const char in0[])
281 : INHERITED(format, in0) {
282 }
GrGLSLExpr1(const char format[],const char in0[],const char in1[])283 GrGLSLExpr1(const char format[], const char in0[], const char in1[])
284 : INHERITED(format, in0, in1) {
285 }
286
287 static const char* ZerosStr();
288 static const char* OnesStr();
289 static const char* CastStr();
290 static const char* CastIntStr();
291
292 friend GrGLSLExpr1 operator*(const GrGLSLExpr1& in0, const GrGLSLExpr1&in1);
293 friend GrGLSLExpr1 operator+(const GrGLSLExpr1& in0, const GrGLSLExpr1&in1);
294 friend GrGLSLExpr1 operator-(const GrGLSLExpr1& in0, const GrGLSLExpr1&in1);
295
296 friend class GrGLSLExpr<GrGLSLExpr1>;
297 friend class GrGLSLExpr<GrGLSLExpr4>;
298
299 typedef GrGLSLExpr<GrGLSLExpr1> INHERITED;
300 };
301
302 /** Class representing a float vector (vec4) GLSL expression. */
303 class GrGLSLExpr4 : public GrGLSLExpr<GrGLSLExpr4> {
304 public:
GrGLSLExpr4()305 GrGLSLExpr4()
306 : INHERITED() {
307 }
GrGLSLExpr4(int v)308 explicit GrGLSLExpr4(int v)
309 : INHERITED(v) {
310 }
GrGLSLExpr4(const char * expr)311 GrGLSLExpr4(const char* expr)
312 : INHERITED(expr) {
313 }
GrGLSLExpr4(const SkString & expr)314 GrGLSLExpr4(const SkString& expr)
315 : INHERITED(expr) {
316 }
317
318 typedef GrGLSLExpr1 AExpr;
319 AExpr a() const;
320
321 /** GLSL vec4 cast / constructor, eg vec4(floatv) -> vec4(floatv, floatv, floatv, floatv) */
322 static GrGLSLExpr4 VectorCast(const GrGLSLExpr1& expr);
323 static GrGLSLExpr4 VectorCast(const GrGLSLExpr4& expr);
324
325 private:
GrGLSLExpr4(const char format[],const char in0[])326 GrGLSLExpr4(const char format[], const char in0[])
327 : INHERITED(format, in0) {
328 }
GrGLSLExpr4(const char format[],const char in0[],const char in1[])329 GrGLSLExpr4(const char format[], const char in0[], const char in1[])
330 : INHERITED(format, in0, in1) {
331 }
332
333 static const char* ZerosStr();
334 static const char* OnesStr();
335 static const char* CastStr();
336 static const char* CastIntStr();
337
338 // The vector-by-scalar and scalar-by-vector binary operations.
339 friend GrGLSLExpr4 operator*(const GrGLSLExpr1& in0, const GrGLSLExpr4&in1);
340 friend GrGLSLExpr4 operator+(const GrGLSLExpr1& in0, const GrGLSLExpr4&in1);
341 friend GrGLSLExpr4 operator-(const GrGLSLExpr1& in0, const GrGLSLExpr4&in1);
342 friend GrGLSLExpr4 operator*(const GrGLSLExpr4& in0, const GrGLSLExpr1&in1);
343 friend GrGLSLExpr4 operator+(const GrGLSLExpr4& in0, const GrGLSLExpr1&in1);
344 friend GrGLSLExpr4 operator-(const GrGLSLExpr4& in0, const GrGLSLExpr1&in1);
345
346 // The vector-by-vector, i.e. component-wise, binary operations.
347 friend GrGLSLExpr4 operator*(const GrGLSLExpr4& in0, const GrGLSLExpr4&in1);
348 friend GrGLSLExpr4 operator+(const GrGLSLExpr4& in0, const GrGLSLExpr4&in1);
349 friend GrGLSLExpr4 operator-(const GrGLSLExpr4& in0, const GrGLSLExpr4&in1);
350
351 friend class GrGLSLExpr<GrGLSLExpr4>;
352
353 typedef GrGLSLExpr<GrGLSLExpr4> INHERITED;
354 };
355
356 /**
357 * Does an inplace mul, *=, of vec4VarName by mulFactor.
358 * A semicolon is added after the assignment.
359 */
360 void GrGLSLMulVarBy4f(SkString* outAppend, const char* vec4VarName, const GrGLSLExpr4& mulFactor);
361
362 #include "GrGLSL_impl.h"
363
364 #endif
365