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
14class 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.
18enum 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
53bool 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 */
59inline 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 */
82void 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 */
89static 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 */
130template <typename Self>
131class GrGLSLExpr {
132public:
133    bool isOnes() const { return kOnes_ExprType == fType; }
134    bool isZeros() const { return kZeros_ExprType == fType; }
135
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
146    bool isValid() const {
147        return kFullExpr_ExprType != fType || !fExpr.isEmpty();
148    }
149
150protected:
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. */
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 */
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.
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.
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. */
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. */
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
248private:
249    enum ExprType {
250        kZeros_ExprType,
251        kOnes_ExprType,
252        kFullExpr_ExprType,
253    };
254    ExprType fType;
255    SkString fExpr;
256};
257
258class GrGLSLExpr1;
259class GrGLSLExpr4;
260
261/** Class representing a float GLSL expression. */
262class GrGLSLExpr1 : public GrGLSLExpr<GrGLSLExpr1> {
263public:
264    GrGLSLExpr1()
265        : INHERITED() {
266    }
267    explicit GrGLSLExpr1(int v)
268        : INHERITED(v) {
269    }
270    GrGLSLExpr1(const char* expr)
271        : INHERITED(expr) {
272    }
273    GrGLSLExpr1(const SkString& expr)
274        : INHERITED(expr) {
275    }
276
277    static GrGLSLExpr1 VectorCast(const GrGLSLExpr1& expr);
278
279private:
280    GrGLSLExpr1(const char format[], const char in0[])
281        : INHERITED(format, in0) {
282    }
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. */
303class GrGLSLExpr4 : public GrGLSLExpr<GrGLSLExpr4> {
304public:
305    GrGLSLExpr4()
306        : INHERITED() {
307    }
308    explicit GrGLSLExpr4(int v)
309        : INHERITED(v) {
310    }
311    GrGLSLExpr4(const char* expr)
312        : INHERITED(expr) {
313    }
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
325private:
326    GrGLSLExpr4(const char format[], const char in0[])
327        : INHERITED(format, in0) {
328    }
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 */
360void GrGLSLMulVarBy4f(SkString* outAppend, const char* vec4VarName, const GrGLSLExpr4& mulFactor);
361
362#include "GrGLSL_impl.h"
363
364#endif
365