| OLD | NEW |
| (Empty) |
| 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 "GrShaderVar.h" | |
| 12 #include "../glsl/GrGLSL.h" | |
| 13 #include "../glsl/GrGLSLCaps.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 igno
red. | |
| 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 GrGLSLCaps* glslCaps, SkString* out) const { | |
| 160 SkASSERT(kDefault_GrSLPrecision == fPrecision || GrSLTypeIsFloatType(fTy
pe)); | |
| 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(glslCaps, this->getTypeModifier())); | |
| 168 out->append(" "); | |
| 169 } | |
| 170 out->append(PrecisionString(glslCaps, fPrecision)); | |
| 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(const GrGLSLCaps* glslCaps, GrSLPrecision
p) { | |
| 206 // Desktop GLSL has added precision qualifiers but they don't do anythin
g. | |
| 207 if (glslCaps->usesPrecisionModifiers()) { | |
| 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(const GrGLSLCaps* glslCaps, TypeModifi
er t) { | |
| 224 GrGLSLGeneration gen = glslCaps->generation(); | |
| 225 switch (t) { | |
| 226 case kNone_TypeModifier: | |
| 227 return ""; | |
| 228 case kIn_TypeModifier: | |
| 229 return "in"; | |
| 230 case kInOut_TypeModifier: | |
| 231 return "inout"; | |
| 232 case kOut_TypeModifier: | |
| 233 return "out"; | |
| 234 case kUniform_TypeModifier: | |
| 235 return "uniform"; | |
| 236 case kAttribute_TypeModifier: | |
| 237 return k110_GrGLSLGeneration == gen ? "attribute" : "in"; | |
| 238 case kVaryingIn_TypeModifier: | |
| 239 return k110_GrGLSLGeneration == gen ? "varying" : "in"; | |
| 240 case kVaryingOut_TypeModifier: | |
| 241 return k110_GrGLSLGeneration == gen ? "varying" : "out"; | |
| 242 default: | |
| 243 SkFAIL("Unknown shader variable type modifier."); | |
| 244 return ""; // suppress warning | |
| 245 } | |
| 246 } | |
| 247 | |
| 248 Origin fOrigin; | |
| 249 /// Work around driver bugs on some hardware that don't correctly | |
| 250 /// support uniform float [] | |
| 251 bool fUseUniformFloatArrays; | |
| 252 | |
| 253 typedef GrShaderVar INHERITED; | |
| 254 }; | |
| 255 | |
| 256 #endif | |
| OLD | NEW |