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