/*
* 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