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