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