aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-12 16:40:03 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-07-12 16:40:03 +0000
commitd7727ceb82e271f8b5580c51571c57b09c5e3ced (patch)
tree06719ef30d6eb2df2a18ec75f56c709951f14db0 /src
parentba68cdb415bd576f01bf27f9e9eca99a1dc84ba3 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/gpu/gl/GrGLSL.cpp16
-rw-r--r--src/gpu/gl/GrGLSL.h12
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp39
-rw-r--r--src/gpu/gl/GrGLShaderVar.h71
4 files changed, 82 insertions, 56 deletions
diff --git a/src/gpu/gl/GrGLSL.cpp b/src/gpu/gl/GrGLSL.cpp
index 21dd940c66..759a17c39a 100644
--- a/src/gpu/gl/GrGLSL.cpp
+++ b/src/gpu/gl/GrGLSL.cpp
@@ -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,
const char* nameIfDeclared,
GrGLShaderVar* var) {
diff --git a/src/gpu/gl/GrGLSL.h b/src/gpu/gl/GrGLSL.h
index 587d6f27b4..7b92c23434 100644
--- a/src/gpu/gl/GrGLSL.h
+++ b/src/gpu/gl/GrGLSL.h
@@ -58,18 +58,6 @@ const char* GrGetGLSLVersionDecl(GrGLBinding binding,
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
* variable from the fragment shader for the color. Otherwise, the shader must
* declare an output variable for the color. If this function returns true:
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index d24f2f89f6..3303bf2729 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -14,6 +14,9 @@ static const int kVarsPerBlock = 8;
// except FS outputs where we expect 2 at most.
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.
// Likely to become non-constant and non-static, perhaps even
// varying by stage, if we use 1D textures for gradients!
@@ -139,10 +142,9 @@ const GrGLShaderVar& GrGLShaderBuilder::addUniform(uint32_t visibility,
var->setArrayCount(count);
if ((kVertex_ShaderType | kFragment_ShaderType) == visibility) {
+ // the fragment and vertex precisions must match
+ var->setPrecision(kDefaultFragmentPrecision);
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;
@@ -186,7 +188,6 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
}
}
-
void GrGLShaderBuilder::addVarying(GrSLType type,
const char* name,
int stageNum,
@@ -198,6 +199,30 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
}
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,
const GrGLContextInfo& ctx,
SkString* string) {
@@ -229,7 +254,9 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const {
break;
case kFragment_ShaderType:
*shaderStr = fHeader;
- shaderStr->append(GrGetGLSLShaderPrecisionDecl(fContext.binding()));
+ append_default_precision_qualifier(kDefaultFragmentPrecision,
+ fContext.binding(),
+ shaderStr);
append_decls(fFSUnis, fContext, shaderStr);
append_decls(fFSInputs, fContext, shaderStr);
// We shouldn't have declared outputs on 1.10
@@ -239,5 +266,5 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const {
shaderStr->append(fFSCode);
break;
}
-
}
+
diff --git a/src/gpu/gl/GrGLShaderVar.h b/src/gpu/gl/GrGLShaderVar.h
index 7be417dec3..2eccd3b1e8 100644
--- a/src/gpu/gl/GrGLShaderVar.h
+++ b/src/gpu/gl/GrGLShaderVar.h
@@ -33,6 +33,17 @@ public:
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
*/
@@ -40,7 +51,7 @@ public:
fType = kFloat_GrSLType;
fTypeModifier = kNone_TypeModifier;
fCount = kNonArray;
- fEmitPrecision = false;
+ fPrecision = kDefault_Precision;
fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
}
@@ -49,7 +60,7 @@ public:
, fTypeModifier(var.fTypeModifier)
, fName(var.fName)
, fCount(var.fCount)
- , fEmitPrecision(var.fEmitPrecision)
+ , fPrecision(var.fPrecision)
, fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
/**
@@ -66,13 +77,13 @@ public:
void set(GrSLType type,
TypeModifier typeModifier,
const SkString& name,
- bool emitPrecision = false,
+ Precision precision = kDefault_Precision,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fTypeModifier = typeModifier;
fName = name;
fCount = kNonArray;
- fEmitPrecision = emitPrecision;
+ fPrecision = precision;
fUseUniformFloatArrays = useUniformFloatArrays;
}
@@ -82,13 +93,13 @@ public:
void set(GrSLType type,
TypeModifier typeModifier,
const char* name,
- bool specifyPrecision = false,
+ Precision precision = kDefault_Precision,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fTypeModifier = typeModifier;
fName = name;
fCount = kNonArray;
- fEmitPrecision = specifyPrecision;
+ fPrecision = precision;
fUseUniformFloatArrays = useUniformFloatArrays;
}
@@ -99,13 +110,13 @@ public:
TypeModifier typeModifier,
const SkString& name,
int count,
- bool specifyPrecision = false,
+ Precision precision = kDefault_Precision,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fTypeModifier = typeModifier;
fName = name;
fCount = count;
- fEmitPrecision = specifyPrecision;
+ fPrecision = precision;
fUseUniformFloatArrays = useUniformFloatArrays;
}
@@ -116,13 +127,13 @@ public:
TypeModifier typeModifier,
const char* name,
int count,
- bool specifyPrecision = false,
+ Precision precision = kDefault_Precision,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fTypeModifier = typeModifier;
fName = name;
fCount = count;
- fEmitPrecision = specifyPrecision;
+ fPrecision = precision;
fUseUniformFloatArrays = useUniformFloatArrays;
}
@@ -178,13 +189,14 @@ public:
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.
@@ -195,10 +207,7 @@ public:
gl.glslGeneration()));
out->append(" ");
}
- if (this->emitsPrecision()) {
- out->append(GrGetGLSLVarPrecisionDeclType(gl.binding()));
- out->append(" ");
- }
+ out->append(PrecisionString(fPrecision, gl.binding()));
GrSLType effectiveType = this->getType();
if (this->isArray()) {
if (this->isUnsizedArray()) {
@@ -257,8 +266,7 @@ public:
}
private:
- static const char* TypeModifierString(TypeModifier t,
- GrGLSLGeneration gen) {
+ static const char* TypeModifierString(TypeModifier t, GrGLSLGeneration gen) {
switch (t) {
case kNone_TypeModifier:
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;
SkString fName;
int fCount;
- bool fEmitPrecision;
+ Precision fPrecision;
/// Work around driver bugs on some hardware that don't correctly
/// support uniform float []
bool fUseUniformFloatArrays;