Home | History | Annotate | Download | only in glsl
      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  */
     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  */
     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:
    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 
    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. */
    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 
    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:
    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 
    279 private:
    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. */
    303 class GrGLSLExpr4 : public GrGLSLExpr<GrGLSLExpr4> {
    304 public:
    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 
    325 private:
    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  */
    360 void GrGLSLMulVarBy4f(SkString* outAppend, const char* vec4VarName, const GrGLSLExpr4& mulFactor);
    361 
    362 #include "GrGLSL_impl.h"
    363 
    364 #endif
    365