Make GrGLShaderVar objects aware of whether they are uniform, varying, or
attribute varibles. Extract GLSL generation enum and utility function into
new GrGLSL header.
git-svn-id: http://skia.googlecode.com/svn/trunk@2827 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrGLProgram.cpp b/src/gpu/GrGLProgram.cpp
index 9395c0e..b7e902d 100644
--- a/src/gpu/GrGLProgram.cpp
+++ b/src/gpu/GrGLProgram.cpp
@@ -369,9 +369,9 @@
namespace {
const char* glsl_version_string(const GrGLInterface* gl,
- GrGLProgram::GLSLVersion v) {
+ GrGLSLGeneration v) {
switch (v) {
- case GrGLProgram::k110_GLSLVersion:
+ case k110_GLSLGeneration:
if (gl->supportsES2()) {
// ES2s shader language is based on version 1.20 but is version
// 1.00 of the ES language.
@@ -379,10 +379,10 @@
} else {
return "#version 110\n";
}
- case GrGLProgram::k130_GLSLVersion:
+ case k130_GLSLGeneration:
GrAssert(!gl->supportsES2());
return "#version 130\n";
- case GrGLProgram::k150_GLSLVersion:
+ case k150_GLSLGeneration:
GrAssert(!gl->supportsES2());
return "#version 150\n";
default:
@@ -400,6 +400,8 @@
const char** fsInName = NULL) {
segments->fVSOutputs.push_back();
segments->fVSOutputs.back().setType(type);
+ segments->fVSOutputs.back().setTypeModifier(
+ GrGLShaderVar::kOut_TypeModifier);
segments->fVSOutputs.back().accessName()->printf("v%s", name);
if (vsOutName) {
*vsOutName = segments->fVSOutputs.back().getName().c_str();
@@ -411,11 +413,15 @@
// and output as non-array.
segments->fGSInputs.push_back();
segments->fGSInputs.back().setType(type);
+ segments->fGSInputs.back().setTypeModifier(
+ GrGLShaderVar::kIn_TypeModifier);
segments->fGSInputs.back().setUnsizedArray();
*segments->fGSInputs.back().accessName() =
segments->fVSOutputs.back().getName();
segments->fGSOutputs.push_back();
segments->fGSOutputs.back().setType(type);
+ segments->fGSOutputs.back().setTypeModifier(
+ GrGLShaderVar::kOut_TypeModifier);
segments->fGSOutputs.back().accessName()->printf("g%s", name);
fsName = segments->fGSOutputs.back().accessName();
} else {
@@ -423,6 +429,8 @@
}
segments->fFSInputs.push_back();
segments->fFSInputs.back().setType(type);
+ segments->fFSInputs.back().setTypeModifier(
+ GrGLShaderVar::kIn_TypeModifier);
segments->fFSInputs.back().setName(*fsName);
if (fsInName) {
*fsInName = fsName->c_str();
@@ -450,6 +458,7 @@
ShaderCodeSegments* segments) const {
if (fProgramDesc.fEdgeAANumEdges > 0) {
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec3f_Type,
+ GrGLShaderVar::kUniform_TypeModifier,
EDGES_UNI_NAME,
fProgramDesc.fEdgeAANumEdges);
programData->fUniLocations.fEdgesUni = kUseUniform;
@@ -499,8 +508,10 @@
*coverageVar = "edgeAlpha";
} else if (layout & GrDrawTarget::kEdge_VertexLayoutBit) {
const char *vsName, *fsName;
- append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments, &vsName, &fsName);
- segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type, EDGE_ATTR_NAME);
+ append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments,
+ &vsName, &fsName);
+ segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
+ GrGLShaderVar::kAttribute_TypeModifier, EDGE_ATTR_NAME);
segments->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName);
if (GrDrawState::kHairLine_EdgeType == fProgramDesc.fVertexEdgeType) {
segments->fFSCode.appendf("\tfloat edgeAlpha = abs(dot(vec3(gl_FragCoord.xy,1), %s.xyz));\n", fsName);
@@ -528,18 +539,19 @@
namespace {
// returns true if the color output was explicitly declared or not.
-bool decl_and_get_fs_color_output(GrGLProgram::GLSLVersion v,
+bool decl_and_get_fs_color_output(GrGLSLGeneration v,
VarArray* fsOutputs,
const char** name) {
switch (v) {
- case GrGLProgram::k110_GLSLVersion:
+ case k110_GLSLGeneration:
*name = "gl_FragColor";
return false;
break;
- case GrGLProgram::k130_GLSLVersion: // fallthru
- case GrGLProgram::k150_GLSLVersion:
+ case k130_GLSLGeneration: // fallthru
+ case k150_GLSLGeneration:
*name = declared_color_output_name();
fsOutputs->push_back().set(GrGLShaderVar::kVec4f_Type,
+ GrGLShaderVar::kOut_TypeModifier,
declared_color_output_name());
return true;
break;
@@ -556,7 +568,8 @@
switch (colorInput) {
case GrGLProgram::ProgramDesc::kAttribute_ColorInput: {
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
- COL_ATTR_NAME);
+ GrGLShaderVar::kAttribute_TypeModifier,
+ COL_ATTR_NAME);
const char *vsName, *fsName;
append_varying(GrGLShaderVar::kVec4f_Type, "Color", segments, &vsName, &fsName);
segments->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
@@ -564,7 +577,8 @@
} break;
case GrGLProgram::ProgramDesc::kUniform_ColorInput:
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
- COL_UNI_NAME);
+ GrGLShaderVar::kUniform_TypeModifier,
+ COL_UNI_NAME);
programData->fUniLocations.fColorUni = kUseUniform;
*inColor = COL_UNI_NAME;
break;
@@ -582,6 +596,7 @@
void genPerVertexCoverage(ShaderCodeSegments* segments,
GrStringBuilder* inCoverage) {
segments->fVSAttrs.push_back().set(GrGLShaderVar::kFloat_Type,
+ GrGLShaderVar::kAttribute_TypeModifier,
COV_ATTR_NAME);
const char *vsName, *fsName;
append_varying(GrGLShaderVar::kFloat_Type, "Coverage",
@@ -599,11 +614,11 @@
}
void GrGLProgram::genGeometryShader(const GrGLInterface* gl,
- GLSLVersion glslVersion,
+ GrGLSLGeneration glslGeneration,
ShaderCodeSegments* segments) const {
#if GR_GL_EXPERIMENTAL_GS
if (fProgramDesc.fExperimentalGS) {
- GrAssert(glslVersion >= k150_GLSLVersion);
+ GrAssert(glslGeneration >= k150_GLSLGeneration);
segments->fGSHeader.append("layout(triangles) in;\n"
"layout(triangle_strip, max_vertices = 6) out;\n");
segments->fGSCode.append("void main() {\n"
@@ -628,7 +643,7 @@
}
bool GrGLProgram::genProgram(const GrGLInterface* gl,
- GLSLVersion glslVersion,
+ GrGLSLGeneration glslGeneration,
GrGLProgram::CachedData* programData) const {
ShaderCodeSegments segments;
@@ -676,19 +691,22 @@
// declare an output, which is incompatible with gl_FragColor/gl_FragData.
const char* fsColorOutput = NULL;
bool dualSourceOutputWritten = false;
- segments.fHeader.printf(glsl_version_string(gl, glslVersion));
- bool isColorDeclared = decl_and_get_fs_color_output(glslVersion,
+ segments.fHeader.printf(glsl_version_string(gl, glslGeneration));
+ bool isColorDeclared = decl_and_get_fs_color_output(glslGeneration,
&segments.fFSOutputs,
&fsColorOutput);
#if GR_GL_ATTRIBUTE_MATRICES
- segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
+ segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type,
+ GrGLShaderVar::kAttribute_TypeModifier, VIEW_MATRIX_NAME);
programData->fUniLocations.fViewMatrixUni = kSetAsAttribute;
#else
- segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
+ segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type,
+ GrGLShaderVar::kUniform_TypeModifier, VIEW_MATRIX_NAME);
programData->fUniLocations.fViewMatrixUni = kUseUniform;
#endif
- segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type, POS_ATTR_NAME);
+ segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
+ GrGLShaderVar::kAttribute_TypeModifier, POS_ATTR_NAME);
segments.fVSCode.append(
"void main() {\n"
@@ -716,7 +734,8 @@
if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
tex_attr_name(t, texCoordAttrs + t);
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
- texCoordAttrs[t].c_str());
+ GrGLShaderVar::kAttribute_TypeModifier,
+ texCoordAttrs[t].c_str());
}
}
@@ -775,6 +794,7 @@
}
if (needColorFilterUniform) {
segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
+ GrGLShaderVar::kUniform_TypeModifier,
COL_FILTER_UNI_NAME);
programData->fUniLocations.fColorFilterUni = kUseUniform;
}
@@ -854,7 +874,8 @@
}
if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) {
segments.fFSOutputs.push_back().set(GrGLShaderVar::kVec4f_Type,
- dual_source_output_name());
+ GrGLShaderVar::kOut_TypeModifier,
+ dual_source_output_name());
bool outputIsZero = false;
GrStringBuilder coeff;
if (ProgramDesc::kCoverage_DualSrcOutput !=
@@ -908,13 +929,13 @@
///////////////////////////////////////////////////////////////////////////
// insert GS
#if GR_DEBUG
- this->genGeometryShader(gl, glslVersion, &segments);
+ this->genGeometryShader(gl, glslGeneration, &segments);
#endif
///////////////////////////////////////////////////////////////////////////
// compile and setup attribs and unis
- if (!CompileShaders(gl, glslVersion, segments, programData)) {
+ if (!CompileShaders(gl, glslGeneration, segments, programData)) {
return false;
}
@@ -934,14 +955,11 @@
inline void expand_decls(const VarArray& vars,
const GrGLInterface* gl,
- const char* prefix,
- GrStringBuilder* string) {
+ GrStringBuilder* string,
+ GrGLSLGeneration gen) {
const int count = vars.count();
for (int i = 0; i < count; ++i) {
- string->append(prefix);
- string->append(" ");
- vars[i].appendDecl(gl, string);
- string->append(";\n");
+ vars[i].appendDecl(gl, string, gen);
}
}
@@ -980,18 +998,18 @@
inline void append_decls(const VarArray& vars,
const GrGLInterface* gl,
- const char* prefix,
StrArray* strings,
LengthArray* lengths,
- TempArray* temp) {
- expand_decls(vars, gl, prefix, &temp->push_back());
+ TempArray* temp,
+ GrGLSLGeneration gen) {
+ expand_decls(vars, gl, &temp->push_back(), gen);
append_string(temp->back(), strings, lengths);
}
}
bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
- GLSLVersion glslVersion,
+ GrGLSLGeneration glslGeneration,
const ShaderCodeSegments& segments,
CachedData* programData) {
enum { kPreAllocStringCnt = 8 };
@@ -1004,19 +1022,12 @@
GrStringBuilder inputs;
GrStringBuilder outputs;
- static const char* gVaryingPrefixes[2][2] = {{"varying", "varying"},
- {"out", "in"}};
- const char** varyingPrefixes = k110_GLSLVersion == glslVersion ?
- gVaryingPrefixes[0] :
- gVaryingPrefixes[1];
- const char* attributePrefix = k110_GLSLVersion == glslVersion ?
- "attribute" :
- "in";
-
append_string(segments.fHeader, &strs, &lengths);
- append_decls(segments.fVSUnis, gl, "uniform", &strs, &lengths, &temps);
- append_decls(segments.fVSAttrs, gl, attributePrefix, &strs, &lengths, &temps);
- append_decls(segments.fVSOutputs, gl, varyingPrefixes[0], &strs, &lengths, &temps);
+ append_decls(segments.fVSUnis, gl, &strs, &lengths, &temps, glslGeneration);
+ append_decls(segments.fVSAttrs, gl, &strs, &lengths,
+ &temps, glslGeneration);
+ append_decls(segments.fVSOutputs, gl, &strs, &lengths,
+ &temps, glslGeneration);
append_string(segments.fVSCode, &strs, &lengths);
#if PRINT_SHADERS
@@ -1037,8 +1048,10 @@
temps.reset();
append_string(segments.fHeader, &strs, &lengths);
append_string(segments.fGSHeader, &strs, &lengths);
- append_decls(segments.fGSInputs, gl, "in", &strs, &lengths, &temps);
- append_decls(segments.fGSOutputs, gl, "out", &strs, &lengths, &temps);
+ append_decls(segments.fGSInputs, gl, &strs, &lengths,
+ &temps, glslGeneration);
+ append_decls(segments.fGSOutputs, gl, &strs, &lengths,
+ &temps, glslGeneration);
append_string(segments.fGSCode, &strs, &lengths);
#if PRINT_SHADERS
print_shader(strs.count(), &strs[0], &lengths[0]);
@@ -1058,11 +1071,14 @@
append_string(segments.fHeader, &strs, &lengths);
GrStringBuilder precisionStr(GrShaderPrecision(gl));
append_string(precisionStr, &strs, &lengths);
- append_decls(segments.fFSUnis, gl, "uniform", &strs, &lengths, &temps);
- append_decls(segments.fFSInputs, gl, varyingPrefixes[1], &strs, &lengths, &temps);
+ append_decls(segments.fFSUnis, gl, &strs, &lengths, &temps, glslGeneration);
+ append_decls(segments.fFSInputs, gl, &strs, &lengths,
+ &temps, glslGeneration);
// We shouldn't have declared outputs on 1.10
- GrAssert(k110_GLSLVersion != glslVersion || segments.fFSOutputs.empty());
- append_decls(segments.fFSOutputs, gl, "out", &strs, &lengths, &temps);
+ GrAssert(k110_GLSLGeneration != glslGeneration ||
+ segments.fFSOutputs.empty());
+ append_decls(segments.fFSOutputs, gl, &strs, &lengths,
+ &temps, glslGeneration);
append_string(segments.fFSFunctions, &strs, &lengths);
append_string(segments.fFSCode, &strs, &lengths);
@@ -1334,6 +1350,7 @@
GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
+ radial2FSParams->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
radial2FSParams->setArrayCount(6);
radial2_param_name(stageNum, radial2FSParams->accessName());
segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
@@ -1523,9 +1540,11 @@
//GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
*kernel = &segments->fFSUnis.push_back();
(*kernel)->setType(GrGLShaderVar::kFloat_Type);
+ (*kernel)->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
(*kernel)->setArrayCount(desc.fKernelWidth);
GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
imgInc->setType(GrGLShaderVar::kVec2f_Type);
+ imgInc->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
convolve_param_names(stageNum,
(*kernel)->accessName(),
@@ -1612,9 +1631,11 @@
GrGLShaderVar* mat;
#if GR_GL_ATTRIBUTE_MATRICES
mat = &segments->fVSAttrs.push_back();
+ mat->setTypeModifier(GrGLShaderVar::kAttribute_TypeModifier);
locations->fTextureMatrixUni = kSetAsAttribute;
#else
mat = &segments->fVSUnis.push_back();
+ mat->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
locations->fTextureMatrixUni = kUseUniform;
#endif
tex_matrix_name(stageNum, mat->accessName());
@@ -1628,14 +1649,16 @@
}
}
- segments->fFSUnis.push_back().setType(GrGLShaderVar::kSampler2D_Type);
+ segments->fFSUnis.push_back().set(GrGLShaderVar::kSampler2D_Type,
+ GrGLShaderVar::kUniform_TypeModifier, "");
sampler_name(stageNum, segments->fFSUnis.back().accessName());
locations->fSamplerUni = kUseUniform;
const char* samplerName = segments->fFSUnis.back().getName().c_str();
const char* texelSizeName = NULL;
if (StageDesc::k2x2_FetchMode == desc.fFetchMode) {
- segments->fFSUnis.push_back().setType(GrGLShaderVar::kVec2f_Type);
+ segments->fFSUnis.push_back().set(GrGLShaderVar::kVec2f_Type,
+ GrGLShaderVar::kUniform_TypeModifier, "");
normalized_texel_size_name(stageNum, segments->fFSUnis.back().accessName());
texelSizeName = segments->fFSUnis.back().getName().c_str();
}
@@ -1758,7 +1781,8 @@
StageDesc::kCustomTextureDomain_OptFlagBit) {
GrStringBuilder texDomainName;
tex_domain_name(stageNum, &texDomainName);
- segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, texDomainName);
+ segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
+ GrGLShaderVar::kUniform_TypeModifier, texDomainName);
GrStringBuilder coordVar("clampCoord");
segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
float_vector_type_str(coordDims),