Move helper functions out of header file, write new genProgram helpers.
Review: codereview.appspot.com/5304045/ git-svn-id: http://skia.googlecode.com/svn/trunk@2532 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
c32c999455
commit
2a2e3ef5b8
@ -16,6 +16,13 @@
|
||||
|
||||
namespace {
|
||||
|
||||
enum {
|
||||
/// Used to mark a StageUniLocation field that should be bound
|
||||
/// to a uniform during getUniformLocationsAndInitCache().
|
||||
kUseUniform = 2000
|
||||
};
|
||||
|
||||
|
||||
const char* GrPrecision(const GrGLInterface* gl) {
|
||||
if (gl->supportsES()) {
|
||||
return "mediump";
|
||||
@ -541,6 +548,53 @@ bool decl_and_get_fs_color_output(GrGLProgram::GLSLVersion v,
|
||||
}
|
||||
}
|
||||
|
||||
void genInputColor(GrGLProgram::ProgramDesc::ColorType colorType,
|
||||
GrGLProgram::CachedData* programData,
|
||||
ShaderCodeSegments* segments,
|
||||
GrStringBuilder* inColor) {
|
||||
switch (colorType) {
|
||||
case GrGLProgram::ProgramDesc::kAttribute_ColorType: {
|
||||
segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
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);
|
||||
*inColor = fsName;
|
||||
} break;
|
||||
case GrGLProgram::ProgramDesc::kUniform_ColorType:
|
||||
segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
COL_UNI_NAME);
|
||||
programData->fUniLocations.fColorUni = kUseUniform;
|
||||
*inColor = COL_UNI_NAME;
|
||||
break;
|
||||
case GrGLProgram::ProgramDesc::kTransBlack_ColorType:
|
||||
GrAssert(!"needComputedColor should be false.");
|
||||
break;
|
||||
case GrGLProgram::ProgramDesc::kSolidWhite_ColorType:
|
||||
break;
|
||||
default:
|
||||
GrCrash("Unknown color type.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void genPerVertexCoverage(ShaderCodeSegments* segments,
|
||||
GrStringBuilder* inCoverage) {
|
||||
segments->fVSAttrs.push_back().set(GrGLShaderVar::kFloat_Type,
|
||||
COV_ATTR_NAME);
|
||||
const char *vsName, *fsName;
|
||||
append_varying(GrGLShaderVar::kFloat_Type, "Coverage",
|
||||
segments, &vsName, &fsName);
|
||||
segments->fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName);
|
||||
if (inCoverage->size()) {
|
||||
segments->fFSCode.appendf("\tfloat edgeAndAttrCov = %s * %s;\n",
|
||||
fsName, inCoverage->c_str());
|
||||
*inCoverage = "edgeAndAttrCov";
|
||||
} else {
|
||||
*inCoverage = fsName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GrGLProgram::genGeometryShader(const GrGLInterface* gl,
|
||||
@ -644,30 +698,8 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
|
||||
GrStringBuilder inColor;
|
||||
|
||||
if (needComputedColor) {
|
||||
switch (fProgramDesc.fColorType) {
|
||||
case ProgramDesc::kAttribute_ColorType: {
|
||||
segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
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);
|
||||
inColor = fsName;
|
||||
} break;
|
||||
case ProgramDesc::kUniform_ColorType:
|
||||
segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
|
||||
COL_UNI_NAME);
|
||||
programData->fUniLocations.fColorUni = kUseUniform;
|
||||
inColor = COL_UNI_NAME;
|
||||
break;
|
||||
case ProgramDesc::kTransBlack_ColorType:
|
||||
GrAssert(!"needComputedColor should be false.");
|
||||
break;
|
||||
case ProgramDesc::kSolidWhite_ColorType:
|
||||
break;
|
||||
default:
|
||||
GrCrash("Unknown color type.");
|
||||
break;
|
||||
}
|
||||
genInputColor((ProgramDesc::ColorType) fProgramDesc.fColorType,
|
||||
programData, &segments, &inColor);
|
||||
}
|
||||
|
||||
// we output point size in the GS if present
|
||||
@ -714,14 +746,14 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
|
||||
inCoords = texCoordAttrs[tcIdx].c_str();
|
||||
}
|
||||
|
||||
genStageCode(gl,
|
||||
s,
|
||||
fProgramDesc.fStages[s],
|
||||
inColor.size() ? inColor.c_str() : NULL,
|
||||
outColor.c_str(),
|
||||
inCoords,
|
||||
&segments,
|
||||
&programData->fUniLocations.fStages[s]);
|
||||
this->genStageCode(gl,
|
||||
s,
|
||||
fProgramDesc.fStages[s],
|
||||
inColor.size() ? inColor.c_str() : NULL,
|
||||
outColor.c_str(),
|
||||
inCoords,
|
||||
&segments,
|
||||
&programData->fUniLocations.fStages[s]);
|
||||
inColor = outColor;
|
||||
}
|
||||
}
|
||||
@ -785,19 +817,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
|
||||
|
||||
// include explicit per-vertex coverage if we have it
|
||||
if (GrDrawTarget::kCoverage_VertexLayoutBit & layout) {
|
||||
segments.fVSAttrs.push_back().set(GrGLShaderVar::kFloat_Type,
|
||||
COV_ATTR_NAME);
|
||||
const char *vsName, *fsName;
|
||||
append_varying(GrGLShaderVar::kFloat_Type, "Coverage",
|
||||
&segments, &vsName, &fsName);
|
||||
segments.fVSCode.appendf("\t%s = " COV_ATTR_NAME ";\n", vsName);
|
||||
if (inCoverage.size()) {
|
||||
segments.fFSCode.appendf("\tfloat edgeAndAttrCov = %s * %s;\n",
|
||||
fsName, inCoverage.c_str());
|
||||
inCoverage = "edgeAndAttrCov";
|
||||
} else {
|
||||
inCoverage = fsName;
|
||||
}
|
||||
genPerVertexCoverage(&segments, &inCoverage);
|
||||
}
|
||||
|
||||
GrStringBuilder outCoverage;
|
||||
@ -1287,14 +1307,59 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLInterface* gl,
|
||||
// Stage code generation
|
||||
//============================================================================
|
||||
|
||||
static bool genRadial2GradientCoordMapping(int stageNum,
|
||||
ShaderCodeSegments* segments,
|
||||
const char* radial2VaryingFSName,
|
||||
const char* radial2ParamsName,
|
||||
GrStringBuilder& sampleCoords,
|
||||
GrStringBuilder& fsCoordName,
|
||||
int varyingDims,
|
||||
int coordDims) {
|
||||
namespace {
|
||||
|
||||
bool isRadialMapping(GrGLProgram::StageDesc::CoordMapping mapping) {
|
||||
return
|
||||
(GrGLProgram::StageDesc::kRadial2Gradient_CoordMapping == mapping ||
|
||||
GrGLProgram::StageDesc::kRadial2GradientDegenerate_CoordMapping == mapping);
|
||||
}
|
||||
|
||||
const char* genRadialVS(int stageNum,
|
||||
ShaderCodeSegments* segments,
|
||||
GrGLProgram::StageUniLocations* locations,
|
||||
const char** radial2VaryingVSName,
|
||||
const char** radial2VaryingFSName,
|
||||
const char* varyingVSName,
|
||||
int varyingDims, int coordDims) {
|
||||
|
||||
GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
|
||||
radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
|
||||
radial2FSParams->setArrayCount(6);
|
||||
radial2_param_name(stageNum, radial2FSParams->accessName());
|
||||
segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
|
||||
|
||||
locations->fRadial2Uni = kUseUniform;
|
||||
|
||||
// for radial grads without perspective we can pass the linear
|
||||
// part of the quadratic as a varying.
|
||||
if (varyingDims == coordDims) {
|
||||
GrAssert(2 == coordDims);
|
||||
append_varying(GrGLShaderVar::kFloat_Type,
|
||||
"Radial2BCoeff",
|
||||
stageNum,
|
||||
segments,
|
||||
radial2VaryingVSName,
|
||||
radial2VaryingFSName);
|
||||
|
||||
// r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
|
||||
const char* r2ParamName = radial2FSParams->getName().c_str();
|
||||
segments->fVSCode.appendf("\t%s = 2.0 *(%s[2] * %s.x - %s[3]);\n",
|
||||
*radial2VaryingVSName, r2ParamName,
|
||||
varyingVSName, r2ParamName);
|
||||
}
|
||||
|
||||
return radial2FSParams->getName().c_str();
|
||||
}
|
||||
|
||||
bool genRadial2GradientCoordMapping(int stageNum,
|
||||
ShaderCodeSegments* segments,
|
||||
const char* radial2VaryingFSName,
|
||||
const char* radial2ParamsName,
|
||||
GrStringBuilder& sampleCoords,
|
||||
GrStringBuilder& fsCoordName,
|
||||
int varyingDims,
|
||||
int coordDims) {
|
||||
GrStringBuilder cName("c");
|
||||
GrStringBuilder ac4Name("ac4");
|
||||
GrStringBuilder rootName("root");
|
||||
@ -1342,14 +1407,14 @@ static bool genRadial2GradientCoordMapping(int stageNum,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool genRadial2GradientDegenerateCoordMapping(int stageNum,
|
||||
ShaderCodeSegments* segments,
|
||||
const char* radial2VaryingFSName,
|
||||
const char* radial2ParamsName,
|
||||
GrStringBuilder& sampleCoords,
|
||||
GrStringBuilder& fsCoordName,
|
||||
int varyingDims,
|
||||
int coordDims) {
|
||||
bool genRadial2GradientDegenerateCoordMapping(int stageNum,
|
||||
ShaderCodeSegments* segments,
|
||||
const char* radial2VaryingFSName,
|
||||
const char* radial2ParamsName,
|
||||
GrStringBuilder& sampleCoords,
|
||||
GrStringBuilder& fsCoordName,
|
||||
int varyingDims,
|
||||
int coordDims) {
|
||||
GrStringBuilder cName("c");
|
||||
|
||||
cName.appendS32(stageNum);
|
||||
@ -1381,6 +1446,106 @@ static bool genRadial2GradientDegenerateCoordMapping(int stageNum,
|
||||
return true;
|
||||
}
|
||||
|
||||
void gen2x2FS(int stageNum,
|
||||
ShaderCodeSegments* segments,
|
||||
GrGLProgram::StageUniLocations* locations,
|
||||
GrStringBuilder* sampleCoords,
|
||||
const char* samplerName,
|
||||
const char* texelSizeName,
|
||||
const char* smear,
|
||||
const char* fsOutColor,
|
||||
GrStringBuilder& texFunc,
|
||||
GrStringBuilder& modulate,
|
||||
bool complexCoord,
|
||||
int coordDims) {
|
||||
locations->fNormalizedTexelSizeUni = kUseUniform;
|
||||
if (complexCoord) {
|
||||
// assign the coord to a var rather than compute 4x.
|
||||
GrStringBuilder coordVar("tCoord");
|
||||
coordVar.appendS32(stageNum);
|
||||
segments->fFSCode.appendf("\t%s %s = %s;\n",
|
||||
float_vector_type_str(coordDims),
|
||||
coordVar.c_str(), sampleCoords->c_str());
|
||||
*sampleCoords = coordVar;
|
||||
}
|
||||
GrAssert(2 == coordDims);
|
||||
GrStringBuilder accumVar("accum");
|
||||
accumVar.appendS32(stageNum);
|
||||
segments->fFSCode.appendf("\tvec4 %s = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
|
||||
segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
|
||||
segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
|
||||
segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
|
||||
segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str());
|
||||
|
||||
}
|
||||
|
||||
void genConvolutionVS(int stageNum,
|
||||
const GrGLProgram::ProgramDesc::StageDesc& desc,
|
||||
ShaderCodeSegments* segments,
|
||||
GrGLProgram::StageUniLocations* locations,
|
||||
const char** kernelName,
|
||||
const char** imageIncrementName,
|
||||
const char* varyingVSName) {
|
||||
GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
|
||||
kernel->setType(GrGLShaderVar::kFloat_Type);
|
||||
kernel->setArrayCount(desc.fKernelWidth);
|
||||
GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
|
||||
imgInc->setType(GrGLShaderVar::kVec2f_Type);
|
||||
|
||||
convolve_param_names(stageNum,
|
||||
kernel->accessName(),
|
||||
imgInc->accessName());
|
||||
*kernelName = kernel->getName().c_str();
|
||||
*imageIncrementName = imgInc->getName().c_str();
|
||||
|
||||
// need image increment in both VS and FS
|
||||
segments->fVSUnis.push_back(*imgInc).setEmitPrecision(true);
|
||||
|
||||
locations->fKernelUni = kUseUniform;
|
||||
locations->fImageIncrementUni = kUseUniform;
|
||||
float scale = (desc.fKernelWidth - 1) * 0.5f;
|
||||
segments->fVSCode.appendf("\t%s -= vec2(%g, %g) * %s;\n",
|
||||
varyingVSName, scale, scale,
|
||||
*imageIncrementName);
|
||||
}
|
||||
|
||||
void genConvolutionFS(int stageNum,
|
||||
const GrGLProgram::ProgramDesc::StageDesc& desc,
|
||||
ShaderCodeSegments* segments,
|
||||
const char* samplerName,
|
||||
const char* kernelName,
|
||||
const char* smear,
|
||||
const char* imageIncrementName,
|
||||
const char* fsOutColor,
|
||||
GrStringBuilder& sampleCoords,
|
||||
GrStringBuilder& texFunc,
|
||||
GrStringBuilder& modulate) {
|
||||
GrStringBuilder sumVar("sum");
|
||||
sumVar.appendS32(stageNum);
|
||||
GrStringBuilder coordVar("coord");
|
||||
coordVar.appendS32(stageNum);
|
||||
|
||||
segments->fFSCode.appendf("\tvec4 %s = vec4(0, 0, 0, 0);\n",
|
||||
sumVar.c_str());
|
||||
segments->fFSCode.appendf("\tvec2 %s = %s;\n",
|
||||
coordVar.c_str(),
|
||||
sampleCoords.c_str());
|
||||
segments->fFSCode.appendf("\tfor (int i = 0; i < %d; i++) {\n",
|
||||
desc.fKernelWidth);
|
||||
segments->fFSCode.appendf("\t\t%s += %s(%s, %s)%s * %s[i];\n",
|
||||
sumVar.c_str(), texFunc.c_str(),
|
||||
samplerName, coordVar.c_str(), smear,
|
||||
kernelName);
|
||||
segments->fFSCode.appendf("\t\t%s += %s;\n",
|
||||
coordVar.c_str(),
|
||||
imageIncrementName);
|
||||
segments->fFSCode.appendf("\t}\n");
|
||||
segments->fFSCode.appendf("\t%s = %s%s;\n", fsOutColor,
|
||||
sumVar.c_str(), modulate.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GrGLProgram::genStageCode(const GrGLInterface* gl,
|
||||
int stageNum,
|
||||
const GrGLProgram::StageDesc& desc,
|
||||
@ -1458,21 +1623,20 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
|
||||
const char *radial2VaryingVSName = NULL;
|
||||
const char *radial2VaryingFSName = NULL;
|
||||
|
||||
if (StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping ||
|
||||
StageDesc::kRadial2GradientDegenerate_CoordMapping == desc.fCoordMapping) {
|
||||
radial2ParamsName = this->genRadialVS(stageNum, segments,
|
||||
locations,
|
||||
&radial2VaryingVSName,
|
||||
&radial2VaryingFSName,
|
||||
varyingVSName,
|
||||
varyingDims, coordDims);
|
||||
if (isRadialMapping((StageDesc::CoordMapping) desc.fCoordMapping)) {
|
||||
radial2ParamsName = genRadialVS(stageNum, segments,
|
||||
locations,
|
||||
&radial2VaryingVSName,
|
||||
&radial2VaryingFSName,
|
||||
varyingVSName,
|
||||
varyingDims, coordDims);
|
||||
}
|
||||
|
||||
const char* kernelName = NULL;
|
||||
const char* imageIncrementName = NULL;
|
||||
if (ProgramDesc::StageDesc::kConvolution_FetchMode == desc.fFetchMode) {
|
||||
this->genConvolutionVS(stageNum, desc, segments, locations,
|
||||
&kernelName, &imageIncrementName, varyingVSName);
|
||||
genConvolutionVS(stageNum, desc, segments, locations,
|
||||
&kernelName, &imageIncrementName, varyingVSName);
|
||||
}
|
||||
|
||||
/// Fragment Shader Stuff
|
||||
@ -1565,12 +1729,12 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
|
||||
|
||||
switch (desc.fFetchMode) {
|
||||
case StageDesc::k2x2_FetchMode:
|
||||
this->gen2x2FS(stageNum, segments, locations, &sampleCoords,
|
||||
gen2x2FS(stageNum, segments, locations, &sampleCoords,
|
||||
samplerName, texelSizeName, smear, fsOutColor,
|
||||
texFunc, modulate, complexCoord, coordDims);
|
||||
break;
|
||||
case ProgramDesc::StageDesc::kConvolution_FetchMode:
|
||||
this->genConvolutionFS(stageNum, desc, segments,
|
||||
genConvolutionFS(stageNum, desc, segments,
|
||||
samplerName, kernelName, smear, imageIncrementName, fsOutColor,
|
||||
sampleCoords, texFunc, modulate);
|
||||
break;
|
||||
@ -1582,139 +1746,4 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
|
||||
}
|
||||
}
|
||||
|
||||
const char* GrGLProgram::genRadialVS(int stageNum,
|
||||
ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations,
|
||||
const char** radial2VaryingVSName,
|
||||
const char** radial2VaryingFSName,
|
||||
const char* varyingVSName,
|
||||
int varyingDims, int coordDims) const {
|
||||
|
||||
GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
|
||||
radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
|
||||
radial2FSParams->setArrayCount(6);
|
||||
radial2_param_name(stageNum, radial2FSParams->accessName());
|
||||
segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
|
||||
|
||||
locations->fRadial2Uni = kUseUniform;
|
||||
|
||||
// for radial grads without perspective we can pass the linear
|
||||
// part of the quadratic as a varying.
|
||||
if (varyingDims == coordDims) {
|
||||
GrAssert(2 == coordDims);
|
||||
append_varying(GrGLShaderVar::kFloat_Type,
|
||||
"Radial2BCoeff",
|
||||
stageNum,
|
||||
segments,
|
||||
radial2VaryingVSName,
|
||||
radial2VaryingFSName);
|
||||
|
||||
// r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
|
||||
const char* r2ParamName = radial2FSParams->getName().c_str();
|
||||
segments->fVSCode.appendf("\t%s = 2.0 *(%s[2] * %s.x - %s[3]);\n",
|
||||
*radial2VaryingVSName, r2ParamName,
|
||||
varyingVSName, r2ParamName);
|
||||
}
|
||||
|
||||
return radial2FSParams->getName().c_str();
|
||||
}
|
||||
|
||||
|
||||
void GrGLProgram::gen2x2FS(int stageNum,
|
||||
ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations,
|
||||
GrStringBuilder* sampleCoords,
|
||||
const char* samplerName,
|
||||
const char* texelSizeName,
|
||||
const char* smear,
|
||||
const char* fsOutColor,
|
||||
GrStringBuilder& texFunc,
|
||||
GrStringBuilder& modulate,
|
||||
bool complexCoord,
|
||||
int coordDims) const {
|
||||
locations->fNormalizedTexelSizeUni = kUseUniform;
|
||||
if (complexCoord) {
|
||||
// assign the coord to a var rather than compute 4x.
|
||||
GrStringBuilder coordVar("tCoord");
|
||||
coordVar.appendS32(stageNum);
|
||||
segments->fFSCode.appendf("\t%s %s = %s;\n",
|
||||
float_vector_type_str(coordDims),
|
||||
coordVar.c_str(), sampleCoords->c_str());
|
||||
*sampleCoords = coordVar;
|
||||
}
|
||||
GrAssert(2 == coordDims);
|
||||
GrStringBuilder accumVar("accum");
|
||||
accumVar.appendS32(stageNum);
|
||||
segments->fFSCode.appendf("\tvec4 %s = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
|
||||
segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
|
||||
segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
|
||||
segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, smear);
|
||||
segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str());
|
||||
|
||||
}
|
||||
|
||||
void GrGLProgram::genConvolutionVS(int stageNum,
|
||||
const ProgramDesc::StageDesc& desc,
|
||||
ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations,
|
||||
const char** kernelName,
|
||||
const char** imageIncrementName,
|
||||
const char* varyingVSName) const {
|
||||
GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
|
||||
kernel->setType(GrGLShaderVar::kFloat_Type);
|
||||
kernel->setArrayCount(desc.fKernelWidth);
|
||||
GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
|
||||
imgInc->setType(GrGLShaderVar::kVec2f_Type);
|
||||
|
||||
convolve_param_names(stageNum,
|
||||
kernel->accessName(),
|
||||
imgInc->accessName());
|
||||
*kernelName = kernel->getName().c_str();
|
||||
*imageIncrementName = imgInc->getName().c_str();
|
||||
|
||||
// need image increment in both VS and FS
|
||||
segments->fVSUnis.push_back(*imgInc).setEmitPrecision(true);
|
||||
|
||||
locations->fKernelUni = kUseUniform;
|
||||
locations->fImageIncrementUni = kUseUniform;
|
||||
float scale = (desc.fKernelWidth - 1) * 0.5f;
|
||||
segments->fVSCode.appendf("\t%s -= vec2(%g, %g) * %s;\n",
|
||||
varyingVSName, scale, scale,
|
||||
*imageIncrementName);
|
||||
}
|
||||
|
||||
void GrGLProgram::genConvolutionFS(int stageNum,
|
||||
const ProgramDesc::StageDesc& desc,
|
||||
ShaderCodeSegments* segments,
|
||||
const char* samplerName,
|
||||
const char* kernelName,
|
||||
const char* smear,
|
||||
const char* imageIncrementName,
|
||||
const char* fsOutColor,
|
||||
GrStringBuilder& sampleCoords,
|
||||
GrStringBuilder& texFunc,
|
||||
GrStringBuilder& modulate) const {
|
||||
GrStringBuilder sumVar("sum");
|
||||
sumVar.appendS32(stageNum);
|
||||
GrStringBuilder coordVar("coord");
|
||||
coordVar.appendS32(stageNum);
|
||||
|
||||
segments->fFSCode.appendf("\tvec4 %s = vec4(0, 0, 0, 0);\n",
|
||||
sumVar.c_str());
|
||||
segments->fFSCode.appendf("\tvec2 %s = %s;\n",
|
||||
coordVar.c_str(),
|
||||
sampleCoords.c_str());
|
||||
segments->fFSCode.appendf("\tfor (int i = 0; i < %d; i++) {\n",
|
||||
desc.fKernelWidth);
|
||||
segments->fFSCode.appendf("\t\t%s += %s(%s, %s)%s * %s[i];\n",
|
||||
sumVar.c_str(), texFunc.c_str(),
|
||||
samplerName, coordVar.c_str(), smear,
|
||||
kernelName);
|
||||
segments->fFSCode.appendf("\t\t%s += %s;\n",
|
||||
coordVar.c_str(),
|
||||
imageIncrementName);
|
||||
segments->fFSCode.appendf("\t}\n");
|
||||
segments->fFSCode.appendf("\t%s = %s%s;\n", fsOutColor,
|
||||
sumVar.c_str(), modulate.c_str());
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
return 7 + GrDrawTarget::kMaxTexCoords + 3 * stage;
|
||||
}
|
||||
|
||||
private:
|
||||
public:
|
||||
|
||||
// Parameters that affect code generation
|
||||
// These structs should be kept compact; they are the input to an
|
||||
@ -199,11 +199,13 @@ private:
|
||||
} fProgramDesc;
|
||||
GR_STATIC_ASSERT(!(sizeof(ProgramDesc) % 4));
|
||||
|
||||
const ProgramDesc& getDesc() { return fProgramDesc; }
|
||||
|
||||
// for code readability
|
||||
typedef ProgramDesc::StageDesc StageDesc;
|
||||
|
||||
private:
|
||||
|
||||
const ProgramDesc& getDesc() { return fProgramDesc; }
|
||||
|
||||
public:
|
||||
enum {
|
||||
kUnusedUniform = -1,
|
||||
@ -300,12 +302,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
enum {
|
||||
kUseUniform = 2000
|
||||
};
|
||||
|
||||
// should set all fields in locations var to kUseUniform if the
|
||||
// corresponding uniform is required for the program.
|
||||
// Determines which uniforms will need to be bound.
|
||||
void genStageCode(const GrGLInterface* gl,
|
||||
int stageNum,
|
||||
const ProgramDesc::StageDesc& desc,
|
||||
@ -347,52 +345,10 @@ private:
|
||||
bool bindDualSrcOut,
|
||||
CachedData* programData) const;
|
||||
|
||||
// Gets locations for all uniforms set to kUseUniform and initializes cache
|
||||
// to invalid values.
|
||||
// Binds uniforms; initializes cache to invalid values.
|
||||
void getUniformLocationsAndInitCache(const GrGLInterface* gl,
|
||||
CachedData* programData) const;
|
||||
|
||||
const char* genRadialVS(int stageNum, ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations,
|
||||
const char** radial2VaryingVSName,
|
||||
const char** radial2VaryingFSName,
|
||||
const char* varyingVSName,
|
||||
int varyingDims, int coordDims) const;
|
||||
|
||||
void gen2x2FS(int stageNum,
|
||||
ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations,
|
||||
GrStringBuilder* sampleCoords,
|
||||
const char* samplerName,
|
||||
const char* texelSizeName,
|
||||
const char* smear,
|
||||
const char* fsOutColor,
|
||||
GrStringBuilder& texFunc,
|
||||
GrStringBuilder& modulate,
|
||||
bool complexCoord,
|
||||
int coordDims) const;
|
||||
|
||||
void genConvolutionVS(int stageNum,
|
||||
const ProgramDesc::StageDesc& desc,
|
||||
ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations,
|
||||
const char** kernelName,
|
||||
const char** imageIncrementName,
|
||||
const char* varyingVSName) const;
|
||||
|
||||
|
||||
void genConvolutionFS(int stageNum,
|
||||
const ProgramDesc::StageDesc& desc,
|
||||
ShaderCodeSegments* segments,
|
||||
const char* samplerName,
|
||||
const char* kernelName,
|
||||
const char* smear,
|
||||
const char* imageIncrementName,
|
||||
const char* fsOutColor,
|
||||
GrStringBuilder& sampleCoords,
|
||||
GrStringBuilder& texFunc,
|
||||
GrStringBuilder& modulate) const;
|
||||
|
||||
friend class GrGpuGLShaders;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user