Home | History | Annotate | Download | only in gl
      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 GrGLShaderVar_DEFINED
      9 #define GrGLShaderVar_DEFINED
     10 
     11 #include "GrGLContext.h"
     12 #include "GrGLSL.h"
     13 #include "GrShaderVar.h"
     14 
     15 #define USE_UNIFORM_FLOAT_ARRAYS true
     16 
     17 /**
     18  * Represents a variable in a shader
     19  */
     20 class GrGLShaderVar : public GrShaderVar {
     21 public:
     22     /**
     23      * See GL_ARB_fragment_coord_conventions.
     24      */
     25     enum Origin {
     26         kDefault_Origin,        // when set to kDefault the origin field is ignored.
     27         kUpperLeft_Origin,      // only used to declare vec4 in gl_FragCoord.
     28     };
     29 
     30     /**
     31      * Defaults to a float with no precision specifier
     32      */
     33     GrGLShaderVar()
     34         : GrShaderVar()
     35         , fOrigin(kDefault_Origin)
     36         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
     37     }
     38 
     39     GrGLShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray,
     40                   Precision precision = kDefault_Precision)
     41         : GrShaderVar(name, type, arrayCount, precision)
     42         , fOrigin(kDefault_Origin)
     43         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
     44         SkASSERT(kVoid_GrSLType != type);
     45         fOrigin = kDefault_Origin;
     46         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
     47     }
     48 
     49     GrGLShaderVar(const char* name, GrSLType type, TypeModifier typeModifier,
     50                   int arrayCount = kNonArray, Precision precision = kDefault_Precision)
     51         : GrShaderVar(name, type, typeModifier, arrayCount, precision)
     52         , fOrigin(kDefault_Origin)
     53         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
     54         SkASSERT(kVoid_GrSLType != type);
     55     }
     56 
     57     GrGLShaderVar(const GrShaderVar& var)
     58         : GrShaderVar(var)
     59         , fOrigin(kDefault_Origin)
     60         , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) {
     61         SkASSERT(kVoid_GrSLType != var.getType());
     62     }
     63 
     64     GrGLShaderVar(const GrGLShaderVar& var)
     65         : GrShaderVar(var.c_str(), var.getType(), var.getTypeModifier(),
     66                       var.getArrayCount(), var.getPrecision())
     67         , fOrigin(var.fOrigin)
     68         , fUseUniformFloatArrays(var.fUseUniformFloatArrays) {
     69         SkASSERT(kVoid_GrSLType != var.getType());
     70     }
     71 
     72     /**
     73      * Values for array count that have special meaning. We allow 1-sized arrays.
     74      */
     75     enum {
     76         kNonArray     =  0, // not an array
     77         kUnsizedArray = -1, // an unsized array (declared with [])
     78     };
     79 
     80     /**
     81      * Sets as a non-array.
     82      */
     83     void set(GrSLType type,
     84              TypeModifier typeModifier,
     85              const SkString& name,
     86              Precision precision = kDefault_Precision,
     87              Origin origin = kDefault_Origin,
     88              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
     89         SkASSERT(kVoid_GrSLType != type);
     90         INHERITED::set(type, typeModifier, name, precision);
     91         fOrigin = origin;
     92         fUseUniformFloatArrays = useUniformFloatArrays;
     93     }
     94 
     95     /**
     96      * Sets as a non-array.
     97      */
     98     void set(GrSLType type,
     99              TypeModifier typeModifier,
    100              const char* name,
    101              Precision precision = kDefault_Precision,
    102              Origin origin = kDefault_Origin,
    103              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    104         SkASSERT(kVoid_GrSLType != type);
    105         INHERITED::set(type, typeModifier, name, precision);
    106         fOrigin = origin;
    107         fUseUniformFloatArrays = useUniformFloatArrays;
    108     }
    109 
    110     /**
    111      * Set all var options
    112      */
    113     void set(GrSLType type,
    114              TypeModifier typeModifier,
    115              const SkString& name,
    116              int count,
    117              Precision precision = kDefault_Precision,
    118              Origin origin = kDefault_Origin,
    119              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    120         SkASSERT(kVoid_GrSLType != type);
    121         INHERITED::set(type, typeModifier, name, count, precision);
    122         fOrigin = origin;
    123         fUseUniformFloatArrays = useUniformFloatArrays;
    124     }
    125 
    126     /**
    127      * Set all var options
    128      */
    129     void set(GrSLType type,
    130              TypeModifier typeModifier,
    131              const char* name,
    132              int count,
    133              Precision precision = kDefault_Precision,
    134              Origin origin = kDefault_Origin,
    135              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    136         SkASSERT(kVoid_GrSLType != type);
    137         INHERITED::set(type, typeModifier, name, count, precision);
    138         fOrigin = origin;
    139         fUseUniformFloatArrays = useUniformFloatArrays;
    140     }
    141 
    142     /**
    143      * Get the origin of the var
    144      */
    145     Origin getOrigin() const { return fOrigin; }
    146 
    147     /**
    148      * Set the origin of the var
    149      */
    150     void setOrigin(Origin origin) { fOrigin = origin; }
    151 
    152     /**
    153      * Write a declaration of this variable to out.
    154      */
    155     void appendDecl(const GrGLContextInfo& ctxInfo, SkString* out) const {
    156         if (kUpperLeft_Origin == fOrigin) {
    157             // this is the only place where we specify a layout modifier. If we use other layout
    158             // modifiers in the future then they should be placed in a list.
    159             out->append("layout(origin_upper_left) ");
    160         }
    161         if (this->getTypeModifier() != kNone_TypeModifier) {
    162            out->append(TypeModifierString(this->getTypeModifier(),
    163                                           ctxInfo.glslGeneration()));
    164            out->append(" ");
    165         }
    166         out->append(PrecisionString(fPrecision, ctxInfo.standard()));
    167         GrSLType effectiveType = this->getType();
    168         if (this->isArray()) {
    169             if (this->isUnsizedArray()) {
    170                 out->appendf("%s %s[]",
    171                              GrGLSLTypeString(effectiveType),
    172                              this->getName().c_str());
    173             } else {
    174                 SkASSERT(this->getArrayCount() > 0);
    175                 out->appendf("%s %s[%d]",
    176                              GrGLSLTypeString(effectiveType),
    177                              this->getName().c_str(),
    178                              this->getArrayCount());
    179             }
    180         } else {
    181             out->appendf("%s %s",
    182                          GrGLSLTypeString(effectiveType),
    183                          this->getName().c_str());
    184         }
    185     }
    186 
    187     void appendArrayAccess(int index, SkString* out) const {
    188         out->appendf("%s[%d]%s",
    189                      this->getName().c_str(),
    190                      index,
    191                      fUseUniformFloatArrays ? "" : ".x");
    192     }
    193 
    194     void appendArrayAccess(const char* indexName, SkString* out) const {
    195         out->appendf("%s[%s]%s",
    196                      this->getName().c_str(),
    197                      indexName,
    198                      fUseUniformFloatArrays ? "" : ".x");
    199     }
    200 
    201     static const char* PrecisionString(Precision p, GrGLStandard standard) {
    202         // Desktop GLSL has added precision qualifiers but they don't do anything.
    203         if (kGLES_GrGLStandard == standard) {
    204             switch (p) {
    205                 case kLow_Precision:
    206                     return "lowp ";
    207                 case kMedium_Precision:
    208                     return "mediump ";
    209                 case kHigh_Precision:
    210                     return "highp ";
    211                 case kDefault_Precision:
    212                     return "";
    213                 default:
    214                     SkFAIL("Unexpected precision type.");
    215             }
    216         }
    217         return "";
    218     }
    219 
    220 private:
    221     static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
    222         switch (t) {
    223             case kNone_TypeModifier:
    224                 return "";
    225             case kIn_TypeModifier:
    226                 return "in";
    227             case kInOut_TypeModifier:
    228                 return "inout";
    229             case kOut_TypeModifier:
    230                 return "out";
    231             case kUniform_TypeModifier:
    232                 return "uniform";
    233             case kAttribute_TypeModifier:
    234                 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
    235             case kVaryingIn_TypeModifier:
    236                 return k110_GrGLSLGeneration == gen ? "varying" : "in";
    237             case kVaryingOut_TypeModifier:
    238                 return k110_GrGLSLGeneration == gen ? "varying" : "out";
    239             default:
    240                 SkFAIL("Unknown shader variable type modifier.");
    241                 return ""; // suppress warning
    242         }
    243     }
    244 
    245     Origin          fOrigin;
    246     /// Work around driver bugs on some hardware that don't correctly
    247     /// support uniform float []
    248     bool            fUseUniformFloatArrays;
    249 
    250     typedef GrShaderVar INHERITED;
    251 };
    252 
    253 #endif
    254