| /* | |
| * Copyright 2016 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef GrShaderVar_DEFINED | |
| #define GrShaderVar_DEFINED | |
| #include "SkString.h" | |
| #include "GrTypesPriv.h" | |
| class GrShaderCaps; | |
| #define USE_UNIFORM_FLOAT_ARRAYS true | |
| /** | |
| * Represents a variable in a shader | |
| */ | |
| class GrShaderVar { | |
| public: | |
| enum TypeModifier { | |
| kNone_TypeModifier, | |
| kOut_TypeModifier, | |
| kIn_TypeModifier, | |
| kInOut_TypeModifier, | |
| kUniform_TypeModifier, | |
| }; | |
| /** | |
| * Values for array count that have special meaning. We allow 1-sized arrays.git | |
| */ | |
| enum { | |
| kNonArray = 0, // not an array | |
| kUnsizedArray = -1, // an unsized array (declared with []) | |
| }; | |
| /** | |
| * Defaults to a non-arry half with no type modifier or layout qualifier. | |
| */ | |
| GrShaderVar() | |
| : fType(kHalf_GrSLType) | |
| , fTypeModifier(kNone_TypeModifier) | |
| , fCount(kNonArray) | |
| , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) { | |
| } | |
| GrShaderVar(const SkString& name, GrSLType type, int arrayCount = kNonArray, | |
| GrSLPrecision precision = kDefault_GrSLPrecision) | |
| : fType(type) | |
| , fTypeModifier(kNone_TypeModifier) | |
| , fCount(arrayCount) | |
| , fPrecision(precision) | |
| , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) | |
| , fName(name) { | |
| SkASSERT(kVoid_GrSLType != type); | |
| fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS; | |
| } | |
| GrShaderVar(const char* name, GrSLType type, int arrayCount = kNonArray, | |
| GrSLPrecision precision = kDefault_GrSLPrecision) | |
| : fType(type) | |
| , fTypeModifier(kNone_TypeModifier) | |
| , fCount(arrayCount) | |
| , fPrecision(precision) | |
| , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) | |
| , fName(name) { | |
| SkASSERT(kVoid_GrSLType != type); | |
| fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS; | |
| } | |
| GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier, | |
| GrSLPrecision precision = kDefault_GrSLPrecision) | |
| : fType(type) | |
| , fTypeModifier(typeModifier) | |
| , fCount(kNonArray) | |
| , fPrecision(precision) | |
| , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) | |
| , fName(name) { | |
| SkASSERT(kVoid_GrSLType != type); | |
| } | |
| GrShaderVar(const char* name, GrSLType type, TypeModifier typeModifier, | |
| int arrayCount, GrSLPrecision precision = kDefault_GrSLPrecision) | |
| : fType(type) | |
| , fTypeModifier(typeModifier) | |
| , fCount(arrayCount) | |
| , fPrecision(precision) | |
| , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) | |
| , fName(name) { | |
| SkASSERT(kVoid_GrSLType != type); | |
| } | |
| GrShaderVar(const GrShaderVar& that) | |
| : fType(that.fType) | |
| , fTypeModifier(that.fTypeModifier) | |
| , fCount(that.fCount) | |
| , fPrecision(that.fPrecision) | |
| , fUseUniformFloatArrays(USE_UNIFORM_FLOAT_ARRAYS) | |
| , fName(that.fName) | |
| , fLayoutQualifier(that.fLayoutQualifier) | |
| , fExtraModifiers(that.fExtraModifiers) { | |
| SkASSERT(kVoid_GrSLType != that.getType()); | |
| } | |
| /** | |
| * Sets as a non-array. | |
| */ | |
| void set(GrSLType type, | |
| const SkString& name, | |
| TypeModifier typeModifier = kNone_TypeModifier, | |
| GrSLPrecision precision = kDefault_GrSLPrecision, | |
| const char* layoutQualifier = nullptr, | |
| const char* extraModifiers = nullptr, | |
| bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { | |
| SkASSERT(kVoid_GrSLType != type); | |
| SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeTemporarilyAcceptsPrecision(type)); | |
| fType = type; | |
| fTypeModifier = typeModifier; | |
| fName = name; | |
| fCount = kNonArray; | |
| fPrecision = precision; | |
| fLayoutQualifier = layoutQualifier; | |
| if (extraModifiers) { | |
| fExtraModifiers.printf("%s ", extraModifiers); | |
| } | |
| fUseUniformFloatArrays = useUniformFloatArrays; | |
| } | |
| /** | |
| * Sets as a non-array. | |
| */ | |
| void set(GrSLType type, | |
| const char* name, | |
| TypeModifier typeModifier = kNone_TypeModifier, | |
| GrSLPrecision precision = kDefault_GrSLPrecision, | |
| const char* layoutQualifier = nullptr, | |
| const char* extraModifiers = nullptr, | |
| bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { | |
| SkASSERT(kVoid_GrSLType != type); | |
| SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeTemporarilyAcceptsPrecision(type)); | |
| fType = type; | |
| fTypeModifier = typeModifier; | |
| fName = name; | |
| fCount = kNonArray; | |
| fPrecision = precision; | |
| fLayoutQualifier = layoutQualifier; | |
| if (extraModifiers) { | |
| fExtraModifiers.printf("%s ", extraModifiers); | |
| } | |
| fUseUniformFloatArrays = useUniformFloatArrays; | |
| } | |
| /** | |
| * Set all var options | |
| */ | |
| void set(GrSLType type, | |
| const SkString& name, | |
| int count, | |
| TypeModifier typeModifier, | |
| GrSLPrecision precision = kDefault_GrSLPrecision, | |
| const char* layoutQualifier = nullptr, | |
| const char* extraModifiers = nullptr, | |
| bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { | |
| SkASSERT(kVoid_GrSLType != type); | |
| SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeTemporarilyAcceptsPrecision(type)); | |
| fType = type; | |
| fTypeModifier = typeModifier; | |
| fName = name; | |
| fCount = count; | |
| fPrecision = precision; | |
| fLayoutQualifier = layoutQualifier; | |
| if (extraModifiers) { | |
| fExtraModifiers.printf("%s ", extraModifiers); | |
| } | |
| fUseUniformFloatArrays = useUniformFloatArrays; | |
| } | |
| /** | |
| * Set all var options | |
| */ | |
| void set(GrSLType type, | |
| const char* name, | |
| int count, | |
| TypeModifier typeModifier, | |
| GrSLPrecision precision = kDefault_GrSLPrecision, | |
| const char* layoutQualifier = nullptr, | |
| const char* extraModifiers = nullptr, | |
| bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) { | |
| SkASSERT(kVoid_GrSLType != type); | |
| SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeTemporarilyAcceptsPrecision(type)); | |
| fType = type; | |
| fTypeModifier = typeModifier; | |
| fName = name; | |
| fCount = count; | |
| fPrecision = precision; | |
| fLayoutQualifier = layoutQualifier; | |
| if (extraModifiers) { | |
| fExtraModifiers.printf("%s ", extraModifiers); | |
| } | |
| fUseUniformFloatArrays = useUniformFloatArrays; | |
| } | |
| /** | |
| * Is the var an array. | |
| */ | |
| bool isArray() const { return kNonArray != fCount; } | |
| /** | |
| * Is this an unsized array, (i.e. declared with []). | |
| */ | |
| bool isUnsizedArray() const { return kUnsizedArray == fCount; } | |
| /** | |
| * Get the array length of the var. | |
| */ | |
| int getArrayCount() const { return fCount; } | |
| /** | |
| * Set the array length of the var | |
| */ | |
| void setArrayCount(int count) { fCount = count; } | |
| /** | |
| * Set to be a non-array. | |
| */ | |
| void setNonArray() { fCount = kNonArray; } | |
| /** | |
| * Set to be an unsized array. | |
| */ | |
| void setUnsizedArray() { fCount = kUnsizedArray; } | |
| /** | |
| * Access the var name as a writable string | |
| */ | |
| SkString* accessName() { return &fName; } | |
| /** | |
| * Set the var name | |
| */ | |
| void setName(const SkString& n) { fName = n; } | |
| void setName(const char* n) { fName = n; } | |
| /** | |
| * Get the var name. | |
| */ | |
| const SkString& getName() const { return fName; } | |
| /** | |
| * Shortcut for this->getName().c_str(); | |
| */ | |
| const char* c_str() const { return this->getName().c_str(); } | |
| /** | |
| * Get the type of the var | |
| */ | |
| GrSLType getType() const { return fType; } | |
| /** | |
| * Set the type of the var | |
| */ | |
| void setType(GrSLType type) { fType = type; } | |
| TypeModifier getTypeModifier() const { return fTypeModifier; } | |
| void setTypeModifier(TypeModifier type) { fTypeModifier = type; } | |
| /** | |
| * Get the precision of the var | |
| */ | |
| GrSLPrecision getPrecision() const { return fPrecision; } | |
| /** | |
| * Set the precision of the var | |
| */ | |
| void setPrecision(GrSLPrecision p) { fPrecision = p; } | |
| /** | |
| * Appends to the layout qualifier | |
| */ | |
| void addLayoutQualifier(const char* layoutQualifier) { | |
| if (!layoutQualifier || !strlen(layoutQualifier)) { | |
| return; | |
| } | |
| if (fLayoutQualifier.isEmpty()) { | |
| fLayoutQualifier = layoutQualifier; | |
| } else { | |
| fLayoutQualifier.appendf(", %s", layoutQualifier); | |
| } | |
| } | |
| void setIOType(GrIOType); | |
| void addModifier(const char* modifier) { | |
| if (modifier) { | |
| fExtraModifiers.appendf("%s ", modifier); | |
| } | |
| } | |
| /** | |
| * Write a declaration of this variable to out. | |
| */ | |
| void appendDecl(const GrShaderCaps*, SkString* out) const; | |
| void appendArrayAccess(int index, SkString* out) const { | |
| out->appendf("%s[%d]%s", | |
| this->getName().c_str(), | |
| index, | |
| fUseUniformFloatArrays ? "" : ".x"); | |
| } | |
| void appendArrayAccess(const char* indexName, SkString* out) const { | |
| out->appendf("%s[%s]%s", | |
| this->getName().c_str(), | |
| indexName, | |
| fUseUniformFloatArrays ? "" : ".x"); | |
| } | |
| private: | |
| GrSLType fType; | |
| TypeModifier fTypeModifier; | |
| int fCount; | |
| GrSLPrecision fPrecision; | |
| /// Work around driver bugs on some hardware that don't correctly | |
| /// support uniform float [] | |
| bool fUseUniformFloatArrays; | |
| SkString fName; | |
| SkString fLayoutQualifier; | |
| SkString fExtraModifiers; | |
| }; | |
| #endif |