1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/gl/GrGLShaderVar.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,360 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef GrGLShaderVar_DEFINED 1.12 +#define GrGLShaderVar_DEFINED 1.13 + 1.14 +#include "GrGLContext.h" 1.15 +#include "GrGLSL.h" 1.16 +#include "SkString.h" 1.17 + 1.18 +#define USE_UNIFORM_FLOAT_ARRAYS true 1.19 + 1.20 +/** 1.21 + * Represents a variable in a shader 1.22 + */ 1.23 +class GrGLShaderVar { 1.24 +public: 1.25 + 1.26 + /** 1.27 + * Early versions of GLSL have Varying and Attribute; those are later 1.28 + * deprecated, but we still need to know whether a Varying variable 1.29 + * should be treated as In or Out. 1.30 + */ 1.31 + enum TypeModifier { 1.32 + kNone_TypeModifier, 1.33 + kOut_TypeModifier, 1.34 + kIn_TypeModifier, 1.35 + kInOut_TypeModifier, 1.36 + kUniform_TypeModifier, 1.37 + kAttribute_TypeModifier, 1.38 + kVaryingIn_TypeModifier, 1.39 + kVaryingOut_TypeModifier 1.40 + }; 1.41 + 1.42 + enum Precision { 1.43 + kLow_Precision, // lowp 1.44 + kMedium_Precision, // mediump 1.45 + kHigh_Precision, // highp 1.46 + kDefault_Precision, // Default for the current context. We make 1.47 + // fragment shaders default to mediump on ES2 1.48 + // because highp support is not guaranteed (and 1.49 + // we haven't been motivated to test for it). 1.50 + // Otherwise, highp. 1.51 + }; 1.52 + 1.53 + /** 1.54 + * See GL_ARB_fragment_coord_conventions. 1.55 + */ 1.56 + enum Origin { 1.57 + kDefault_Origin, // when set to kDefault the origin field is ignored. 1.58 + kUpperLeft_Origin, // only used to declare vec4 in gl_FragCoord. 1.59 + }; 1.60 + 1.61 + /** 1.62 + * Defaults to a float with no precision specifier 1.63 + */ 1.64 + GrGLShaderVar() { 1.65 + fType = kFloat_GrSLType; 1.66 + fTypeModifier = kNone_TypeModifier; 1.67 + fCount = kNonArray; 1.68 + fPrecision = kDefault_Precision; 1.69 + fOrigin = kDefault_Origin; 1.70 + fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS; 1.71 + } 1.72 + 1.73 + GrGLShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray, 1.74 + Precision precision = kDefault_Precision) { 1.75 + SkASSERT(kVoid_GrSLType != type); 1.76 + fType = type; 1.77 + fTypeModifier = kNone_TypeModifier; 1.78 + fCount = arrayCount; 1.79 + fPrecision = precision; 1.80 + fOrigin = kDefault_Origin; 1.81 + fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS; 1.82 + fName = name; 1.83 + } 1.84 + 1.85 + GrGLShaderVar(const GrGLShaderVar& var) 1.86 + : fType(var.fType) 1.87 + , fTypeModifier(var.fTypeModifier) 1.88 + , fName(var.fName) 1.89 + , fCount(var.fCount) 1.90 + , fPrecision(var.fPrecision) 1.91 + , fOrigin(var.fOrigin) 1.92 + , fUseUniformFloatArrays(var.fUseUniformFloatArrays) { 1.93 + SkASSERT(kVoid_GrSLType != var.fType); 1.94 + } 1.95 + 1.96 + /** 1.97 + * Values for array count that have special meaning. We allow 1-sized arrays. 1.98 + */ 1.99 + enum { 1.100 + kNonArray = 0, // not an array 1.101 + kUnsizedArray = -1, // an unsized array (declared with []) 1.102 + }; 1.103 + 1.104 + /** 1.105 + * Sets as a non-array. 1.106 + */ 1.107 + void set(GrSLType type, 1.108 + TypeModifier typeModifier, 1.109 + const SkString& name, 1.110 + Precision precision = kDefault_Precision, 1.111 + Origin origin = kDefault_Origin, 1.112 + bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { 1.113 + SkASSERT(kVoid_GrSLType != type); 1.114 + fType = type; 1.115 + fTypeModifier = typeModifier; 1.116 + fName = name; 1.117 + fCount = kNonArray; 1.118 + fPrecision = precision; 1.119 + fOrigin = origin; 1.120 + fUseUniformFloatArrays = useUniformFloatArrays; 1.121 + } 1.122 + 1.123 + /** 1.124 + * Sets as a non-array. 1.125 + */ 1.126 + void set(GrSLType type, 1.127 + TypeModifier typeModifier, 1.128 + const char* name, 1.129 + Precision precision = kDefault_Precision, 1.130 + Origin origin = kDefault_Origin, 1.131 + bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { 1.132 + SkASSERT(kVoid_GrSLType != type); 1.133 + fType = type; 1.134 + fTypeModifier = typeModifier; 1.135 + fName = name; 1.136 + fCount = kNonArray; 1.137 + fPrecision = precision; 1.138 + fOrigin = origin; 1.139 + fUseUniformFloatArrays = useUniformFloatArrays; 1.140 + } 1.141 + 1.142 + /** 1.143 + * Set all var options 1.144 + */ 1.145 + void set(GrSLType type, 1.146 + TypeModifier typeModifier, 1.147 + const SkString& name, 1.148 + int count, 1.149 + Precision precision = kDefault_Precision, 1.150 + Origin origin = kDefault_Origin, 1.151 + bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { 1.152 + SkASSERT(kVoid_GrSLType != type); 1.153 + fType = type; 1.154 + fTypeModifier = typeModifier; 1.155 + fName = name; 1.156 + fCount = count; 1.157 + fPrecision = precision; 1.158 + fOrigin = origin; 1.159 + fUseUniformFloatArrays = useUniformFloatArrays; 1.160 + } 1.161 + 1.162 + /** 1.163 + * Set all var options 1.164 + */ 1.165 + void set(GrSLType type, 1.166 + TypeModifier typeModifier, 1.167 + const char* name, 1.168 + int count, 1.169 + Precision precision = kDefault_Precision, 1.170 + Origin origin = kDefault_Origin, 1.171 + bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { 1.172 + SkASSERT(kVoid_GrSLType != type); 1.173 + fType = type; 1.174 + fTypeModifier = typeModifier; 1.175 + fName = name; 1.176 + fCount = count; 1.177 + fPrecision = precision; 1.178 + fOrigin = origin; 1.179 + fUseUniformFloatArrays = useUniformFloatArrays; 1.180 + } 1.181 + 1.182 + /** 1.183 + * Is the var an array. 1.184 + */ 1.185 + bool isArray() const { return kNonArray != fCount; } 1.186 + /** 1.187 + * Is this an unsized array, (i.e. declared with []). 1.188 + */ 1.189 + bool isUnsizedArray() const { return kUnsizedArray == fCount; } 1.190 + /** 1.191 + * Get the array length of the var. 1.192 + */ 1.193 + int getArrayCount() const { return fCount; } 1.194 + /** 1.195 + * Set the array length of the var 1.196 + */ 1.197 + void setArrayCount(int count) { fCount = count; } 1.198 + /** 1.199 + * Set to be a non-array. 1.200 + */ 1.201 + void setNonArray() { fCount = kNonArray; } 1.202 + /** 1.203 + * Set to be an unsized array. 1.204 + */ 1.205 + void setUnsizedArray() { fCount = kUnsizedArray; } 1.206 + 1.207 + /** 1.208 + * Access the var name as a writable string 1.209 + */ 1.210 + SkString* accessName() { return &fName; } 1.211 + /** 1.212 + * Set the var name 1.213 + */ 1.214 + void setName(const SkString& n) { fName = n; } 1.215 + void setName(const char* n) { fName = n; } 1.216 + 1.217 + /** 1.218 + * Get the var name. 1.219 + */ 1.220 + const SkString& getName() const { return fName; } 1.221 + 1.222 + /** 1.223 + * Shortcut for this->getName().c_str(); 1.224 + */ 1.225 + const char* c_str() const { return this->getName().c_str(); } 1.226 + 1.227 + /** 1.228 + * Get the type of the var 1.229 + */ 1.230 + GrSLType getType() const { return fType; } 1.231 + /** 1.232 + * Set the type of the var 1.233 + */ 1.234 + void setType(GrSLType type) { fType = type; } 1.235 + 1.236 + TypeModifier getTypeModifier() const { return fTypeModifier; } 1.237 + void setTypeModifier(TypeModifier type) { fTypeModifier = type; } 1.238 + 1.239 + /** 1.240 + * Get the precision of the var 1.241 + */ 1.242 + Precision getPrecision() const { return fPrecision; } 1.243 + 1.244 + /** 1.245 + * Set the precision of the var 1.246 + */ 1.247 + void setPrecision(Precision p) { fPrecision = p; } 1.248 + 1.249 + /** 1.250 + * Get the origin of the var 1.251 + */ 1.252 + Origin getOrigin() const { return fOrigin; } 1.253 + 1.254 + /** 1.255 + * Set the origin of the var 1.256 + */ 1.257 + void setOrigin(Origin origin) { fOrigin = origin; } 1.258 + 1.259 + /** 1.260 + * Write a declaration of this variable to out. 1.261 + */ 1.262 + void appendDecl(const GrGLContextInfo& ctxInfo, SkString* out) const { 1.263 + if (kUpperLeft_Origin == fOrigin) { 1.264 + // this is the only place where we specify a layout modifier. If we use other layout 1.265 + // modifiers in the future then they should be placed in a list. 1.266 + out->append("layout(origin_upper_left) "); 1.267 + } 1.268 + if (this->getTypeModifier() != kNone_TypeModifier) { 1.269 + out->append(TypeModifierString(this->getTypeModifier(), 1.270 + ctxInfo.glslGeneration())); 1.271 + out->append(" "); 1.272 + } 1.273 + out->append(PrecisionString(fPrecision, ctxInfo.standard())); 1.274 + GrSLType effectiveType = this->getType(); 1.275 + if (this->isArray()) { 1.276 + if (this->isUnsizedArray()) { 1.277 + out->appendf("%s %s[]", 1.278 + GrGLSLTypeString(effectiveType), 1.279 + this->getName().c_str()); 1.280 + } else { 1.281 + SkASSERT(this->getArrayCount() > 0); 1.282 + out->appendf("%s %s[%d]", 1.283 + GrGLSLTypeString(effectiveType), 1.284 + this->getName().c_str(), 1.285 + this->getArrayCount()); 1.286 + } 1.287 + } else { 1.288 + out->appendf("%s %s", 1.289 + GrGLSLTypeString(effectiveType), 1.290 + this->getName().c_str()); 1.291 + } 1.292 + } 1.293 + 1.294 + void appendArrayAccess(int index, SkString* out) const { 1.295 + out->appendf("%s[%d]%s", 1.296 + this->getName().c_str(), 1.297 + index, 1.298 + fUseUniformFloatArrays ? "" : ".x"); 1.299 + } 1.300 + 1.301 + void appendArrayAccess(const char* indexName, SkString* out) const { 1.302 + out->appendf("%s[%s]%s", 1.303 + this->getName().c_str(), 1.304 + indexName, 1.305 + fUseUniformFloatArrays ? "" : ".x"); 1.306 + } 1.307 + 1.308 + static const char* PrecisionString(Precision p, GrGLStandard standard) { 1.309 + // Desktop GLSL has added precision qualifiers but they don't do anything. 1.310 + if (kGLES_GrGLStandard == standard) { 1.311 + switch (p) { 1.312 + case kLow_Precision: 1.313 + return "lowp "; 1.314 + case kMedium_Precision: 1.315 + return "mediump "; 1.316 + case kHigh_Precision: 1.317 + return "highp "; 1.318 + case kDefault_Precision: 1.319 + return ""; 1.320 + default: 1.321 + GrCrash("Unexpected precision type."); 1.322 + } 1.323 + } 1.324 + return ""; 1.325 + } 1.326 + 1.327 +private: 1.328 + static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) { 1.329 + switch (t) { 1.330 + case kNone_TypeModifier: 1.331 + return ""; 1.332 + case kIn_TypeModifier: 1.333 + return "in"; 1.334 + case kInOut_TypeModifier: 1.335 + return "inout"; 1.336 + case kOut_TypeModifier: 1.337 + return "out"; 1.338 + case kUniform_TypeModifier: 1.339 + return "uniform"; 1.340 + case kAttribute_TypeModifier: 1.341 + return k110_GrGLSLGeneration == gen ? "attribute" : "in"; 1.342 + case kVaryingIn_TypeModifier: 1.343 + return k110_GrGLSLGeneration == gen ? "varying" : "in"; 1.344 + case kVaryingOut_TypeModifier: 1.345 + return k110_GrGLSLGeneration == gen ? "varying" : "out"; 1.346 + default: 1.347 + GrCrash("Unknown shader variable type modifier."); 1.348 + return ""; // suppress warning 1.349 + } 1.350 + } 1.351 + 1.352 + GrSLType fType; 1.353 + TypeModifier fTypeModifier; 1.354 + SkString fName; 1.355 + int fCount; 1.356 + Precision fPrecision; 1.357 + Origin fOrigin; 1.358 + /// Work around driver bugs on some hardware that don't correctly 1.359 + /// support uniform float [] 1.360 + bool fUseUniformFloatArrays; 1.361 +}; 1.362 + 1.363 +#endif