Consolidate texture access functions, provide default GrTextureAccess

Review URL: https://codereview.appspot.com/6506086/


git-svn-id: http://skia.googlecode.com/svn/trunk@5428 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2012-09-07 13:54:15 +00:00
Родитель 5e72845024
Коммит dbbf843dfe
8 изменённых файлов: 49 добавлений и 110 удалений

Просмотреть файл

@ -65,20 +65,20 @@ void GrGLColorTableEffect::emitFS(GrGLShaderBuilder* builder,
}
code->appendf("\t\t%s.a = ", outputColor);
builder->emitCustomTextureLookup(samplers[0],
"vec2(coord.a, 0.125)");
builder->appendTextureLookup(code, samplers[0], "vec2(coord.a, 0.125)");
code->append(";\n");
code->appendf("\t\t%s.r = ", outputColor);
builder->emitCustomTextureLookup(samplers[0],
"vec2(coord.r, 0.375)");
builder->appendTextureLookup(code, samplers[0], "vec2(coord.r, 0.375)");
code->append(";\n");
code->appendf("\t\t%s.g = ", outputColor);
builder->emitCustomTextureLookup(samplers[0],
"vec2(coord.g, 0.625)");
builder->appendTextureLookup(code, samplers[0], "vec2(coord.g, 0.625)");
code->append(";\n");
code->appendf("\t\t%s.b = ", outputColor);
builder->emitCustomTextureLookup(samplers[0],
"vec2(coord.b, 0.875)");
builder->appendTextureLookup(code, samplers[0], "vec2(coord.b, 0.875)");
code->append(";\n");
code->appendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
}

Просмотреть файл

@ -25,7 +25,6 @@ public:
const TextureSamplerArray& samplers) SK_OVERRIDE {
builder->fFSCode.appendf("\t\t%s = ", outputColor);
builder->appendTextureLookup(&builder->fFSCode, samplers[0]);
builder->fFSCode.appendf("%s;\n", builder->fSwizzle.c_str());
if (GrConfigConversionEffect::kNone_PMConversion == fPMConversion) {
GrAssert(fSwapRedAndBlue);
builder->fFSCode.appendf("\t%s = %s.bgra;\n", outputColor, outputColor);

Просмотреть файл

@ -964,16 +964,30 @@ GrGLProgramStage* GrGLProgram::GenStageCode(const GrCustomStage* stage,
int numTextures = stage->numTextures();
SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
// temporary until we force custom stages to provide their own texture access
SkSTArray<8, bool, true> deleteTextureAccess;
textureSamplers.push_back_n(numTextures);
deleteTextureAccess.push_back_n(numTextures);
for (int i = 0; i < numTextures; ++i) {
// Right now we don't require a texture access for every texture. This will change soon.
const GrTextureAccess* access = stage->textureAccess(i);
if (NULL != access) {
GrAssert(access->getTexture() == stage->texture(i));
textureSamplers[i].init(builder, access);
GrAssert(NULL != stage->texture(i));
if (NULL == access) {
SkString swizzle;
if (desc.fInConfigFlags & StageDesc::kSmearAlpha_InConfigFlag) {
swizzle.printf("aaaa");
} else {
swizzle.printf("rgba");
}
access = SkNEW_ARGS(GrTextureAccess, (stage->texture(i), swizzle));
deleteTextureAccess[i] = true;
} else {
textureSamplers[i].init(builder, stage->texture(i));
GrAssert(access->getTexture() == stage->texture(i));
deleteTextureAccess[i] = false;
}
textureSamplers[i].init(builder, access);
uniforms->fSamplerUniforms.push_back(textureSamplers[i].fSamplerUniform);
}
@ -991,12 +1005,15 @@ GrGLProgramStage* GrGLProgram::GenStageCode(const GrCustomStage* stage,
glStage->emitVS(builder, varyingVSName);
builder->fVSCode.appendf("\t}\n");
builder->computeSwizzle(desc.fInConfigFlags);
// Enclose custom code in a block to avoid namespace conflicts
builder->fFSCode.appendf("\t{ // %s \n", glStage->name());
glStage->emitFS(builder, fsOutColor, fsInColor, textureSamplers);
builder->fFSCode.appendf("\t}\n");
for (int i = 0; i < numTextures; ++i) {
if (deleteTextureAccess[i]) {
SkDELETE(textureSamplers[i].textureAccess());
}
}
return glStage;
}

Просмотреть файл

@ -105,19 +105,11 @@ public:
kNone_InConfigFlag = 0x00,
/**
Smear alpha across all four channels. This is incompatible with
kSmearRed. It is prefereable to perform the smear outside the
shader using GL_ARB_texture_swizzle if possible rather than
setting this flag.
Smear alpha across all four channels. It is prefereable to perform the smear
outside the shader using GL_ARB_texture_swizzle if possible rather than setting
this flag.
*/
kSmearAlpha_InConfigFlag = 0x02,
/**
Smear the red channel across all four channels. This flag is
incompatible with kSmearAlpha. It is preferable to use
GL_ARB_texture_swizzle instead of this flag.
*/
kSmearRed_InConfigFlag = 0x04,
kSmearAlpha_InConfigFlag = 0x01,
kDummyInConfigFlag,
kInConfigBitMask = (kDummyInConfigFlag-1) |

Просмотреть файл

@ -83,19 +83,6 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctx, GrGLUniformMana
, fTexCoordVaryingType(kVoid_GrSLType) {
}
void GrGLShaderBuilder::computeSwizzle(uint32_t configFlags) {
fSwizzle = "";
if (configFlags & GrGLProgram::StageDesc::kSmearAlpha_InConfigFlag) {
GrAssert(!(configFlags &
GrGLProgram::StageDesc::kSmearRed_InConfigFlag));
fSwizzle = ".aaaa";
} else if (configFlags & GrGLProgram::StageDesc::kSmearRed_InConfigFlag) {
GrAssert(!(configFlags &
GrGLProgram::StageDesc::kSmearAlpha_InConfigFlag));
fSwizzle = ".rrrr";
}
}
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
@ -126,14 +113,17 @@ void GrGLShaderBuilder::appendTextureLookup(SkString* out,
const GrGLShaderBuilder::TextureSampler& sampler,
const char* coordName,
GrSLType varyingType) const {
GrAssert(NULL != sampler.textureAccess());
SkString swizzle = build_swizzle_string(*sampler.textureAccess(), fContext.caps());
if (NULL == coordName) {
coordName = fDefaultTexCoordsName.c_str();
varyingType = kVec2f_GrSLType;
}
out->appendf("%s(%s, %s)",
out->appendf("%s(%s, %s)%s",
sample_function_name(varyingType),
this->getUniformCStr(sampler.fSamplerUniform),
coordName);
coordName, swizzle.c_str());
}
void GrGLShaderBuilder::appendTextureLookupAndModulate(
@ -145,22 +135,9 @@ void GrGLShaderBuilder::appendTextureLookupAndModulate(
GrAssert(NULL != out);
SkString lookup;
this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
lookup.append(fSwizzle.c_str());
GrGLSLModulate4f(out, modulation, lookup.c_str());
}
void GrGLShaderBuilder::emitCustomTextureLookup(const GrGLShaderBuilder::TextureSampler& sampler,
const char* coordName,
GrSLType varyingType) {
GrAssert(NULL != sampler.textureAccess());
SkString swizzle = build_swizzle_string(*sampler.textureAccess(), fContext.caps());
fFSCode.appendf("%s( %s, %s)%s;\n",
sample_function_name(varyingType),
this->getUniformCStr(sampler.fSamplerUniform),
coordName, swizzle.c_str());
}
GrCustomStage::StageKey GrGLShaderBuilder::KeyForTextureAccess(const GrTextureAccess& access,
const GrGLCaps& caps) {
GrCustomStage::StageKey key = 0;

Просмотреть файл

@ -29,7 +29,6 @@ public:
public:
TextureSampler()
: fTextureAccess(NULL)
, fTexture(NULL)
, fSamplerUniform(GrGLUniformManager::kInvalidUniformHandle) {}
TextureSampler(const TextureSampler& other) { *this = other; }
@ -38,7 +37,6 @@ public:
GrAssert(NULL == fTextureAccess);
GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
fTexture = other.fTexture;
fTextureAccess = other.fTextureAccess;
fSamplerUniform = other.fSamplerUniform;
return *this;
@ -49,7 +47,6 @@ public:
private:
void init(GrGLShaderBuilder* builder, const GrTextureAccess* access) {
GrAssert(NULL == fTextureAccess);
GrAssert(NULL == fTexture);
GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
GrAssert(NULL != builder);
@ -60,27 +57,9 @@ public:
GrAssert(GrGLUniformManager::kInvalidUniformHandle != fSamplerUniform);
fTextureAccess = access;
fTexture = access->getTexture();
}
// TODO: Remove once GrTextureAccess is required.
void init(GrGLShaderBuilder* builder, const GrTexture* texture) {
GrAssert(NULL == fTextureAccess);
GrAssert(NULL == fTexture);
GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
GrAssert(NULL != builder);
GrAssert(NULL != texture);
fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
kSampler2D_GrSLType,
"Sampler");
GrAssert(GrGLUniformManager::kInvalidUniformHandle != fSamplerUniform);
fTexture = texture;
}
const GrTextureAccess* fTextureAccess;
const GrTexture* fTexture; // TODO: remove once tex access cannot be NULL
GrGLUniformManager::UniformHandle fSamplerUniform;
friend class GrGLShaderBuilder; // to access fSamplerUniform
@ -97,30 +76,29 @@ public:
GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&);
void computeSwizzle(uint32_t configFlags);
/** 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. This should only be called by GrGLProgram.*/
void setupTextureAccess(const char* varyingFSName, GrSLType varyingType);
/** appends a texture sample with projection if necessary; if coordName is not
/** Appends a texture sample with projection if necessary; if coordName is not
specified, uses fSampleCoords. coordType must either be Vec2f or Vec3f. The latter is
interpreted as projective texture coords. */
interpreted as projective texture coords. The vec length and swizzle order of the result
depends on the GrTextureAccess associated with the TextureSampler. */
void appendTextureLookup(SkString* out,
const TextureSampler&,
const char* coordName = NULL,
GrSLType coordType = kVec2f_GrSLType) const;
/** appends a texture lookup, with swizzle as necessary. If coordName is NULL then it as if
defaultTexCoordsName() was passed. coordType must be either kVec2f or kVec3f. If modulateVar
is not NULL or "" then the texture lookup will be modulated by it. modulation must refer to
be expression that evaluates to a float or vec4. */
/** Does the work of appendTextureLookup and modulates the result by modulation. The result is
always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
called. */
void appendTextureLookupAndModulate(SkString* out,
const char* modulation,
const TextureSampler&,
const char* coordName = NULL,
GrSLType varyingType = kVec2f_GrSLType) const;
GrSLType coordType = kVec2f_GrSLType) const;
/** Gets the name of the default texture coords which are always kVec2f */
const char* defaultTexCoordsName() const { return fDefaultTexCoordsName.c_str(); }
@ -131,16 +109,6 @@ public:
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. coordType must either be Vec2f or Vec3f. The latter is interpreted
as projective texture coords.*/
void emitCustomTextureLookup(const TextureSampler&,
const char* coordName,
GrSLType coordType = kVec2f_GrSLType);
/** Emits a helper function outside of main(). Currently ShaderType must be
kFragment_ShaderType. */
void emitFunction(ShaderType shader,
@ -234,13 +202,6 @@ public:
SkString fFSCode;
bool fUsesGS;
/// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
//@{
SkString fSwizzle;
//@}
private:
enum {
kNonStageIdx = -1,

Просмотреть файл

@ -722,13 +722,7 @@ void GrGpuGL::buildProgram(bool isPoints,
if (GrPixelConfigIsAlphaOnly(texture->config())) {
// If we don't have texture swizzle support then the shader must smear the
// single channel after reading the texture.
if (this->glCaps().textureRedSupport()) {
// We can use R8 textures so use kSmearRed.
stage.fInConfigFlags |= StageDesc::kSmearRed_InConfigFlag;
} else {
// We can use A8 textures so use kSmearAlpha.
stage.fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag;
}
stage.fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag;
}
}
}

Просмотреть файл

@ -78,7 +78,6 @@ bool GrGpuGL::programUnitTest() {
static const int IN_CONFIG_FLAGS[] = {
StageDesc::kNone_InConfigFlag,
StageDesc::kSmearAlpha_InConfigFlag,
StageDesc::kSmearRed_InConfigFlag,
};
static const int NUM_TESTS = 512;