Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2016 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 GrShaderVar_DEFINED
      9 #define GrShaderVar_DEFINED
     10 
     11 #include "SkString.h"
     12 #include "GrTypesPriv.h"
     13 
     14 class GrShaderCaps;
     15 
     16 #define USE_UNIFORM_FLOAT_ARRAYS true
     17 
     18 /**
     19  * Represents a variable in a shader
     20  */
     21 class GrShaderVar {
     22 public:
     23     enum TypeModifier {
     24         kNone_TypeModifier,
     25         kOut_TypeModifier,
     26         kIn_TypeModifier,
     27         kInOut_TypeModifier,
     28         kUniform_TypeModifier,
     29     };
     30 
     31     /**
     32      * Values for array count that have special meaning. We allow 1-sized arrays.git
     33      */
     34     enum {
     35         kNonArray     =  0, // not an array
     36         kUnsizedArray = -1, // an unsized array (declared with [])
     37     };
     38 
     39     /**
     40      * Defaults to a non-arry half with no type modifier or layout qualifier.
     41      */
     42     GrShaderVar()
     43         : fType(kHalf_GrSLType)
     44         , fTypeModifier(kNone_TypeModifier)
     45         , fCount(kNonArray)
     46         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
     47     }
     48 
     49     GrShaderVar(const SkString& name, GrSLType type, int arrayCount = kNonArray,
     50                 GrSLPrecision precision = kDefault_GrSLPrecision)
     51         : fType(type)
     52         , fTypeModifier(kNone_TypeModifier)
     53         , fCount(arrayCount)
     54         , fPrecision(precision)
     55         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
     56         , fName(name) {
     57         SkASSERT(kVoid_GrSLType != type);
     58         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
     59     }
     60 
     61     GrShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
     62                 GrSLPrecision precision = kDefault_GrSLPrecision)
     63         : fType(type)
     64         , fTypeModifier(kNone_TypeModifier)
     65         , fCount(arrayCount)
     66         , fPrecision(precision)
     67         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
     68         , fName(name) {
     69         SkASSERT(kVoid_GrSLType != type);
     70         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
     71     }
     72 
     73     GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
     74                 GrSLPrecision precision = kDefault_GrSLPrecision)
     75         : fType(type)
     76         , fTypeModifier(typeModifier)
     77         , fCount(kNonArray)
     78         , fPrecision(precision)
     79         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
     80         , fName(name) {
     81         SkASSERT(kVoid_GrSLType != type);
     82     }
     83 
     84     GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
     85                 int arrayCount, GrSLPrecision precision = kDefault_GrSLPrecision)
     86         : fType(type)
     87         , fTypeModifier(typeModifier)
     88         , fCount(arrayCount)
     89         , fPrecision(precision)
     90         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
     91         , fName(name) {
     92         SkASSERT(kVoid_GrSLType != type);
     93     }
     94 
     95     GrShaderVar(const GrShaderVar& that)
     96         : fType(that.fType)
     97         , fTypeModifier(that.fTypeModifier)
     98         , fCount(that.fCount)
     99         , fPrecision(that.fPrecision)
    100         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS)
    101         , fName(that.fName)
    102         , fLayoutQualifier(that.fLayoutQualifier)
    103         , fExtraModifiers(that.fExtraModifiers) {
    104         SkASSERT(kVoid_GrSLType != that.getType());
    105     }
    106 
    107     /**
    108      * Sets as a non-array.
    109      */
    110     void set(GrSLType type,
    111              const SkString& name,
    112              TypeModifier typeModifier = kNone_TypeModifier,
    113              GrSLPrecision precision = kDefault_GrSLPrecision,
    114              const char* layoutQualifier = nullptr,
    115              const char* extraModifiers = nullptr,
    116              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    117         SkASSERT(kVoid_GrSLType != type);
    118         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeTemporarilyAcceptsPrecision(type));
    119         fType = type;
    120         fTypeModifier = typeModifier;
    121         fName = name;
    122         fCount = kNonArray;
    123         fPrecision = precision;
    124         fLayoutQualifier = layoutQualifier;
    125         if (extraModifiers) {
    126             fExtraModifiers.printf("%s ", extraModifiers);
    127         }
    128         fUseUniformFloatArrays = useUniformFloatArrays;
    129     }
    130 
    131     /**
    132      * Sets as a non-array.
    133      */
    134     void set(GrSLType type,
    135              const char* name,
    136              TypeModifier typeModifier = kNone_TypeModifier,
    137              GrSLPrecision precision = kDefault_GrSLPrecision,
    138              const char* layoutQualifier = nullptr,
    139              const char* extraModifiers = nullptr,
    140              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    141         SkASSERT(kVoid_GrSLType != type);
    142         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeTemporarilyAcceptsPrecision(type));
    143         fType = type;
    144         fTypeModifier = typeModifier;
    145         fName = name;
    146         fCount = kNonArray;
    147         fPrecision = precision;
    148         fLayoutQualifier = layoutQualifier;
    149         if (extraModifiers) {
    150             fExtraModifiers.printf("%s ", extraModifiers);
    151         }
    152         fUseUniformFloatArrays = useUniformFloatArrays;
    153     }
    154 
    155     /**
    156      * Set all var options
    157      */
    158     void set(GrSLType type,
    159              const SkString& name,
    160              int count,
    161              TypeModifier typeModifier,
    162              GrSLPrecision precision = kDefault_GrSLPrecision,
    163              const char* layoutQualifier = nullptr,
    164              const char* extraModifiers = nullptr,
    165              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    166         SkASSERT(kVoid_GrSLType != type);
    167         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeTemporarilyAcceptsPrecision(type));
    168         fType = type;
    169         fTypeModifier = typeModifier;
    170         fName = name;
    171         fCount = count;
    172         fPrecision = precision;
    173         fLayoutQualifier = layoutQualifier;
    174         if (extraModifiers) {
    175             fExtraModifiers.printf("%s ", extraModifiers);
    176         }
    177         fUseUniformFloatArrays = useUniformFloatArrays;
    178     }
    179 
    180     /**
    181      * Set all var options
    182      */
    183     void set(GrSLType type,
    184              const char* name,
    185              int count,
    186              TypeModifier typeModifier,
    187              GrSLPrecision precision = kDefault_GrSLPrecision,
    188              const char* layoutQualifier = nullptr,
    189              const char* extraModifiers = nullptr,
    190              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    191         SkASSERT(kVoid_GrSLType != type);
    192         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeTemporarilyAcceptsPrecision(type));
    193         fType = type;
    194         fTypeModifier = typeModifier;
    195         fName = name;
    196         fCount = count;
    197         fPrecision = precision;
    198         fLayoutQualifier = layoutQualifier;
    199         if (extraModifiers) {
    200             fExtraModifiers.printf("%s ", extraModifiers);
    201         }
    202         fUseUniformFloatArrays = useUniformFloatArrays;
    203     }
    204 
    205     /**
    206      * Is the var an array.
    207      */
    208     bool isArray() const { return kNonArray != fCount; }
    209     /**
    210      * Is this an unsized array, (i.e. declared with []).
    211      */
    212     bool isUnsizedArray() const { return kUnsizedArray == fCount; }
    213     /**
    214      * Get the array length of the var.
    215      */
    216     int getArrayCount() const { return fCount; }
    217     /**
    218      * Set the array length of the var
    219      */
    220     void setArrayCount(int count) { fCount = count; }
    221     /**
    222      * Set to be a non-array.
    223      */
    224     void setNonArray() { fCount = kNonArray; }
    225     /**
    226      * Set to be an unsized array.
    227      */
    228     void setUnsizedArray() { fCount = kUnsizedArray; }
    229 
    230     /**
    231      * Access the var name as a writable string
    232      */
    233     SkString* accessName() { return &fName; }
    234     /**
    235      * Set the var name
    236      */
    237     void setName(const SkString& n) { fName = n; }
    238     void setName(const char* n) { fName = n; }
    239 
    240     /**
    241      * Get the var name.
    242      */
    243     const SkString& getName() const { return fName; }
    244 
    245     /**
    246      * Shortcut for this->getName().c_str();
    247      */
    248     const char* c_str() const { return this->getName().c_str(); }
    249 
    250     /**
    251      * Get the type of the var
    252      */
    253     GrSLType getType() const { return fType; }
    254     /**
    255      * Set the type of the var
    256      */
    257     void setType(GrSLType type) { fType = type; }
    258 
    259     TypeModifier getTypeModifier() const { return fTypeModifier; }
    260     void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
    261 
    262     /**
    263      * Get the precision of the var
    264      */
    265     GrSLPrecision getPrecision() const { return fPrecision; }
    266 
    267     /**
    268      * Set the precision of the var
    269      */
    270     void setPrecision(GrSLPrecision p) { fPrecision = p; }
    271 
    272     /**
    273      * Appends to the layout qualifier
    274      */
    275     void addLayoutQualifier(const char* layoutQualifier) {
    276         if (!layoutQualifier || !strlen(layoutQualifier)) {
    277             return;
    278         }
    279         if (fLayoutQualifier.isEmpty()) {
    280             fLayoutQualifier = layoutQualifier;
    281         } else {
    282             fLayoutQualifier.appendf(", %s", layoutQualifier);
    283         }
    284     }
    285 
    286     void setIOType(GrIOType);
    287 
    288     void addModifier(const char* modifier) {
    289         if (modifier) {
    290             fExtraModifiers.appendf("%s ", modifier);
    291         }
    292     }
    293 
    294     /**
    295      * Write a declaration of this variable to out.
    296      */
    297     void appendDecl(const GrShaderCaps*, SkString* out) const;
    298 
    299     void appendArrayAccess(int index, SkString* out) const {
    300         out->appendf("%s[%d]%s",
    301                      this->getName().c_str(),
    302                      index,
    303                      fUseUniformFloatArrays ? "" : ".x");
    304     }
    305 
    306     void appendArrayAccess(const char* indexName, SkString* out) const {
    307         out->appendf("%s[%s]%s",
    308                      this->getName().c_str(),
    309                      indexName,
    310                      fUseUniformFloatArrays ? "" : ".x");
    311     }
    312 
    313 private:
    314     GrSLType        fType;
    315     TypeModifier    fTypeModifier;
    316     int             fCount;
    317     GrSLPrecision   fPrecision;
    318     /// Work around driver bugs on some hardware that don't correctly
    319     /// support uniform float []
    320     bool            fUseUniformFloatArrays;
    321 
    322     SkString        fName;
    323     SkString        fLayoutQualifier;
    324     SkString        fExtraModifiers;
    325 };
    326 
    327 #endif
    328