diff options
-rw-r--r-- | src/gpu/effects/GrConvolutionEffect.cpp | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 86 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.cpp | 52 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.h | 33 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 86 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.h | 50 |
6 files changed, 163 insertions, 146 deletions
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp index 8ccf5859e4..15f2aebd5f 100644 --- a/src/gpu/effects/GrConvolutionEffect.cpp +++ b/src/gpu/effects/GrConvolutionEffect.cpp @@ -124,7 +124,7 @@ void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* state, fKernelWidth); code->appendf("\t\t\tsum += "); - this->emitTextureLookup(code, samplerName, "coord"); + state->emitTextureLookup(samplerName, "coord"); code->appendf(" * %s;\n", kernelIndex.c_str()); code->appendf("\t\t\tcoord += %s;\n", diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 8fc3ac2b3b..2fdcd77674 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -1405,10 +1405,8 @@ void gen2x2FS(int stageNum, GrGLProgram::StageUniLocations* locations, const char* samplerName, const char* texelSizeName, - const char* swizzle, const char* fsOutColor, - GrStringBuilder& texFunc, - GrStringBuilder& modulate) { + GrStringBuilder& texFunc) { locations->fNormalizedTexelSizeUni = kUseUniform; if (segments->fComplexCoord) { // assign the coord to a var rather than compute 4x. @@ -1422,11 +1420,11 @@ void gen2x2FS(int stageNum, GrAssert(2 == segments->fCoordDims); 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, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, swizzle); - segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, swizzle); - segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, swizzle); - segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, swizzle); - segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str()); + segments->fFSCode.appendf("\tvec4 %s = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, segments->fSwizzle.c_str()); + segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, segments->fSwizzle.c_str()); + segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, segments->fSwizzle.c_str()); + segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, segments->fSwizzle.c_str()); + segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), segments->fModulate.c_str()); } @@ -1456,11 +1454,9 @@ void genMorphologyFS(int stageNum, const StageDesc& desc, GrGLShaderBuilder* segments, const char* samplerName, - const char* swizzle, const char* imageIncrementName, const char* fsOutColor, - GrStringBuilder& texFunc, - GrStringBuilder& modulate) { + GrStringBuilder& texFunc) { GrStringBuilder valueVar("value"); valueVar.appendS32(stageNum); GrStringBuilder coordVar("coord"); @@ -1482,13 +1478,14 @@ void genMorphologyFS(int stageNum, segments->fFSCode.appendf("\t\t%s = %s(%s, %s(%s, %s)%s);\n", valueVar.c_str(), isDilate ? "max" : "min", valueVar.c_str(), texFunc.c_str(), - samplerName, coordVar.c_str(), swizzle); + samplerName, coordVar.c_str(), + segments->fSwizzle.c_str()); 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, - valueVar.c_str(), modulate.c_str()); + valueVar.c_str(), segments->fModulate.c_str()); } } @@ -1660,25 +1657,8 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, (StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag | StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag); - const char* swizzle = ""; - if (desc.fInConfigFlags & StageDesc::kSwapRAndB_InConfigFlag) { - GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag)); - GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearRed_InConfigFlag)); - swizzle = ".bgra"; - } else if (desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag) { - GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); - GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearRed_InConfigFlag)); - swizzle = ".aaaa"; - } else if (desc.fInConfigFlags & StageDesc::kSmearRed_InConfigFlag) { - GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); - GrAssert(!(desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag)); - swizzle = ".rrrr"; - } - - GrStringBuilder modulate; - if (NULL != fsInColor) { - modulate.printf(" * %s", fsInColor); - } + segments->computeSwizzle(desc.fInConfigFlags); + segments->computeModulate(fsInColor); if (desc.fOptFlags & StageDesc::kCustomTextureDomain_OptFlagBit) { @@ -1697,14 +1677,24 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, locations->fTexDomUni = kUseUniform; } + if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit | + StageDesc::kNoPerspective_OptFlagBit)) { + segments->setSamplerMode(GrGLShaderBuilder::kDefault_SamplerMode); + } else if (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping && + StageDesc::kSingle_FetchMode == desc.fFetchMode) { + segments->setSamplerMode(GrGLShaderBuilder::kProj_SamplerMode); + } else { + segments->setSamplerMode( + GrGLShaderBuilder::kExplicitDivide_SamplerMode); + } + // NOTE: GrGLProgramStages are now responsible for fetching if (NULL == customStage) { switch (desc.fFetchMode) { case StageDesc::k2x2_FetchMode: GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); gen2x2FS(stageNum, segments, locations, - samplerName, texelSizeName, swizzle, fsOutColor, - texFunc, modulate); + samplerName, texelSizeName, fsOutColor, texFunc); break; case StageDesc::kConvolution_FetchMode: GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); @@ -1713,8 +1703,7 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, case StageDesc::kErode_FetchMode: GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); genMorphologyFS(stageNum, desc, segments, - samplerName, swizzle, imageIncrementName, fsOutColor, - texFunc, modulate); + samplerName, imageIncrementName, fsOutColor, texFunc); break; default: if (desc.fInConfigFlags & kMulByAlphaMask) { @@ -1728,43 +1717,28 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, fsOutColor, texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), - swizzle); + segments->fSwizzle.c_str()); if (desc.fInConfigFlags & StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag) { segments->fFSCode.appendf("\t%s = vec4(ceil(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n", fsOutColor, fsOutColor, fsOutColor, - fsOutColor, modulate.c_str()); + fsOutColor, segments->fModulate.c_str()); } else { segments->fFSCode.appendf("\t%s = vec4(floor(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n", fsOutColor, fsOutColor, fsOutColor, - fsOutColor, modulate.c_str()); + fsOutColor, segments->fModulate.c_str()); } } else { - segments->fFSCode.appendf("\t%s = %s(%s, %s)%s%s;\n", - fsOutColor, texFunc.c_str(), - samplerName, - segments->fSampleCoords.c_str(), - swizzle, modulate.c_str()); + segments->emitDefaultFetch(fsOutColor, samplerName); } } } if (NULL != customStage) { - if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit | - StageDesc::kNoPerspective_OptFlagBit)) { - customStage->setSamplerMode(GrGLProgramStage::kDefault_SamplerMode); - } else if (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping && - StageDesc::kSingle_FetchMode == desc.fFetchMode) { - customStage->setSamplerMode(GrGLProgramStage::kProj_SamplerMode); - } else { - customStage->setSamplerMode( - GrGLProgramStage::kExplicitDivide_SamplerMode); - } - // Enclose custom code in a block to avoid namespace conflicts segments->fFSCode.appendf("\t{ // stage %d %s \n", stageNum, customStage->name()); - customStage->emitTextureSetup(segments); + segments->emitTextureSetup(); customStage->emitFS(segments, fsOutColor, fsInColor, samplerName); segments->fFSCode.appendf("\t}\n"); } diff --git a/src/gpu/gl/GrGLProgramStage.cpp b/src/gpu/gl/GrGLProgramStage.cpp index b5e2228cd9..96c6e55bed 100644 --- a/src/gpu/gl/GrGLProgramStage.cpp +++ b/src/gpu/gl/GrGLProgramStage.cpp @@ -41,55 +41,3 @@ void GrGLProgramStage::setData(const GrGLInterface*, } -void GrGLProgramStage::emitTextureSetup(GrGLShaderBuilder* segments) { - GrStringBuilder retval; - - switch (fSamplerMode) { - case kDefault_SamplerMode: - // Fall through - case kProj_SamplerMode: - // Do nothing - break; - case kExplicitDivide_SamplerMode: - retval = "inCoord"; - segments->fFSCode.appendf("\t %s %s = %s%s / %s%s\n", - GrGLShaderVar::TypeString - (GrSLFloatVectorType(segments->fCoordDims)), - retval.c_str(), - segments->fSampleCoords.c_str(), - GrGLSLVectorNonhomogCoords(segments->fVaryingDims), - segments->fSampleCoords.c_str(), - GrGLSLVectorHomogCoord(segments->fVaryingDims)); - segments->fSampleCoords = retval; - break; - } -} - -void GrGLProgramStage::emitTextureLookup(GrStringBuilder* code, - const char* samplerName, - const char* coordName) { - switch (fSamplerMode) { - case kDefault_SamplerMode: - // Fall through - case kExplicitDivide_SamplerMode: - code->appendf("texture2D(%s, %s)", samplerName, coordName); - break; - case kProj_SamplerMode: - code->appendf("texture2DProj(%s, %s)", samplerName, coordName); - break; - } - -} - -void GrGLProgramStage::emitDefaultFetch(GrGLShaderBuilder* state, - const char* fsOutColor, - const char* samplerName, - const char* swizzle, - const char* modulate) { - state->fFSCode.appendf("\t%s = ", fsOutColor); - this->emitTextureLookup(&state->fFSCode, samplerName, - state->fSampleCoords.c_str()); - state->fFSCode.appendf("%s%s;\n", swizzle, modulate); -} - - diff --git a/src/gpu/gl/GrGLProgramStage.h b/src/gpu/gl/GrGLProgramStage.h index 60ab60dbd8..0d2d66061e 100644 --- a/src/gpu/gl/GrGLProgramStage.h +++ b/src/gpu/gl/GrGLProgramStage.h @@ -96,43 +96,10 @@ public: GrCustomStage* stage, int stageNum); - // TODO: needs a better name - enum SamplerMode { - kDefault_SamplerMode, - kProj_SamplerMode, - kExplicitDivide_SamplerMode // must do an explicit divide - }; - - void setSamplerMode(SamplerMode samplerMode) { fSamplerMode = samplerMode; } - - /** Does perspective divide or other necessary transform, then - updates the name of the sample coordinates. */ - void emitTextureSetup(GrGLShaderBuilder* segments); - - /** Human-meaningful string to identify this effect; may be embedded - in generated shader code. Because the implementation is delegated to - the factory, the name will be the same as that of the generating - GrCustomStage. */ const char* name() const { return fFactory.name(); } protected: - /** Convenience function for subclasses to write texture2D() or - texture2DProj(), depending on fSamplerMode. */ - void emitTextureLookup(GrStringBuilder* code, - const char* samplerName, - const char* coordName); - - /** Standard texture fetch, complete with swizzle & modulate if - appropriate. */ - void emitDefaultFetch(GrGLShaderBuilder* state, - const char* fsOutColor, - const char* samplerName, - const char* swizzle, - const char* modulate); - - SamplerMode fSamplerMode; - const GrProgramStageFactory& fFactory; }; diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index 321e507e4b..289e7be634 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -6,6 +6,7 @@ */ #include "gl/GrGLShaderBuilder.h" +#include "gl/GrGLProgram.h" namespace { @@ -33,6 +34,7 @@ GrGLShaderBuilder::GrGLShaderBuilder() , fFSOutputs(sMaxFSOutputs) , fUsesGS(false) , fVaryingDims(0) + , fSamplerMode(kDefault_SamplerMode) , fComplexCoord(false) { } @@ -85,3 +87,87 @@ void GrGLShaderBuilder::appendVarying(GrSLType type, nameWithStage.appendS32(stageNum); this->appendVarying(type, nameWithStage.c_str(), vsOutName, fsInName); } + +void GrGLShaderBuilder::computeSwizzle(uint32_t configFlags) { + static const uint32_t kMulByAlphaMask = + (GrGLProgram::StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag | + GrGLProgram::StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag); + + fSwizzle = ""; + if (configFlags & GrGLProgram::StageDesc::kSwapRAndB_InConfigFlag) { + GrAssert(!(configFlags & + GrGLProgram::StageDesc::kSmearAlpha_InConfigFlag)); + GrAssert(!(configFlags & + GrGLProgram::StageDesc::kSmearRed_InConfigFlag)); + fSwizzle = ".bgra"; + } else if (configFlags & GrGLProgram::StageDesc::kSmearAlpha_InConfigFlag) { + GrAssert(!(configFlags & kMulByAlphaMask)); + GrAssert(!(configFlags & + GrGLProgram::StageDesc::kSmearRed_InConfigFlag)); + fSwizzle = ".aaaa"; + } else if (configFlags & GrGLProgram::StageDesc::kSmearRed_InConfigFlag) { + GrAssert(!(configFlags & kMulByAlphaMask)); + GrAssert(!(configFlags & + GrGLProgram::StageDesc::kSmearAlpha_InConfigFlag)); + fSwizzle = ".rrrr"; + } +} + +void GrGLShaderBuilder::computeModulate(const char* fsInColor) { + if (NULL != fsInColor) { + fModulate.printf(" * %s", fsInColor); + } +} + +void GrGLShaderBuilder::emitTextureSetup() { + GrStringBuilder retval; + + switch (fSamplerMode) { + case kDefault_SamplerMode: + // Fall through + case kProj_SamplerMode: + // Do nothing + break; + case kExplicitDivide_SamplerMode: + retval = "inCoord"; + fFSCode.appendf("\t %s %s = %s%s / %s%s\n", + GrGLShaderVar::TypeString + (GrSLFloatVectorType(fCoordDims)), + retval.c_str(), + fSampleCoords.c_str(), + GrGLSLVectorNonhomogCoords(fVaryingDims), + fSampleCoords.c_str(), + GrGLSLVectorHomogCoord(fVaryingDims)); + fSampleCoords = retval; + break; + } +} + +void GrGLShaderBuilder::emitTextureLookup(const char* samplerName, + const char* coordName) { + if (NULL == coordName) { + coordName = fSampleCoords.c_str(); + } + switch (fSamplerMode) { + default: + SkDEBUGFAIL("Unknown sampler mode"); + // Fall through + case kDefault_SamplerMode: + // Fall through + case kExplicitDivide_SamplerMode: + fFSCode.appendf("texture2D(%s, %s)", samplerName, coordName); + break; + case kProj_SamplerMode: + fFSCode.appendf("texture2DProj(%s, %s)", samplerName, coordName); + break; + } + +} + +void GrGLShaderBuilder::emitDefaultFetch(const char* outColor, + const char* samplerName) { + fFSCode.appendf("\t%s = ", outColor); + this->emitTextureLookup(samplerName); + fFSCode.appendf("%s%s;\n", fSwizzle.c_str(), fModulate.c_str()); +} + diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 6a7e279748..889219d876 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -37,6 +37,38 @@ public: const char** vsOutName = NULL, const char** fsInName = NULL); + void computeSwizzle(uint32_t configFlags); + void computeModulate(const char* fsInColor); + + void emitTextureSetup(); + + /** texture2D(samplerName, coordName), with projection + if necessary; if coordName is not specified, + uses fSampleCoords. */ + void emitTextureLookup(const char* samplerName, + const char* coordName = NULL); + + /** sets outColor to results of texture lookup, with + swizzle, and/or modulate as necessary */ + void emitDefaultFetch(const char* outColor, + const char* samplerName); + + // TODO: needs a better name + enum SamplerMode { + kDefault_SamplerMode, + kProj_SamplerMode, + kExplicitDivide_SamplerMode // must do an explicit divide + }; + + // TODO: computing this requires information about fetch mode + // && coord mapping, as well as StageDesc::fOptFlags - proably + // need to set up default value and have some custom stages + // override as necessary? + void setSamplerMode(SamplerMode samplerMode) { + fSamplerMode = samplerMode; + } + + GrStringBuilder fHeader; // VS+FS, GLSL version, etc VarArray fVSUnis; VarArray fVSAttrs; @@ -53,16 +85,26 @@ public: GrStringBuilder fFSCode; bool fUsesGS; - /// Per-stage settings + /// Per-stage settings - only valid while we're inside + /// GrGLProgram::genStageCode(). //@{ - int fVaryingDims; + int fVaryingDims; static const int fCoordDims = 2; +protected: + + SamplerMode fSamplerMode; + +public: + /// True if fSampleCoords is an expression; false if it's a bare /// variable name - bool fComplexCoord; - GrStringBuilder fSampleCoords; + bool fComplexCoord; + GrStringBuilder fSampleCoords; + + GrStringBuilder fSwizzle; + GrStringBuilder fModulate; //@} |