Refactor how precision is handled with GrGLShaderVar
Review URL: http://codereview.appspot.com/6392049/ git-svn-id: http://skia.googlecode.com/svn/trunk@4575 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
ba68cdb415
commit
d7727ceb82
@ -55,22 +55,6 @@ const char* GrGetGLSLVersionDecl(GrGLBinding binding,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* GrGetGLSLVarPrecisionDeclType(GrGLBinding binding) {
|
|
||||||
if (kES2_GrGLBinding == binding) {
|
|
||||||
return "mediump";
|
|
||||||
} else {
|
|
||||||
return " ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* GrGetGLSLShaderPrecisionDecl(GrGLBinding binding) {
|
|
||||||
if (kES2_GrGLBinding == binding) {
|
|
||||||
return "precision mediump float;\n";
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
|
bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
|
||||||
const char* nameIfDeclared,
|
const char* nameIfDeclared,
|
||||||
GrGLShaderVar* var) {
|
GrGLShaderVar* var) {
|
||||||
|
@ -57,18 +57,6 @@ GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding,
|
|||||||
const char* GrGetGLSLVersionDecl(GrGLBinding binding,
|
const char* GrGetGLSLVersionDecl(GrGLBinding binding,
|
||||||
GrGLSLGeneration v);
|
GrGLSLGeneration v);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string to include in a variable decleration to set the fp precision
|
|
||||||
* or an emptry string if precision is not required.
|
|
||||||
*/
|
|
||||||
const char* GrGetGLSLVarPrecisionDeclType(GrGLBinding binding);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string to set the default fp precision for an entire shader, or
|
|
||||||
* an emptry string if precision is not required.
|
|
||||||
*/
|
|
||||||
const char* GrGetGLSLShaderPrecisionDecl(GrGLBinding binding);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Depending on the GLSL version being emitted there may be an assumed output
|
* Depending on the GLSL version being emitted there may be an assumed output
|
||||||
* variable from the fragment shader for the color. Otherwise, the shader must
|
* variable from the fragment shader for the color. Otherwise, the shader must
|
||||||
|
@ -14,6 +14,9 @@ static const int kVarsPerBlock = 8;
|
|||||||
// except FS outputs where we expect 2 at most.
|
// except FS outputs where we expect 2 at most.
|
||||||
static const int kMaxFSOutputs = 2;
|
static const int kMaxFSOutputs = 2;
|
||||||
|
|
||||||
|
// ES2 FS only guarantees mediump and lowp support
|
||||||
|
static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
|
||||||
|
|
||||||
// Architectural assumption: always 2-d input coords.
|
// Architectural assumption: always 2-d input coords.
|
||||||
// Likely to become non-constant and non-static, perhaps even
|
// Likely to become non-constant and non-static, perhaps even
|
||||||
// varying by stage, if we use 1D textures for gradients!
|
// varying by stage, if we use 1D textures for gradients!
|
||||||
@ -139,10 +142,9 @@ const GrGLShaderVar& GrGLShaderBuilder::addUniform(uint32_t visibility,
|
|||||||
var->setArrayCount(count);
|
var->setArrayCount(count);
|
||||||
|
|
||||||
if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) {
|
if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) {
|
||||||
|
// the fragment and vertex precisions must match
|
||||||
|
var->setPrecision(kDefaultFragmentPrecision);
|
||||||
fFSUnis.push_back(*var);
|
fFSUnis.push_back(*var);
|
||||||
// If it's shared between VS and FS, VS must override
|
|
||||||
// default highp and specify mediump.
|
|
||||||
var->setEmitPrecision(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *var;
|
return *var;
|
||||||
@ -186,7 +188,6 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GrGLShaderBuilder::addVarying(GrSLType type,
|
void GrGLShaderBuilder::addVarying(GrSLType type,
|
||||||
const char* name,
|
const char* name,
|
||||||
int stageNum,
|
int stageNum,
|
||||||
@ -198,6 +199,30 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
|
||||||
|
GrGLBinding binding,
|
||||||
|
SkString* str) {
|
||||||
|
// Desktop GLSL has added precision qualifiers but they don't do anything.
|
||||||
|
if (kES2_GrGLBinding == binding) {
|
||||||
|
switch (p) {
|
||||||
|
case GrGLShaderVar::kHigh_Precision:
|
||||||
|
str->append("precision highp float;\n");
|
||||||
|
break;
|
||||||
|
case GrGLShaderVar::kMedium_Precision:
|
||||||
|
str->append("precision mediump float;\n");
|
||||||
|
break;
|
||||||
|
case GrGLShaderVar::kLow_Precision:
|
||||||
|
str->append("precision lowp float;\n");
|
||||||
|
break;
|
||||||
|
case GrGLShaderVar::kDefault_Precision:
|
||||||
|
GrCrash("Default precision now allowed.");
|
||||||
|
default:
|
||||||
|
GrCrash("Unknown precision value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void append_decls(const GrGLShaderBuilder::VarArray& vars,
|
void append_decls(const GrGLShaderBuilder::VarArray& vars,
|
||||||
const GrGLContextInfo& ctx,
|
const GrGLContextInfo& ctx,
|
||||||
SkString* string) {
|
SkString* string) {
|
||||||
@ -229,7 +254,9 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const {
|
|||||||
break;
|
break;
|
||||||
case kFragment_ShaderType:
|
case kFragment_ShaderType:
|
||||||
*shaderStr = fHeader;
|
*shaderStr = fHeader;
|
||||||
shaderStr->append(GrGetGLSLShaderPrecisionDecl(fContext.binding()));
|
append_default_precision_qualifier(kDefaultFragmentPrecision,
|
||||||
|
fContext.binding(),
|
||||||
|
shaderStr);
|
||||||
append_decls(fFSUnis, fContext, shaderStr);
|
append_decls(fFSUnis, fContext, shaderStr);
|
||||||
append_decls(fFSInputs, fContext, shaderStr);
|
append_decls(fFSInputs, fContext, shaderStr);
|
||||||
// We shouldn't have declared outputs on 1.10
|
// We shouldn't have declared outputs on 1.10
|
||||||
@ -239,5 +266,5 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const {
|
|||||||
shaderStr->append(fFSCode);
|
shaderStr->append(fFSCode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,17 @@ public:
|
|||||||
kAttribute_TypeModifier
|
kAttribute_TypeModifier
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Precision {
|
||||||
|
kLow_Precision, // lowp
|
||||||
|
kMedium_Precision, // mediump
|
||||||
|
kHigh_Precision, // highp
|
||||||
|
kDefault_Precision, // Default for the current context. We make
|
||||||
|
// fragment shaders default to mediump on ES2
|
||||||
|
// because highp support is not guaranteed (and
|
||||||
|
// we haven't been motivated to test for it).
|
||||||
|
// Otherwise, highp.
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defaults to a float with no precision specifier
|
* Defaults to a float with no precision specifier
|
||||||
*/
|
*/
|
||||||
@ -40,7 +51,7 @@ public:
|
|||||||
fType = kFloat_GrSLType;
|
fType = kFloat_GrSLType;
|
||||||
fTypeModifier = kNone_TypeModifier;
|
fTypeModifier = kNone_TypeModifier;
|
||||||
fCount = kNonArray;
|
fCount = kNonArray;
|
||||||
fEmitPrecision = false;
|
fPrecision = kDefault_Precision;
|
||||||
fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
|
fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +60,7 @@ public:
|
|||||||
, fTypeModifier(var.fTypeModifier)
|
, fTypeModifier(var.fTypeModifier)
|
||||||
, fName(var.fName)
|
, fName(var.fName)
|
||||||
, fCount(var.fCount)
|
, fCount(var.fCount)
|
||||||
, fEmitPrecision(var.fEmitPrecision)
|
, fPrecision(var.fPrecision)
|
||||||
, fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
|
, fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,13 +77,13 @@ public:
|
|||||||
void set(GrSLType type,
|
void set(GrSLType type,
|
||||||
TypeModifier typeModifier,
|
TypeModifier typeModifier,
|
||||||
const SkString& name,
|
const SkString& name,
|
||||||
bool emitPrecision = false,
|
Precision precision = kDefault_Precision,
|
||||||
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
||||||
fType = type;
|
fType = type;
|
||||||
fTypeModifier = typeModifier;
|
fTypeModifier = typeModifier;
|
||||||
fName = name;
|
fName = name;
|
||||||
fCount = kNonArray;
|
fCount = kNonArray;
|
||||||
fEmitPrecision = emitPrecision;
|
fPrecision = precision;
|
||||||
fUseUniformFloatArrays = useUniformFloatArrays;
|
fUseUniformFloatArrays = useUniformFloatArrays;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,13 +93,13 @@ public:
|
|||||||
void set(GrSLType type,
|
void set(GrSLType type,
|
||||||
TypeModifier typeModifier,
|
TypeModifier typeModifier,
|
||||||
const char* name,
|
const char* name,
|
||||||
bool specifyPrecision = false,
|
Precision precision = kDefault_Precision,
|
||||||
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
||||||
fType = type;
|
fType = type;
|
||||||
fTypeModifier = typeModifier;
|
fTypeModifier = typeModifier;
|
||||||
fName = name;
|
fName = name;
|
||||||
fCount = kNonArray;
|
fCount = kNonArray;
|
||||||
fEmitPrecision = specifyPrecision;
|
fPrecision = precision;
|
||||||
fUseUniformFloatArrays = useUniformFloatArrays;
|
fUseUniformFloatArrays = useUniformFloatArrays;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,13 +110,13 @@ public:
|
|||||||
TypeModifier typeModifier,
|
TypeModifier typeModifier,
|
||||||
const SkString& name,
|
const SkString& name,
|
||||||
int count,
|
int count,
|
||||||
bool specifyPrecision = false,
|
Precision precision = kDefault_Precision,
|
||||||
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
||||||
fType = type;
|
fType = type;
|
||||||
fTypeModifier = typeModifier;
|
fTypeModifier = typeModifier;
|
||||||
fName = name;
|
fName = name;
|
||||||
fCount = count;
|
fCount = count;
|
||||||
fEmitPrecision = specifyPrecision;
|
fPrecision = precision;
|
||||||
fUseUniformFloatArrays = useUniformFloatArrays;
|
fUseUniformFloatArrays = useUniformFloatArrays;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,13 +127,13 @@ public:
|
|||||||
TypeModifier typeModifier,
|
TypeModifier typeModifier,
|
||||||
const char* name,
|
const char* name,
|
||||||
int count,
|
int count,
|
||||||
bool specifyPrecision = false,
|
Precision precision = kDefault_Precision,
|
||||||
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
|
||||||
fType = type;
|
fType = type;
|
||||||
fTypeModifier = typeModifier;
|
fTypeModifier = typeModifier;
|
||||||
fName = name;
|
fName = name;
|
||||||
fCount = count;
|
fCount = count;
|
||||||
fEmitPrecision = specifyPrecision;
|
fPrecision = precision;
|
||||||
fUseUniformFloatArrays = useUniformFloatArrays;
|
fUseUniformFloatArrays = useUniformFloatArrays;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,13 +189,14 @@ public:
|
|||||||
void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
|
void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must the variable declaration emit a precision specifier
|
* Get the precision of the var
|
||||||
*/
|
*/
|
||||||
bool emitsPrecision() const { return fEmitPrecision; }
|
Precision getPrecision() const { return fPrecision; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify whether the declaration should specify precision
|
* Set the precision of the var
|
||||||
*/
|
*/
|
||||||
void setEmitPrecision(bool p) { fEmitPrecision = p; }
|
void setPrecision(Precision p) { fPrecision = p; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a declaration of this variable to out.
|
* Write a declaration of this variable to out.
|
||||||
@ -195,10 +207,7 @@ public:
|
|||||||
gl.glslGeneration()));
|
gl.glslGeneration()));
|
||||||
out->append(" ");
|
out->append(" ");
|
||||||
}
|
}
|
||||||
if (this->emitsPrecision()) {
|
out->append(PrecisionString(fPrecision, gl.binding()));
|
||||||
out->append(GrGetGLSLVarPrecisionDeclType(gl.binding()));
|
|
||||||
out->append(" ");
|
|
||||||
}
|
|
||||||
GrSLType effectiveType = this->getType();
|
GrSLType effectiveType = this->getType();
|
||||||
if (this->isArray()) {
|
if (this->isArray()) {
|
||||||
if (this->isUnsizedArray()) {
|
if (this->isUnsizedArray()) {
|
||||||
@ -257,8 +266,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char* TypeModifierString(TypeModifier t,
|
static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
|
||||||
GrGLSLGeneration gen) {
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case kNone_TypeModifier:
|
case kNone_TypeModifier:
|
||||||
return "";
|
return "";
|
||||||
@ -276,11 +284,30 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GrSLType fType;
|
static const char* PrecisionString(Precision p, GrGLBinding binding) {
|
||||||
|
// Desktop GLSL has added precision qualifiers but they don't do anything.
|
||||||
|
if (kES2_GrGLBinding == binding) {
|
||||||
|
switch (p) {
|
||||||
|
case kLow_Precision:
|
||||||
|
return "lowp ";
|
||||||
|
case kMedium_Precision:
|
||||||
|
return "mediump ";
|
||||||
|
case kHigh_Precision:
|
||||||
|
return "highp ";
|
||||||
|
case kDefault_Precision:
|
||||||
|
return "";
|
||||||
|
default:
|
||||||
|
GrCrash("Unexpected precision type.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
GrSLType fType;
|
||||||
TypeModifier fTypeModifier;
|
TypeModifier fTypeModifier;
|
||||||
SkString fName;
|
SkString fName;
|
||||||
int fCount;
|
int fCount;
|
||||||
bool fEmitPrecision;
|
Precision fPrecision;
|
||||||
/// Work around driver bugs on some hardware that don't correctly
|
/// Work around driver bugs on some hardware that don't correctly
|
||||||
/// support uniform float []
|
/// support uniform float []
|
||||||
bool fUseUniformFloatArrays;
|
bool fUseUniformFloatArrays;
|
||||||
|
Loading…
Reference in New Issue
Block a user