diff options
author | 2011-10-25 19:51:09 +0000 | |
---|---|---|
committer | 2011-10-25 19:51:09 +0000 | |
commit | 2a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1 (patch) | |
tree | 8aaa3d79df63356c5473120db87d53f021529e6d /src/gpu/GrGLProgram.cpp | |
parent | c32c9994555aaf3f1ffc4c551ed3b355ce02e840 (diff) |
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
Diffstat (limited to 'src/gpu/GrGLProgram.cpp')
-rw-r--r-- | src/gpu/GrGLProgram.cpp | 445 |
1 files changed, 237 insertions, 208 deletions
diff --git a/src/gpu/GrGLProgram.cpp b/src/gpu/GrGLProgram.cpp index 26ada9c988..929ee502b8 100644 --- a/src/gpu/GrGLProgram.cpp +++ b/src/gpu/GrGLProgram.cpp @@ -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()); -} |