зеркало из https://github.com/mozilla/moz-skia.git
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:
Родитель
5e72845024
Коммит
dbbf843dfe
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче