Home | History | Annotate | Download | only in gl
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #ifndef GrGLShaderVar_DEFINED
     10 #define GrGLShaderVar_DEFINED
     11 
     12 #include "GrGLContextInfo.h"
     13 #include "GrGLSL.h"
     14 #include "../GrStringBuilder.h"
     15 
     16 #define USE_UNIFORM_FLOAT_ARRAYS true
     17 
     18 /**
     19  * Represents a variable in a shader
     20  */
     21 class GrGLShaderVar {
     22 public:
     23 
     24     enum Type {
     25         kFloat_Type,
     26         kVec2f_Type,
     27         kVec3f_Type,
     28         kVec4f_Type,
     29         kMat33f_Type,
     30         kMat44f_Type,
     31         kSampler2D_Type,
     32     };
     33 
     34     /**
     35      * Early versions of GLSL have Varying and Attribute; those are later
     36      * deprecated, but we still need to know whether a Varying variable
     37      * should be treated as In or Out.
     38      */
     39     enum TypeModifier {
     40         kNone_TypeModifier,
     41         kOut_TypeModifier,
     42         kIn_TypeModifier,
     43         kUniform_TypeModifier,
     44         kAttribute_TypeModifier
     45     };
     46 
     47     /**
     48      * Defaults to a float with no precision specifier
     49      */
     50     GrGLShaderVar() {
     51         fType = kFloat_Type;
     52         fTypeModifier = kNone_TypeModifier;
     53         fCount = kNonArray;
     54         fEmitPrecision = false;
     55         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
     56     }
     57 
     58     GrGLShaderVar(const GrGLShaderVar& var)
     59         : fType(var.fType)
     60         , fTypeModifier(var.fTypeModifier)
     61         , fName(var.fName)
     62         , fCount(var.fCount)
     63         , fEmitPrecision(var.fEmitPrecision)
     64         , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
     65 
     66     /**
     67      * Values for array count that have special meaning. We allow 1-sized arrays.
     68      */
     69     enum {
     70         kNonArray     =  0, // not an array
     71         kUnsizedArray = -1, // an unsized array (declared with [])
     72     };
     73 
     74     /**
     75      * Sets as a non-array.
     76      */
     77     void set(Type type,
     78              TypeModifier typeModifier,
     79              const GrStringBuilder& name,
     80              bool emitPrecision = false,
     81              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
     82         fType = type;
     83         fTypeModifier = typeModifier;
     84         fName = name;
     85         fCount = kNonArray;
     86         fEmitPrecision = emitPrecision;
     87         fUseUniformFloatArrays = useUniformFloatArrays;
     88     }
     89 
     90     /**
     91      * Sets as a non-array.
     92      */
     93     void set(Type type,
     94              TypeModifier typeModifier,
     95              const char* name,
     96              bool specifyPrecision = false,
     97              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
     98         fType = type;
     99         fTypeModifier = typeModifier;
    100         fName = name;
    101         fCount = kNonArray;
    102         fEmitPrecision = specifyPrecision;
    103         fUseUniformFloatArrays = useUniformFloatArrays;
    104     }
    105 
    106     /**
    107      * Set all var options
    108      */
    109     void set(Type type,
    110              TypeModifier typeModifier,
    111              const GrStringBuilder& name,
    112              int count,
    113              bool specifyPrecision = false,
    114              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    115         fType = type;
    116         fTypeModifier = typeModifier;
    117         fName = name;
    118         fCount = count;
    119         fEmitPrecision = specifyPrecision;
    120         fUseUniformFloatArrays = useUniformFloatArrays;
    121     }
    122 
    123     /**
    124      * Set all var options
    125      */
    126     void set(Type type,
    127              TypeModifier typeModifier,
    128              const char* name,
    129              int count,
    130              bool specifyPrecision = false,
    131              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    132         fType = type;
    133         fTypeModifier = typeModifier;
    134         fName = name;
    135         fCount = count;
    136         fEmitPrecision = specifyPrecision;
    137         fUseUniformFloatArrays = useUniformFloatArrays;
    138     }
    139 
    140     /**
    141      * Is the var an array.
    142      */
    143     bool isArray() const { return kNonArray != fCount; }
    144     /**
    145      * Is this an unsized array, (i.e. declared with []).
    146      */
    147     bool isUnsizedArray() const { return kUnsizedArray == fCount; }
    148     /**
    149      * Get the array length of the var.
    150      */
    151     int getArrayCount() const { return fCount; }
    152     /**
    153      * Set the array length of the var
    154      */
    155     void setArrayCount(int count) { fCount = count; }
    156     /**
    157      * Set to be a non-array.
    158      */
    159     void setNonArray() { fCount = kNonArray; }
    160     /**
    161      * Set to be an unsized array.
    162      */
    163     void setUnsizedArray() { fCount = kUnsizedArray; }
    164 
    165     /**
    166      * Access the var name as a writable string
    167      */
    168     GrStringBuilder* accessName() { return &fName; }
    169     /**
    170      * Set the var name
    171      */
    172     void setName(const GrStringBuilder& n) { fName = n; }
    173     void setName(const char* n) { fName = n; }
    174     /**
    175      * Get the var name.
    176      */
    177     const GrStringBuilder& getName() const { return fName; }
    178 
    179     /**
    180      * Get the type of the var
    181      */
    182     Type getType() const { return fType; }
    183     /**
    184      * Set the type of the var
    185      */
    186     void setType(Type type) { fType = type; }
    187 
    188     TypeModifier getTypeModifier() const { return fTypeModifier; }
    189     void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
    190 
    191     /**
    192      * Must the variable declaration emit a precision specifier
    193      */
    194     bool emitsPrecision() const { return fEmitPrecision; }
    195     /**
    196      * Specify whether the declaration should specify precision
    197      */
    198     void setEmitPrecision(bool p) { fEmitPrecision = p; }
    199 
    200     /**
    201      * Write a declaration of this variable to out.
    202      */
    203     void appendDecl(const GrGLContextInfo& gl, GrStringBuilder* out) const {
    204         if (this->getTypeModifier() != kNone_TypeModifier) {
    205            out->append(TypeModifierString(this->getTypeModifier(),
    206                                           gl.glslGeneration()));
    207            out->append(" ");
    208         }
    209         if (this->emitsPrecision()) {
    210             out->append(GrGetGLSLVarPrecisionDeclType(gl.binding()));
    211             out->append(" ");
    212         }
    213         Type effectiveType = this->getType();
    214         if (this->isArray()) {
    215             if (this->isUnsizedArray()) {
    216                 out->appendf("%s %s[]",
    217                              TypeString(effectiveType),
    218                              this->getName().c_str());
    219             } else {
    220                 GrAssert(this->getArrayCount() > 0);
    221                 out->appendf("%s %s[%d]",
    222                              TypeString(effectiveType),
    223                              this->getName().c_str(),
    224                              this->getArrayCount());
    225             }
    226         } else {
    227             out->appendf("%s %s",
    228                          TypeString(effectiveType),
    229                          this->getName().c_str());
    230         }
    231         out->append(";\n");
    232     }
    233 
    234     static const char* TypeString(Type t) {
    235         switch (t) {
    236             case kFloat_Type:
    237                 return "float";
    238             case kVec2f_Type:
    239                 return "vec2";
    240             case kVec3f_Type:
    241                 return "vec3";
    242             case kVec4f_Type:
    243                 return "vec4";
    244             case kMat33f_Type:
    245                 return "mat3";
    246             case kMat44f_Type:
    247                 return "mat4";
    248             case kSampler2D_Type:
    249                 return "sampler2D";
    250             default:
    251                 GrCrash("Unknown shader var type.");
    252                 return ""; // suppress warning
    253         }
    254     }
    255 
    256     void appendArrayAccess(int index, GrStringBuilder* out) {
    257         out->appendf("%s[%d]%s",
    258                      this->getName().c_str(),
    259                      index,
    260                      fUseUniformFloatArrays ? "" : ".x");
    261     }
    262 
    263     void appendArrayAccess(const char* indexName, GrStringBuilder* out) {
    264         out->appendf("%s[%s]%s",
    265                      this->getName().c_str(),
    266                      indexName,
    267                      fUseUniformFloatArrays ? "" : ".x");
    268     }
    269 
    270 private:
    271     static const char* TypeModifierString(TypeModifier t,
    272                                           GrGLSLGeneration gen) {
    273         switch (t) {
    274             case kNone_TypeModifier:
    275                 return "";
    276             case kOut_TypeModifier:
    277                 return k110_GrGLSLGeneration == gen ? "varying" : "out";
    278             case kIn_TypeModifier:
    279                 return k110_GrGLSLGeneration == gen ? "varying" : "in";
    280             case kUniform_TypeModifier:
    281                 return "uniform";
    282             case kAttribute_TypeModifier:
    283                 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
    284             default:
    285                 GrCrash("Unknown shader variable type modifier.");
    286                 return ""; // suppress warning
    287         }
    288     }
    289 
    290     Type            fType;
    291     TypeModifier    fTypeModifier;
    292     GrStringBuilder fName;
    293     int             fCount;
    294     bool            fEmitPrecision;
    295     /// Work around driver bugs on some hardware that don't correctly
    296     /// support uniform float []
    297     bool            fUseUniformFloatArrays;
    298 };
    299 
    300 #endif
    301