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 GrShaderCaps;
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      * Desktop GLSL 4.20
45      */
46     k420_GrGLSLGeneration,
47     /**
48      * ES GLSL 3.10 only TODO Make GLSLCap objects to make this more granular
49      */
50     k310es_GrGLSLGeneration,
51     /**
52      * ES GLSL 3.20
53      */
54     k320es_GrGLSLGeneration,
55 };
56 
57 bool GrGLSLSupportsNamedFragmentShaderOutputs(GrGLSLGeneration);
58 
59 /**
60  * Adds a line of GLSL code to declare the default precision for float types.
61  */
62 void GrGLSLAppendDefaultFloatPrecisionDeclaration(GrSLPrecision,
63                                                   const GrShaderCaps&,
64                                                   SkString* out);
65 
66 /**
67  * Converts a GrSLPrecision to its corresponding GLSL precision qualifier.
68  */
GrGLSLPrecisionString(GrSLPrecision p)69 static inline const char* GrGLSLPrecisionString(GrSLPrecision p) {
70     switch (p) {
71         case kLow_GrSLPrecision:
72             return "lowp";
73         case kMedium_GrSLPrecision:
74             return "mediump";
75         case kHigh_GrSLPrecision:
76             return "highp";
77         default:
78             SkFAIL("Unexpected precision type.");
79             return "";
80     }
81 }
82 
83 /**
84  * Converts a GrSLType to a string containing the name of the equivalent GLSL type.
85  */
GrGLSLTypeString(GrSLType t)86 static inline const char* GrGLSLTypeString(GrSLType t) {
87     switch (t) {
88         case kVoid_GrSLType:
89             return "void";
90         case kFloat_GrSLType:
91             return "float";
92         case kVec2f_GrSLType:
93             return "vec2";
94         case kVec3f_GrSLType:
95             return "vec3";
96         case kVec4f_GrSLType:
97             return "vec4";
98         case kVec2i_GrSLType:
99             return "ivec2";
100         case kVec3i_GrSLType:
101             return "ivec3";
102         case kVec4i_GrSLType:
103             return "ivec4";
104         case kMat22f_GrSLType:
105             return "mat2";
106         case kMat33f_GrSLType:
107             return "mat3";
108         case kMat44f_GrSLType:
109             return "mat4";
110         case kTexture2DSampler_GrSLType:
111             return "sampler2D";
112         case kITexture2DSampler_GrSLType:
113             return "isampler2D";
114         case kTextureExternalSampler_GrSLType:
115             return "samplerExternalOES";
116         case kTexture2DRectSampler_GrSLType:
117             return "sampler2DRect";
118         case kBufferSampler_GrSLType:
119             return "samplerBuffer";
120         case kBool_GrSLType:
121             return "bool";
122         case kInt_GrSLType:
123             return "int";
124         case kUint_GrSLType:
125             return "uint";
126         case kTexture2D_GrSLType:
127             return "texture2D";
128         case kSampler_GrSLType:
129             return "sampler";
130         case kImageStorage2D_GrSLType:
131             return "image2D";
132         case kIImageStorage2D_GrSLType:
133             return "iimage2D";
134     }
135     SkFAIL("Unknown shader var type.");
136     return ""; // suppress warning
137 }
138 
139 /** A generic base-class representing a GLSL expression.
140  * The instance can be a variable name, expression or vecN(0) or vecN(1). Does simple constant
141  * folding with help of 1 and 0.
142  *
143  * Clients should not use this class, rather the specific instantiations defined
144  * later, for example GrGLSLExpr4.
145  */
146 template <typename Self>
147 class GrGLSLExpr {
148 public:
isOnes()149     bool isOnes() const { return kOnes_ExprType == fType; }
isZeros()150     bool isZeros() const { return kZeros_ExprType == fType; }
151 
c_str()152     const char* c_str() const {
153         if (kZeros_ExprType == fType) {
154             return Self::ZerosStr();
155         } else if (kOnes_ExprType == fType) {
156             return Self::OnesStr();
157         }
158         SkASSERT(!fExpr.isEmpty()); // Empty expressions should not be used.
159         return fExpr.c_str();
160     }
161 
isValid()162     bool isValid() const {
163         return kFullExpr_ExprType != fType || !fExpr.isEmpty();
164     }
165 
166 protected:
167     /** Constructs an invalid expression.
168      * Useful only as a return value from functions that never actually return
169      * this and instances that will be assigned to later. */
GrGLSLExpr()170     GrGLSLExpr()
171         : fType(kFullExpr_ExprType) {
172         // The only constructor that is allowed to build an empty expression.
173         SkASSERT(!this->isValid());
174     }
175 
176     /** Constructs an expression with all components as value v */
GrGLSLExpr(int v)177     explicit GrGLSLExpr(int v) {
178         if (v == 0) {
179             fType = kZeros_ExprType;
180         } else if (v == 1) {
181             fType = kOnes_ExprType;
182         } else {
183             fType = kFullExpr_ExprType;
184             fExpr.appendf(Self::CastIntStr(), v);
185         }
186     }
187 
188     /** Constructs an expression from a string.
189      * Argument expr is a simple expression or a parenthesized expression. */
190     // TODO: make explicit once effects input Exprs.
GrGLSLExpr(const char expr[])191     GrGLSLExpr(const char expr[]) {
192         if (nullptr == expr) {  // TODO: remove this once effects input Exprs.
193             fType = kOnes_ExprType;
194         } else {
195             fType = kFullExpr_ExprType;
196             fExpr = expr;
197         }
198         SkASSERT(this->isValid());
199     }
200 
201     /** Constructs an expression from a string.
202      * Argument expr is a simple expression or a parenthesized expression. */
203     // TODO: make explicit once effects input Exprs.
GrGLSLExpr(const SkString & expr)204     GrGLSLExpr(const SkString& expr) {
205         if (expr.isEmpty()) {  // TODO: remove this once effects input Exprs.
206             fType = kOnes_ExprType;
207         } else {
208             fType = kFullExpr_ExprType;
209             fExpr = expr;
210         }
211         SkASSERT(this->isValid());
212     }
213 
214     /** Constructs an expression from a string with one substitution. */
GrGLSLExpr(const char format[],const char in0[])215     GrGLSLExpr(const char format[], const char in0[])
216         : fType(kFullExpr_ExprType) {
217         fExpr.appendf(format, in0);
218     }
219 
220     /** Constructs an expression from a string with two substitutions. */
GrGLSLExpr(const char format[],const char in0[],const char in1[])221     GrGLSLExpr(const char format[], const char in0[], const char in1[])
222         : fType(kFullExpr_ExprType) {
223         fExpr.appendf(format, in0, in1);
224     }
225 
226     /** Returns expression casted to another type.
227      * Generic implementation that is called for non-trivial cases of casts. */
228     template <typename T>
229     static Self VectorCastImpl(const T& other);
230 
231     /** Returns a GLSL multiplication: component-wise or component-by-scalar.
232      * The multiplication will be component-wise or multiply each component by a scalar.
233      *
234      * The returned expression will compute the value of:
235      *    vecN(in0.x * in1.x, ...) if dim(T0) == dim(T1) (component-wise)
236      *    vecN(in0.x * in1, ...) if dim(T1) == 1 (vector by scalar)
237      *    vecN(in0 * in1.x, ...) if dim(T0) == 1 (scalar by vector)
238      */
239     template <typename T0, typename T1>
240     static Self Mul(T0 in0, T1 in1);
241 
242     /** Returns a GLSL addition: component-wise or add a scalar to each component.
243      * Return value computes:
244      *   vecN(in0.x + in1.x, ...) or vecN(in0.x + in1, ...) or vecN(in0 + in1.x, ...).
245      */
246     template <typename T0, typename T1>
247     static Self Add(T0 in0, T1 in1);
248 
249     /** Returns a GLSL subtraction: component-wise or subtract compoments by a scalar.
250      * Return value computes
251      *   vecN(in0.x - in1.x, ...) or vecN(in0.x - in1, ...) or vecN(in0 - in1.x, ...).
252      */
253     template <typename T0, typename T1>
254     static Self Sub(T0 in0, T1 in1);
255 
256     /** Returns expression that accesses component(s) of the expression.
257      * format should be the form "%s.x" where 'x' is the component(s) to access.
258      * Caller is responsible for making sure the amount of components in the
259      * format string is equal to dim(T).
260      */
261     template <typename T>
262     T extractComponents(const char format[]) const;
263 
264 private:
265     enum ExprType {
266         kZeros_ExprType,
267         kOnes_ExprType,
268         kFullExpr_ExprType,
269     };
270     ExprType fType;
271     SkString fExpr;
272 };
273 
274 class GrGLSLExpr1;
275 class GrGLSLExpr4;
276 
277 /** Class representing a float GLSL expression. */
278 class GrGLSLExpr1 : public GrGLSLExpr<GrGLSLExpr1> {
279 public:
GrGLSLExpr1()280     GrGLSLExpr1()
281         : INHERITED() {
282     }
GrGLSLExpr1(int v)283     explicit GrGLSLExpr1(int v)
284         : INHERITED(v) {
285     }
GrGLSLExpr1(const char * expr)286     GrGLSLExpr1(const char* expr)
287         : INHERITED(expr) {
288     }
GrGLSLExpr1(const SkString & expr)289     GrGLSLExpr1(const SkString& expr)
290         : INHERITED(expr) {
291     }
292 
293     static GrGLSLExpr1 VectorCast(const GrGLSLExpr1& expr);
294 
295 private:
GrGLSLExpr1(const char format[],const char in0[])296     GrGLSLExpr1(const char format[], const char in0[])
297         : INHERITED(format, in0) {
298     }
GrGLSLExpr1(const char format[],const char in0[],const char in1[])299     GrGLSLExpr1(const char format[], const char in0[], const char in1[])
300         : INHERITED(format, in0, in1) {
301     }
302 
303     static const char* ZerosStr();
304     static const char* OnesStr();
305     static const char* CastStr();
306     static const char* CastIntStr();
307 
308     friend GrGLSLExpr1 operator*(const GrGLSLExpr1& in0, const GrGLSLExpr1&in1);
309     friend GrGLSLExpr1 operator+(const GrGLSLExpr1& in0, const GrGLSLExpr1&in1);
310     friend GrGLSLExpr1 operator-(const GrGLSLExpr1& in0, const GrGLSLExpr1&in1);
311 
312     friend class GrGLSLExpr<GrGLSLExpr1>;
313     friend class GrGLSLExpr<GrGLSLExpr4>;
314 
315     typedef GrGLSLExpr<GrGLSLExpr1> INHERITED;
316 };
317 
318 /** Class representing a float vector (vec4) GLSL expression. */
319 class GrGLSLExpr4 : public GrGLSLExpr<GrGLSLExpr4> {
320 public:
GrGLSLExpr4()321     GrGLSLExpr4()
322         : INHERITED() {
323     }
GrGLSLExpr4(int v)324     explicit GrGLSLExpr4(int v)
325         : INHERITED(v) {
326     }
GrGLSLExpr4(const char * expr)327     GrGLSLExpr4(const char* expr)
328         : INHERITED(expr) {
329     }
GrGLSLExpr4(const SkString & expr)330     GrGLSLExpr4(const SkString& expr)
331         : INHERITED(expr) {
332     }
333 
334     typedef GrGLSLExpr1 AExpr;
335     AExpr a() const;
336 
337     /** GLSL vec4 cast / constructor, eg vec4(floatv) -> vec4(floatv, floatv, floatv, floatv) */
338     static GrGLSLExpr4 VectorCast(const GrGLSLExpr1& expr);
339     static GrGLSLExpr4 VectorCast(const GrGLSLExpr4& expr);
340 
341 private:
GrGLSLExpr4(const char format[],const char in0[])342     GrGLSLExpr4(const char format[], const char in0[])
343         : INHERITED(format, in0) {
344     }
GrGLSLExpr4(const char format[],const char in0[],const char in1[])345     GrGLSLExpr4(const char format[], const char in0[], const char in1[])
346         : INHERITED(format, in0, in1) {
347     }
348 
349     static const char* ZerosStr();
350     static const char* OnesStr();
351     static const char* CastStr();
352     static const char* CastIntStr();
353 
354     // The vector-by-scalar and scalar-by-vector binary operations.
355     friend GrGLSLExpr4 operator*(const GrGLSLExpr1& in0, const GrGLSLExpr4&in1);
356     friend GrGLSLExpr4 operator+(const GrGLSLExpr1& in0, const GrGLSLExpr4&in1);
357     friend GrGLSLExpr4 operator-(const GrGLSLExpr1& in0, const GrGLSLExpr4&in1);
358     friend GrGLSLExpr4 operator*(const GrGLSLExpr4& in0, const GrGLSLExpr1&in1);
359     friend GrGLSLExpr4 operator+(const GrGLSLExpr4& in0, const GrGLSLExpr1&in1);
360     friend GrGLSLExpr4 operator-(const GrGLSLExpr4& in0, const GrGLSLExpr1&in1);
361 
362     // The vector-by-vector, i.e. component-wise, binary operations.
363     friend GrGLSLExpr4 operator*(const GrGLSLExpr4& in0, const GrGLSLExpr4&in1);
364     friend GrGLSLExpr4 operator+(const GrGLSLExpr4& in0, const GrGLSLExpr4&in1);
365     friend GrGLSLExpr4 operator-(const GrGLSLExpr4& in0, const GrGLSLExpr4&in1);
366 
367     friend class GrGLSLExpr<GrGLSLExpr4>;
368 
369     typedef GrGLSLExpr<GrGLSLExpr4> INHERITED;
370 };
371 
372 /**
373  * Does an inplace mul, *=, of vec4VarName by mulFactor.
374  * A semicolon is added after the assignment.
375  */
376 void GrGLSLMulVarBy4f(SkString* outAppend, const char* vec4VarName, const GrGLSLExpr4& mulFactor);
377 
378 #include "GrGLSL_impl.h"
379 
380 #endif
381