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                   GrSLPrecision precision = kDefault_GrSLPrecision)
     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, GrSLPrecision precision = kDefault_GrSLPrecision)
     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              GrSLPrecision precision = kDefault_GrSLPrecision,
     87              Origin origin = kDefault_Origin,
     88              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
     89         SkASSERT(kVoid_GrSLType != type);
     90         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
     91         INHERITED::set(type, name, typeModifier, precision);
     92         fOrigin = origin;
     93         fUseUniformFloatArrays = useUniformFloatArrays;
     94     }
     95 
     96     /**
     97      * Sets as a non-array.
     98      */
     99     void set(GrSLType type,
    100              TypeModifier typeModifier,
    101              const char* name,
    102              GrSLPrecision precision = kDefault_GrSLPrecision,
    103              Origin origin = kDefault_Origin,
    104              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    105         SkASSERT(kVoid_GrSLType != type);
    106         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
    107         INHERITED::set(type, name, typeModifier, precision);
    108         fOrigin = origin;
    109         fUseUniformFloatArrays = useUniformFloatArrays;
    110     }
    111 
    112     /**
    113      * Set all var options
    114      */
    115     void set(GrSLType type,
    116              TypeModifier typeModifier,
    117              const SkString& name,
    118              int count,
    119              GrSLPrecision precision = kDefault_GrSLPrecision,
    120              Origin origin = kDefault_Origin,
    121              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    122         SkASSERT(kVoid_GrSLType != type);
    123         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
    124         INHERITED::set(type, name, typeModifier, precision, count);
    125         fOrigin = origin;
    126         fUseUniformFloatArrays = useUniformFloatArrays;
    127     }
    128 
    129     /**
    130      * Set all var options
    131      */
    132     void set(GrSLType type,
    133              TypeModifier typeModifier,
    134              const char* name,
    135              int count,
    136              GrSLPrecision precision = kDefault_GrSLPrecision,
    137              Origin origin = kDefault_Origin,
    138              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
    139         SkASSERT(kVoid_GrSLType != type);
    140         SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
    141         INHERITED::set(type, name, typeModifier, precision, count);
    142         fOrigin = origin;
    143         fUseUniformFloatArrays = useUniformFloatArrays;
    144     }
    145 
    146     /**
    147      * Get the origin of the var
    148      */
    149     Origin getOrigin() const { return fOrigin; }
    150 
    151     /**
    152      * Set the origin of the var
    153      */
    154     void setOrigin(Origin origin) { fOrigin = origin; }
    155 
    156     /**
    157      * Write a declaration of this variable to out.
    158      */
    159     void appendDecl(const GrGLContextInfo& ctxInfo, SkString* out) const {
    160         SkASSERT(kDefault_GrSLPrecision == fPrecision || GrSLTypeIsFloatType(fType));
    161         if (kUpperLeft_Origin == fOrigin) {
    162             // this is the only place where we specify a layout modifier. If we use other layout
    163             // modifiers in the future then they should be placed in a list.
    164             out->append("layout(origin_upper_left) ");
    165         }
    166         if (this->getTypeModifier() != kNone_TypeModifier) {
    167            out->append(TypeModifierString(this->getTypeModifier(), ctxInfo.glslGeneration()));
    168            out->append(" ");
    169         }
    170         out->append(PrecisionString(fPrecision, ctxInfo.standard()));
    171         GrSLType effectiveType = this->getType();
    172         if (this->isArray()) {
    173             if (this->isUnsizedArray()) {
    174                 out->appendf("%s %s[]",
    175                              GrGLSLTypeString(effectiveType),
    176                              this->getName().c_str());
    177             } else {
    178                 SkASSERT(this->getArrayCount() > 0);
    179                 out->appendf("%s %s[%d]",
    180                              GrGLSLTypeString(effectiveType),
    181                              this->getName().c_str(),
    182                              this->getArrayCount());
    183             }
    184         } else {
    185             out->appendf("%s %s",
    186                          GrGLSLTypeString(effectiveType),
    187                          this->getName().c_str());
    188         }
    189     }
    190 
    191     void appendArrayAccess(int index, SkString* out) const {
    192         out->appendf("%s[%d]%s",
    193                      this->getName().c_str(),
    194                      index,
    195                      fUseUniformFloatArrays ? "" : ".x");
    196     }
    197 
    198     void appendArrayAccess(const char* indexName, SkString* out) const {
    199         out->appendf("%s[%s]%s",
    200                      this->getName().c_str(),
    201                      indexName,
    202                      fUseUniformFloatArrays ? "" : ".x");
    203     }
    204 
    205     static const char* PrecisionString(GrSLPrecision p, GrGLStandard standard) {
    206         // Desktop GLSL has added precision qualifiers but they don't do anything.
    207         if (kGLES_GrGLStandard == standard) {
    208             switch (p) {
    209                 case kLow_GrSLPrecision:
    210                     return "lowp ";
    211                 case kMedium_GrSLPrecision:
    212                     return "mediump ";
    213                 case kHigh_GrSLPrecision:
    214                     return "highp ";
    215                 default:
    216                     SkFAIL("Unexpected precision type.");
    217             }
    218         }
    219         return "";
    220     }
    221 
    222 private:
    223     static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
    224         switch (t) {
    225             case kNone_TypeModifier:
    226                 return "";
    227             case kIn_TypeModifier:
    228                 return "in";
    229             case kInOut_TypeModifier:
    230                 return "inout";
    231             case kOut_TypeModifier:
    232                 return "out";
    233             case kUniform_TypeModifier:
    234                 return "uniform";
    235             case kAttribute_TypeModifier:
    236                 return k110_GrGLSLGeneration == gen ? "attribute" : "in";
    237             case kVaryingIn_TypeModifier:
    238                 return k110_GrGLSLGeneration == gen ? "varying" : "in";
    239             case kVaryingOut_TypeModifier:
    240                 return k110_GrGLSLGeneration == gen ? "varying" : "out";
    241             default:
    242                 SkFAIL("Unknown shader variable type modifier.");
    243                 return ""; // suppress warning
    244         }
    245     }
    246 
    247     Origin          fOrigin;
    248     /// Work around driver bugs on some hardware that don't correctly
    249     /// support uniform float []
    250     bool            fUseUniformFloatArrays;
    251 
    252     typedef GrShaderVar INHERITED;
    253 };
    254 
    255 #endif
    256