Some GrGLShaderBuilder cleanup
Review URL: https://codereview.appspot.com/6500043/ git-svn-id: http://skia.googlecode.com/svn/trunk@5322 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
3578eb7d06
commit
34bcb9f803
@ -1148,7 +1148,7 @@ void GrGLLightingEffect::emitFS(GrGLShaderBuilder* builder,
|
||||
interiorNormalBody.c_str(),
|
||||
&interiorNormalName);
|
||||
|
||||
code->appendf("\t\tvec2 coord = %s;\n", builder->fSampleCoords.c_str());
|
||||
code->appendf("\t\tvec2 coord = %s;\n", builder->defaultTexCoordsName());
|
||||
code->appendf("\t\tfloat m[9];\n");
|
||||
|
||||
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
|
||||
|
@ -134,10 +134,10 @@ void GrGLMagnifierEffect::emitFS(GrGLShaderBuilder* state,
|
||||
const char* samplerName) {
|
||||
SkString* code = &state->fFSCode;
|
||||
|
||||
code->appendf("\t\tvec2 coord = %s;\n", state->fSampleCoords.c_str());
|
||||
code->appendf("\t\tvec2 coord = %s;\n", state->defaultTexCoordsName());
|
||||
code->appendf("\t\tvec2 zoom_coord = %s + %s / %s;\n",
|
||||
state->getUniformCStr(fOffsetVar),
|
||||
state->fSampleCoords.c_str(),
|
||||
state->defaultTexCoordsName(),
|
||||
state->getUniformCStr(fZoomVar));
|
||||
|
||||
code->appendf("\t\tvec2 delta = min(coord, vec2(1.0, 1.0) - coord);\n");
|
||||
|
@ -334,7 +334,7 @@ void GrGLMorphologyEffect::emitFS(GrGLShaderBuilder* builder,
|
||||
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
|
||||
|
||||
code->appendf("\t\tvec2 coord = %s - %d.0 * %s;\n",
|
||||
builder->fSampleCoords.c_str(), fRadius, imgInc);
|
||||
builder->defaultTexCoordsName(), fRadius, imgInc);
|
||||
code->appendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width());
|
||||
code->appendf("\t\t\tvalue = %s(value, ", func);
|
||||
builder->emitTextureLookup(samplerName, "coord");
|
||||
|
@ -702,10 +702,11 @@ void GrGLGradientStage::emitColorLookup(GrGLShaderBuilder* builder,
|
||||
const char* tName,
|
||||
const char* outputColor,
|
||||
const char* samplerName) {
|
||||
builder->fSampleCoords.printf("vec2(%s, %s)", tName,
|
||||
builder->getUniformVariable(fFSYUni).c_str());
|
||||
builder->fComplexCoord = true;
|
||||
builder->emitDefaultFetch(outputColor, samplerName);
|
||||
|
||||
builder->fFSCode.appendf("\tvec2 coord = vec2(%s, %s);\n",
|
||||
tName,
|
||||
builder->getUniformVariable(fFSYUni).c_str());
|
||||
builder->emitTextureLookupAndModulate(outputColor, samplerName, "coord");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
@ -552,7 +552,7 @@ void GrGLLinearGradient::emitFS(GrGLShaderBuilder* builder,
|
||||
const char* inputColor,
|
||||
const char* samplerName) {
|
||||
SkString t;
|
||||
t.printf("%s.x", builder->fSampleCoords.c_str());
|
||||
t.printf("%s.x", builder->defaultTexCoordsName());
|
||||
this->emitColorLookup(builder, t.c_str(), outputColor, samplerName);
|
||||
}
|
||||
|
||||
|
@ -552,7 +552,7 @@ void GrGLRadialGradient::emitFS(GrGLShaderBuilder* builder,
|
||||
const char* inputColor,
|
||||
const char* samplerName) {
|
||||
SkString t;
|
||||
t.printf("length(%s.xy)", builder->fSampleCoords.c_str());
|
||||
t.printf("length(%s.xy)", builder->defaultTexCoordsName());
|
||||
this->emitColorLookup(builder, t.c_str(), outputColor, samplerName);
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ void GrGLSweepGradient::emitFS(GrGLShaderBuilder* builder,
|
||||
const char* samplerName) {
|
||||
SkString t;
|
||||
t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5",
|
||||
builder->fSampleCoords.c_str(), builder->fSampleCoords.c_str());
|
||||
builder->defaultTexCoordsName(), builder->defaultTexCoordsName());
|
||||
this->emitColorLookup(builder, t.c_str(), outputColor, samplerName);
|
||||
}
|
||||
|
||||
|
@ -479,7 +479,7 @@ void GrGLConical2Gradient::setupVariables(GrGLShaderBuilder* builder) {
|
||||
|
||||
// For radial gradients without perspective we can pass the linear
|
||||
// part of the quadratic as a varying.
|
||||
if (builder->fVaryingDims == builder->fCoordDims) {
|
||||
if (!builder->defaultTextureMatrixIsPerspective()) {
|
||||
builder->addVarying(kFloat_GrSLType, "Conical2BCoeff",
|
||||
&fVSVaryingName, &fFSVaryingName);
|
||||
}
|
||||
@ -497,7 +497,7 @@ void GrGLConical2Gradient::emitVS(GrGLShaderBuilder* builder,
|
||||
|
||||
// For radial gradients without perspective we can pass the linear
|
||||
// part of the quadratic as a varying.
|
||||
if (builder->fVaryingDims == builder->fCoordDims) {
|
||||
if (!builder->defaultTextureMatrixIsPerspective()) {
|
||||
// r2Var = -2 * (r2Parm[2] * varCoord.x - r2Param[3] * r2Param[5])
|
||||
code->appendf("\t%s = -2.0 * (%s * %s.x + %s * %s);\n",
|
||||
fVSVaryingName, p2.c_str(),
|
||||
@ -535,14 +535,12 @@ void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* builder,
|
||||
// If we we're able to interpolate the linear component,
|
||||
// bVar is the varying; otherwise compute it
|
||||
SkString bVar;
|
||||
if (builder->fCoordDims == builder->fVaryingDims) {
|
||||
if (!builder->defaultTextureMatrixIsPerspective()) {
|
||||
bVar = fFSVaryingName;
|
||||
GrAssert(2 == builder->fVaryingDims);
|
||||
} else {
|
||||
GrAssert(3 == builder->fVaryingDims);
|
||||
bVar = "b";
|
||||
code->appendf("\tfloat %s = -2.0 * (%s * %s.x + %s * %s);\n",
|
||||
bVar.c_str(), p2.c_str(), builder->fSampleCoords.c_str(),
|
||||
bVar.c_str(), p2.c_str(), builder->defaultTexCoordsName(),
|
||||
p3.c_str(), p5.c_str());
|
||||
}
|
||||
|
||||
@ -552,7 +550,7 @@ void GrGLConical2Gradient::emitFS(GrGLShaderBuilder* builder,
|
||||
|
||||
// c = (x^2)+(y^2) - params[4]
|
||||
code->appendf("\tfloat %s = dot(%s, %s) - %s;\n", cName.c_str(),
|
||||
builder->fSampleCoords.c_str(), builder->fSampleCoords.c_str(),
|
||||
builder->defaultTexCoordsName(), builder->defaultTexCoordsName(),
|
||||
p4.c_str());
|
||||
|
||||
// Non-degenerate case (quadratic)
|
||||
|
@ -512,7 +512,7 @@ void GrGLRadial2Gradient::setupVariables(GrGLShaderBuilder* builder) {
|
||||
|
||||
// For radial gradients without perspective we can pass the linear
|
||||
// part of the quadratic as a varying.
|
||||
if (builder->fVaryingDims == builder->fCoordDims) {
|
||||
if (!builder->defaultTextureMatrixIsPerspective()) {
|
||||
builder->addVarying(kFloat_GrSLType, "Radial2BCoeff",
|
||||
&fVSVaryingName, &fFSVaryingName);
|
||||
}
|
||||
@ -528,7 +528,7 @@ void GrGLRadial2Gradient::emitVS(GrGLShaderBuilder* builder,
|
||||
|
||||
// For radial gradients without perspective we can pass the linear
|
||||
// part of the quadratic as a varying.
|
||||
if (builder->fVaryingDims == builder->fCoordDims) {
|
||||
if (!builder->defaultTextureMatrixIsPerspective()) {
|
||||
// r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
|
||||
code->appendf("\t%s = 2.0 *(%s * %s.x - %s);\n",
|
||||
fVSVaryingName, p2.c_str(),
|
||||
@ -561,22 +561,21 @@ void GrGLRadial2Gradient::emitFS(GrGLShaderBuilder* builder,
|
||||
// If we we're able to interpolate the linear component,
|
||||
// bVar is the varying; otherwise compute it
|
||||
SkString bVar;
|
||||
if (builder->fCoordDims == builder->fVaryingDims) {
|
||||
if (!builder->defaultTextureMatrixIsPerspective()) {
|
||||
bVar = fFSVaryingName;
|
||||
GrAssert(2 == builder->fVaryingDims);
|
||||
} else {
|
||||
GrAssert(3 == builder->fVaryingDims);
|
||||
bVar = "b";
|
||||
//bVar.appendS32(stageNum);
|
||||
code->appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
|
||||
bVar.c_str(), p2.c_str(),
|
||||
builder->fSampleCoords.c_str(), p3.c_str());
|
||||
builder->defaultTexCoordsName(), p3.c_str());
|
||||
}
|
||||
|
||||
// c = (x^2)+(y^2) - params[4]
|
||||
code->appendf("\tfloat %s = dot(%s, %s) - %s;\n",
|
||||
cName.c_str(), builder->fSampleCoords.c_str(),
|
||||
builder->fSampleCoords.c_str(),
|
||||
cName.c_str(),
|
||||
builder->defaultTexCoordsName(),
|
||||
builder->defaultTexCoordsName(),
|
||||
p4.c_str());
|
||||
|
||||
// If we aren't degenerate, emit some extra code, and accept a slightly
|
||||
|
@ -69,26 +69,22 @@ void GrGLColorTableEffect::emitFS(GrGLShaderBuilder* builder,
|
||||
|
||||
const GrTextureAccess& access = *fCustomStage.textureAccess(0);
|
||||
code->appendf("\t\t%s.a = ", outputColor);
|
||||
builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
|
||||
access,
|
||||
builder->emitCustomTextureLookup(access,
|
||||
samplerName,
|
||||
"vec2(coord.a, 0.125)");
|
||||
|
||||
code->appendf("\t\t%s.r = ", outputColor);
|
||||
builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
|
||||
access,
|
||||
builder->emitCustomTextureLookup(access,
|
||||
samplerName,
|
||||
"vec2(coord.r, 0.375)");
|
||||
|
||||
code->appendf("\t\t%s.g = ", outputColor);
|
||||
builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
|
||||
access,
|
||||
builder->emitCustomTextureLookup(access,
|
||||
samplerName,
|
||||
"vec2(coord.g, 0.625)");
|
||||
|
||||
code->appendf("\t\t%s.b = ", outputColor);
|
||||
builder->emitCustomTextureLookup(GrGLShaderBuilder::kDefault_SamplerMode,
|
||||
access,
|
||||
builder->emitCustomTextureLookup(access,
|
||||
samplerName,
|
||||
"vec2(coord.b, 0.875)");
|
||||
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
const char* inputColor,
|
||||
const char* samplerName) SK_OVERRIDE {
|
||||
builder->fFSCode.append("\tvec4 tempColor;\n");
|
||||
builder->emitDefaultFetch("tempColor", samplerName);
|
||||
builder->emitTextureLookupAndModulate("tempColor", samplerName);
|
||||
if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) {
|
||||
GrAssert(fSwapRedAndBlue);
|
||||
builder->fFSCode.appendf("\t%s = tempColor.bgra;\n", outputColor);
|
||||
|
@ -75,7 +75,7 @@ void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* builder,
|
||||
const char* imgInc = builder->getUniformCStr(fImageIncrementUni);
|
||||
|
||||
code->appendf("\t\tvec2 coord = %s - %d.0 * %s;\n",
|
||||
builder->fSampleCoords.c_str(), fRadius, imgInc);
|
||||
builder->defaultTexCoordsName(), fRadius, imgInc);
|
||||
|
||||
// Manually unroll loop because some drivers don't; yields 20-30% speedup.
|
||||
for (int i = 0; i < width; i++) {
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
const char* outputColor,
|
||||
const char* inputColor,
|
||||
const char* samplerName) SK_OVERRIDE {
|
||||
builder->emitDefaultFetch(outputColor, samplerName);
|
||||
builder->emitTextureLookupAndModulate(outputColor, samplerName);
|
||||
}
|
||||
|
||||
static inline StageKey GenKey(const GrCustomStage&, const GrGLCaps&) { return 0; }
|
||||
|
@ -50,16 +50,12 @@ void GrGLTextureDomainEffect::emitFS(GrGLShaderBuilder* builder,
|
||||
const char* outputColor,
|
||||
const char* inputColor,
|
||||
const char* samplerName) {
|
||||
SkString coordVar("clampCoord");
|
||||
builder->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
|
||||
GrGLShaderVar::TypeString(GrSLFloatVectorType(builder->fCoordDims)),
|
||||
coordVar.c_str(),
|
||||
builder->fSampleCoords.c_str(),
|
||||
builder->fFSCode.appendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
|
||||
builder->defaultTexCoordsName(),
|
||||
builder->getUniformCStr(fNameUni),
|
||||
builder->getUniformCStr(fNameUni));
|
||||
builder->fSampleCoords = coordVar;
|
||||
|
||||
builder->emitDefaultFetch(outputColor, samplerName);
|
||||
builder->emitTextureLookupAndModulate(outputColor, samplerName, "clampCoord");
|
||||
}
|
||||
|
||||
void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman,
|
||||
|
@ -1000,6 +1000,7 @@ void GrGLProgram::genStageCode(int stageNum,
|
||||
const GrGLProgram::StageDesc& desc = fDesc.fStages[stageNum];
|
||||
StageUniforms& uniforms = fUniforms.fStages[stageNum];
|
||||
GrGLProgramStage* customStage = fProgramStage[stageNum];
|
||||
GrAssert(NULL != customStage);
|
||||
|
||||
GrAssert((desc.fInConfigFlags & StageDesc::kInConfigBitMask) == desc.fInConfigFlags);
|
||||
|
||||
@ -1010,25 +1011,29 @@ void GrGLProgram::genStageCode(int stageNum,
|
||||
// decide whether we need a matrix to transform texture coords and whether the varying needs a
|
||||
// perspective coord.
|
||||
const char* matName = NULL;
|
||||
GrSLType texCoordVaryingType;
|
||||
if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
|
||||
builder->fVaryingDims = builder->fCoordDims;
|
||||
texCoordVaryingType = kVec2f_GrSLType;
|
||||
} else {
|
||||
uniforms.fTextureMatrixUni = builder->addUniform(GrGLShaderBuilder::kVertex_ShaderType,
|
||||
kMat33f_GrSLType, "TexM", &matName);
|
||||
const GrGLShaderVar& mat = builder->getUniformVariable(uniforms.fTextureMatrixUni);
|
||||
|
||||
if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) {
|
||||
builder->fVaryingDims = builder->fCoordDims;
|
||||
texCoordVaryingType = kVec2f_GrSLType;
|
||||
} else {
|
||||
builder->fVaryingDims = builder->fCoordDims + 1;
|
||||
texCoordVaryingType = kVec3f_GrSLType;
|
||||
}
|
||||
}
|
||||
GrAssert(builder->fVaryingDims > 0);
|
||||
const char *varyingVSName, *varyingFSName;
|
||||
builder->addVarying(texCoordVaryingType,
|
||||
"Stage",
|
||||
&varyingVSName,
|
||||
&varyingFSName);
|
||||
builder->setupTextureAccess(varyingFSName, texCoordVaryingType);
|
||||
|
||||
// Must setup variables after computing segments->fVaryingDims
|
||||
if (NULL != customStage) {
|
||||
customStage->setupVariables(builder);
|
||||
}
|
||||
// Must setup variables after calling setupTextureAccess
|
||||
customStage->setupVariables(builder);
|
||||
|
||||
const char* samplerName;
|
||||
uniforms.fSamplerUniforms.push_back(builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
|
||||
@ -1036,45 +1041,29 @@ void GrGLProgram::genStageCode(int stageNum,
|
||||
"Sampler",
|
||||
&samplerName));
|
||||
|
||||
const char *varyingVSName, *varyingFSName;
|
||||
builder->addVarying(GrSLFloatVectorType(builder->fVaryingDims),
|
||||
"Stage",
|
||||
&varyingVSName,
|
||||
&varyingFSName);
|
||||
|
||||
if (!matName) {
|
||||
GrAssert(builder->fVaryingDims == builder->fCoordDims);
|
||||
GrAssert(kVec2f_GrSLType == texCoordVaryingType);
|
||||
builder->fVSCode.appendf("\t%s = %s;\n", varyingVSName, vsInCoord);
|
||||
} else {
|
||||
// varying = texMatrix * texCoord
|
||||
builder->fVSCode.appendf("\t%s = (%s * vec3(%s, 1))%s;\n",
|
||||
varyingVSName, matName, vsInCoord,
|
||||
vector_all_coords(builder->fVaryingDims));
|
||||
vector_all_coords(GrSLTypeToVecLength(texCoordVaryingType)));
|
||||
}
|
||||
|
||||
if (NULL != customStage) {
|
||||
builder->fVSCode.appendf("\t{ // stage %d %s\n",
|
||||
stageNum, customStage->name());
|
||||
customStage->emitVS(builder, varyingVSName);
|
||||
builder->fVSCode.appendf("\t}\n");
|
||||
}
|
||||
|
||||
/// Fragment Shader Stuff
|
||||
|
||||
builder->fSampleCoords = varyingFSName;
|
||||
|
||||
builder->setupTextureAccess(stageNum);
|
||||
builder->fVSCode.appendf("\t{ // stage %d %s\n",
|
||||
stageNum, customStage->name());
|
||||
customStage->emitVS(builder, varyingVSName);
|
||||
builder->fVSCode.appendf("\t}\n");
|
||||
|
||||
builder->computeSwizzle(desc.fInConfigFlags);
|
||||
builder->computeModulate(fsInColor);
|
||||
|
||||
if (NULL != customStage) {
|
||||
// Enclose custom code in a block to avoid namespace conflicts
|
||||
builder->fFSCode.appendf("\t{ // stage %d %s \n",
|
||||
stageNum, customStage->name());
|
||||
customStage->emitFS(builder, fsOutColor, fsInColor,
|
||||
samplerName);
|
||||
builder->fFSCode.appendf("\t}\n");
|
||||
}
|
||||
// Enclose custom code in a block to avoid namespace conflicts
|
||||
builder->fFSCode.appendf("\t{ // stage %d %s \n",
|
||||
stageNum, customStage->name());
|
||||
customStage->emitFS(builder, fsOutColor, fsInColor,
|
||||
samplerName);
|
||||
builder->fFSCode.appendf("\t}\n");
|
||||
builder->setNonStage();
|
||||
}
|
||||
|
@ -80,9 +80,16 @@ const char* GrGLSLVectorHomogCoord(int count) {
|
||||
return HOMOGS[count];
|
||||
}
|
||||
|
||||
const char* GrGLSLVectorHomogCoord(GrSLType type) {
|
||||
return GrGLSLVectorHomogCoord(GrSLTypeToVecLength(type));
|
||||
}
|
||||
|
||||
const char* GrGLSLVectorNonhomogCoords(int count) {
|
||||
static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
|
||||
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
|
||||
return NONHOMOGS[count];
|
||||
}
|
||||
|
||||
const char* GrGLSLVectorNonhomogCoord(GrSLType type) {
|
||||
return GrGLSLVectorNonhomogCoords(GrSLTypeToVecLength(type));
|
||||
}
|
||||
|
@ -45,6 +45,23 @@ enum GrSLType {
|
||||
kSampler2D_GrSLType
|
||||
};
|
||||
|
||||
namespace {
|
||||
inline int GrSLTypeToVecLength(GrSLType type) {
|
||||
static const int kVecLengths[] = {
|
||||
0, // kVoid_GrSLType
|
||||
1, // kFloat_GrSLType
|
||||
2, // kVec2f_GrSLType
|
||||
3, // kVec3f_GrSLType
|
||||
4, // kVec4f_GrSLType
|
||||
1, // kMat33f_GrSLType
|
||||
1, // kMat44f_GrSLType
|
||||
1, // kSampler2D_GrSLType
|
||||
};
|
||||
GrAssert((size_t) type < GR_ARRAY_COUNT(kVecLengths));
|
||||
return kVecLengths[type];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the most recent GLSL Generation compatible with the OpenGL context.
|
||||
*/
|
||||
@ -82,11 +99,12 @@ bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen,
|
||||
GrSLType GrSLFloatVectorType(int count);
|
||||
|
||||
/** Return the GLSL swizzle operator for a homogenous component of a vector
|
||||
with the given number of coordnates, e.g. 2 -> ".y", 3 -> ".z" */
|
||||
with the given number of coordinates, e.g. 2 -> ".y", 3 -> ".z" */
|
||||
const char* GrGLSLVectorHomogCoord(int count);
|
||||
const char* GrGLSLVectorHomogCoord(GrSLType type);
|
||||
|
||||
/** Return the GLSL swizzle operator for a nonhomogenous components of a vector
|
||||
with the given number of coordnates, e.g. 2 -> ".x", 3 -> ".xy" */
|
||||
with the given number of coordinates, e.g. 2 -> ".x", 3 -> ".xy" */
|
||||
const char* GrGLSLVectorNonhomogCoords(int count);
|
||||
|
||||
const char* GrGLSLVectorNonhomogCoords(GrSLType type);
|
||||
#endif
|
||||
|
@ -22,29 +22,25 @@ static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar:
|
||||
typedef GrGLUniformManager::UniformHandle UniformHandle;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkString build_sampler_string(GrGLShaderBuilder::SamplerMode samplerMode) {
|
||||
SkString sampler("texture2D");
|
||||
switch (samplerMode) {
|
||||
case GrGLShaderBuilder::kDefault_SamplerMode:
|
||||
break;
|
||||
case GrGLShaderBuilder::kProj_SamplerMode:
|
||||
sampler.append("Proj");
|
||||
break;
|
||||
case GrGLShaderBuilder::kExplicitDivide_SamplerMode:
|
||||
break;
|
||||
}
|
||||
namespace {
|
||||
|
||||
return sampler;
|
||||
inline const char* sample_function_name(GrSLType type) {
|
||||
if (kVec2f_GrSLType == type) {
|
||||
return "texture2D";
|
||||
} else {
|
||||
GrAssert(kVec3f_GrSLType == type);
|
||||
return "texture2DProj";
|
||||
}
|
||||
}
|
||||
|
||||
static bool texture_requires_alpha_to_red_swizzle(const GrGLCaps& caps,
|
||||
inline bool texture_requires_alpha_to_red_swizzle(const GrGLCaps& caps,
|
||||
const GrTextureAccess& access) {
|
||||
return GrPixelConfigIsAlphaOnly(access.getTexture()->config()) && caps.textureRedSupport() &&
|
||||
access.referencesAlpha();
|
||||
}
|
||||
|
||||
static SkString build_swizzle_string(const GrTextureAccess& textureAccess,
|
||||
const GrGLCaps& caps) {
|
||||
SkString build_swizzle_string(const GrTextureAccess& textureAccess,
|
||||
const GrGLCaps& caps) {
|
||||
const GrTextureAccess::Swizzle& swizzle = textureAccess.getSwizzle();
|
||||
if (0 == swizzle[0]) {
|
||||
return SkString("");
|
||||
@ -63,6 +59,8 @@ static SkString build_swizzle_string(const GrTextureAccess& textureAccess,
|
||||
return swizzleOut;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Architectural assumption: always 2-d input coords.
|
||||
@ -79,8 +77,7 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctx, GrGLUniformMana
|
||||
, fFSInputs(kVarsPerBlock)
|
||||
, fFSOutputs(kMaxFSOutputs)
|
||||
, fUsesGS(false)
|
||||
, fVaryingDims(0)
|
||||
, fComplexCoord(false)
|
||||
, fTexCoordVaryingType(kVoid_GrSLType)
|
||||
, fContext(ctx)
|
||||
, fUniformManager(uniformManager)
|
||||
, fCurrentStage(kNonStageIdx) {
|
||||
@ -107,65 +104,59 @@ void GrGLShaderBuilder::computeModulate(const char* fsInColor) {
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLShaderBuilder::setupTextureAccess(int stageNum) {
|
||||
SkString retval;
|
||||
|
||||
SamplerMode mode = kDefault_SamplerMode;
|
||||
// FIXME: we aren't currently using Proj.
|
||||
if (fVaryingDims != fCoordDims) {
|
||||
mode = kExplicitDivide_SamplerMode;
|
||||
void GrGLShaderBuilder::setupTextureAccess(const char* varyingFSName, GrSLType varyingType) {
|
||||
// FIXME: We don't know how the custom stage will manipulate the coords. So we give up on using
|
||||
// projective texturing and always give the stage 2D coords. This will be fixed when custom
|
||||
// stages are repsonsible for setting up their own tex coords / tex matrices.
|
||||
switch (varyingType) {
|
||||
case kVec2f_GrSLType:
|
||||
fDefaultTexCoordsName = varyingFSName;
|
||||
fTexCoordVaryingType = kVec2f_GrSLType;
|
||||
break;
|
||||
case kVec3f_GrSLType: {
|
||||
fDefaultTexCoordsName = "inCoord";
|
||||
GrAssert(kNonStageIdx != fCurrentStage);
|
||||
fDefaultTexCoordsName.appendS32(fCurrentStage);
|
||||
fTexCoordVaryingType = kVec3f_GrSLType;
|
||||
fFSCode.appendf("\t%s %s = %s.xy / %s.z;\n",
|
||||
GrGLShaderVar::TypeString(kVec2f_GrSLType),
|
||||
fDefaultTexCoordsName.c_str(),
|
||||
varyingFSName,
|
||||
varyingFSName);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GrCrash("Tex coords must either be Vec2f or Vec3f");
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case kDefault_SamplerMode:
|
||||
GrAssert(fVaryingDims == fCoordDims);
|
||||
// Do nothing
|
||||
break;
|
||||
case kProj_SamplerMode:
|
||||
// Do nothing
|
||||
break;
|
||||
case kExplicitDivide_SamplerMode:
|
||||
retval = "inCoord";
|
||||
retval.appendS32(stageNum);
|
||||
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;
|
||||
}
|
||||
fTexFunc = build_sampler_string(mode);
|
||||
fComplexCoord = false;
|
||||
}
|
||||
|
||||
void GrGLShaderBuilder::emitTextureLookup(const char* samplerName,
|
||||
const char* coordName) {
|
||||
const char* coordName,
|
||||
GrSLType varyingType) {
|
||||
if (NULL == coordName) {
|
||||
coordName = fSampleCoords.c_str();
|
||||
coordName = fDefaultTexCoordsName.c_str();
|
||||
varyingType = kVec2f_GrSLType;
|
||||
}
|
||||
fFSCode.appendf("%s(%s, %s)", fTexFunc.c_str(), samplerName, coordName);
|
||||
fFSCode.appendf("%s(%s, %s)", sample_function_name(varyingType), samplerName, coordName);
|
||||
}
|
||||
|
||||
void GrGLShaderBuilder::emitDefaultFetch(const char* outColor,
|
||||
const char* samplerName) {
|
||||
void GrGLShaderBuilder::emitTextureLookupAndModulate(const char* outColor,
|
||||
const char* samplerName,
|
||||
const char* coordName,
|
||||
GrSLType varyingType) {
|
||||
fFSCode.appendf("\t%s = ", outColor);
|
||||
this->emitTextureLookup(samplerName);
|
||||
this->emitTextureLookup(samplerName, coordName, varyingType);
|
||||
fFSCode.appendf("%s%s;\n", fSwizzle.c_str(), fModulate.c_str());
|
||||
}
|
||||
|
||||
void GrGLShaderBuilder::emitCustomTextureLookup(SamplerMode samplerMode,
|
||||
const GrTextureAccess& textureAccess,
|
||||
void GrGLShaderBuilder::emitCustomTextureLookup(const GrTextureAccess& textureAccess,
|
||||
const char* samplerName,
|
||||
const char* coordName) {
|
||||
const char* coordName,
|
||||
GrSLType varyingType) {
|
||||
GrAssert(samplerName && coordName);
|
||||
SkString sampler = build_sampler_string(samplerMode);
|
||||
SkString swizzle = build_swizzle_string(textureAccess, fContext.caps());
|
||||
|
||||
fFSCode.appendf("%s( %s, %s)%s;\n", sampler.c_str(), samplerName,
|
||||
fFSCode.appendf("%s( %s, %s)%s;\n", sample_function_name(varyingType), samplerName,
|
||||
coordName, swizzle.c_str());
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ class GrGLContextInfo;
|
||||
class GrGLShaderBuilder {
|
||||
|
||||
public:
|
||||
|
||||
enum ShaderType {
|
||||
kVertex_ShaderType = 0x1,
|
||||
kGeometry_ShaderType = 0x2,
|
||||
@ -35,36 +34,45 @@ public:
|
||||
void computeSwizzle(uint32_t configFlags);
|
||||
void computeModulate(const char* fsInColor);
|
||||
|
||||
// TODO: needs a better name
|
||||
enum SamplerMode {
|
||||
kDefault_SamplerMode,
|
||||
kProj_SamplerMode,
|
||||
kExplicitDivide_SamplerMode // must do an explicit divide
|
||||
};
|
||||
|
||||
/** Determines whether we should use texture2D() or texture2Dproj(), and if an explicit divide
|
||||
is required for the sample coordinates, creates the new variable and emits the code to
|
||||
initialize it. */
|
||||
void setupTextureAccess(int stageNum);
|
||||
initialize it. This should only be called by GrGLProgram.*/
|
||||
void setupTextureAccess(const char* varyingFSName, GrSLType varyingType);
|
||||
|
||||
/** texture2D(samplerName, coordName), with projection if necessary; if coordName is not
|
||||
specified, uses fSampleCoords. */
|
||||
specified, uses fSampleCoords. coordType must either be Vec2f or Vec3f. The latter is
|
||||
interpreted as projective texture coords. */
|
||||
void emitTextureLookup(const char* samplerName,
|
||||
const char* coordName = NULL);
|
||||
const char* coordName = NULL,
|
||||
GrSLType coordType = kVec2f_GrSLType);
|
||||
|
||||
/** sets outColor to results of texture lookup, with swizzle, and/or modulate as necessary */
|
||||
void emitDefaultFetch(const char* outColor,
|
||||
const char* samplerName);
|
||||
/** sets outColor to results of texture lookup, with swizzle, and/or modulate as necessary. If
|
||||
coordName is NULL then it as if defaultTexCoordsName() was passed. coordType must be either
|
||||
kVec2f or kVec3f. */
|
||||
void emitTextureLookupAndModulate(const char* outColor,
|
||||
const char* samplerName,
|
||||
const char* coordName = NULL,
|
||||
GrSLType coordType = kVec2f_GrSLType);
|
||||
|
||||
/** Gets the name of the default texture coords which are always kVec2f */
|
||||
const char* defaultTexCoordsName() const { return fDefaultTexCoordsName.c_str(); }
|
||||
|
||||
/* Returns true if the texture matrix from which the default texture coords are computed has
|
||||
perspective. */
|
||||
bool defaultTextureMatrixIsPerspective() const {
|
||||
return fTexCoordVaryingType == kVec3f_GrSLType;
|
||||
}
|
||||
|
||||
/** Emits a texture lookup to the shader code with the form:
|
||||
texture2D{Proj}(samplerName, coordName).swizzle
|
||||
The routine selects the type of texturing based on samplerMode.
|
||||
The generated swizzle state is built based on the format of the texture and the requested
|
||||
swizzle access pattern. */
|
||||
void emitCustomTextureLookup(SamplerMode samplerMode,
|
||||
const GrTextureAccess& textureAccess,
|
||||
swizzle access pattern. coordType must either be Vec2f or Vec3f. The latter is interpreted
|
||||
as projective texture coords.*/
|
||||
void emitCustomTextureLookup(const GrTextureAccess& textureAccess,
|
||||
const char* samplerName,
|
||||
const char* coordName);
|
||||
const char* coordName,
|
||||
GrSLType coordType = kVec2f_GrSLType);
|
||||
|
||||
/** Emits a helper function outside of main(). Currently ShaderType must be
|
||||
kFragment_ShaderType. */
|
||||
@ -162,19 +170,9 @@ public:
|
||||
/// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
|
||||
//@{
|
||||
|
||||
int fVaryingDims;
|
||||
static const int fCoordDims = 2;
|
||||
|
||||
/// True if fSampleCoords is an expression; false if it's a bare
|
||||
/// variable name
|
||||
bool fComplexCoord;
|
||||
SkString fSampleCoords;
|
||||
|
||||
SkString fSwizzle;
|
||||
SkString fModulate;
|
||||
|
||||
SkString fTexFunc;
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
@ -186,6 +184,14 @@ private:
|
||||
GrGLUniformManager& fUniformManager;
|
||||
int fCurrentStage;
|
||||
SkString fFSFunctions;
|
||||
|
||||
/// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
|
||||
//@{
|
||||
GrSLType fTexCoordVaryingType; // the type, either Vec2f or Vec3f, of the coords passed
|
||||
// as a varying from the VS to the FS.
|
||||
SkString fDefaultTexCoordsName; // the name of the default 2D coords value.
|
||||
//@}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user