aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/effects/GrConvolutionEffect.cpp2
-rw-r--r--src/gpu/gl/GrGLProgram.cpp86
-rw-r--r--src/gpu/gl/GrGLProgramStage.cpp52
-rw-r--r--src/gpu/gl/GrGLProgramStage.h33
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp86
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h50
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;
//@}