aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-09-07 14:20:32 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-09-07 14:20:32 +0000
commit4592df8e9142803c44334273f1b4f37d09ec65dd (patch)
tree30586e70775eeada778bf6efa8c08a08dbe604d0
parent78201c27a7adf6772a067a47d7aa0e31eb614820 (diff)
Revert 5428 and 5429.
git-svn-id: http://skia.googlecode.com/svn/trunk@5430 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/gpu/effects/GrColorTableEffect.cpp16
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp1
-rw-r--r--src/gpu/gl/GrGLProgram.cpp29
-rw-r--r--src/gpu/gl/GrGLProgram.h16
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp33
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.h55
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp8
-rw-r--r--tests/GLProgramsTest.cpp1
8 files changed, 110 insertions, 49 deletions
diff --git a/src/gpu/effects/GrColorTableEffect.cpp b/src/gpu/effects/GrColorTableEffect.cpp
index d662398d4a..56c51090be 100644
--- a/src/gpu/effects/GrColorTableEffect.cpp
+++ b/src/gpu/effects/GrColorTableEffect.cpp
@@ -65,20 +65,20 @@ void GrGLColorTableEffect::emitFS(GrGLShaderBuilder* builder,
}
code->appendf("\t\t%s.a = ", outputColor);
- builder->appendTextureLookup(code, samplers[0], "vec2(coord.a, 0.125)");
- code->append(";\n");
+ builder->emitCustomTextureLookup(samplers[0],
+ "vec2(coord.a, 0.125)");
code->appendf("\t\t%s.r = ", outputColor);
- builder->appendTextureLookup(code, samplers[0], "vec2(coord.r, 0.375)");
- code->append(";\n");
+ builder->emitCustomTextureLookup(samplers[0],
+ "vec2(coord.r, 0.375)");
code->appendf("\t\t%s.g = ", outputColor);
- builder->appendTextureLookup(code, samplers[0], "vec2(coord.g, 0.625)");
- code->append(";\n");
+ builder->emitCustomTextureLookup(samplers[0],
+ "vec2(coord.g, 0.625)");
code->appendf("\t\t%s.b = ", outputColor);
- builder->appendTextureLookup(code, samplers[0], "vec2(coord.b, 0.875)");
- code->append(";\n");
+ builder->emitCustomTextureLookup(samplers[0],
+ "vec2(coord.b, 0.875)");
code->appendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
}
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index a5385ac999..ffaab35ed5 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -25,6 +25,7 @@ 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);
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index dfe5277fb9..934c4fc796 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -964,30 +964,16 @@ 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);
- 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 {
+ if (NULL != access) {
GrAssert(access->getTexture() == stage->texture(i));
- deleteTextureAccess[i] = false;
+ textureSamplers[i].init(builder, access);
+ } else {
+ textureSamplers[i].init(builder, stage->texture(i));
}
- textureSamplers[i].init(builder, access);
uniforms->fSamplerUniforms.push_back(textureSamplers[i].fSamplerUniform);
}
@@ -1005,15 +991,12 @@ 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;
}
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 0dd1cb10d5..e32238b471 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -105,11 +105,19 @@ public:
kNone_InConfigFlag = 0x00,
/**
- 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.
+ 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.
*/
- kSmearAlpha_InConfigFlag = 0x01,
+ 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,
kDummyInConfigFlag,
kInConfigBitMask = (kDummyInConfigFlag-1) |
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index 68f2eb330b..b10f4e67ad 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -83,6 +83,19 @@ 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
@@ -113,17 +126,14 @@ 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)%s;\n",
+ out->appendf("%s(%s, %s)",
sample_function_name(varyingType),
this->getUniformCStr(sampler.fSamplerUniform),
- coordName, swizzle.c_str());
+ coordName);
}
void GrGLShaderBuilder::appendTextureLookupAndModulate(
@@ -135,9 +145,22 @@ 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;
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index e02d53d00a..c5ac078071 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -29,6 +29,7 @@ public:
public:
TextureSampler()
: fTextureAccess(NULL)
+ , fTexture(NULL)
, fSamplerUniform(GrGLUniformManager::kInvalidUniformHandle) {}
TextureSampler(const TextureSampler& other) { *this = other; }
@@ -37,6 +38,7 @@ public:
GrAssert(NULL == fTextureAccess);
GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
+ fTexture = other.fTexture;
fTextureAccess = other.fTextureAccess;
fSamplerUniform = other.fSamplerUniform;
return *this;
@@ -47,6 +49,7 @@ public:
private:
void init(GrGLShaderBuilder* builder, const GrTextureAccess* access) {
GrAssert(NULL == fTextureAccess);
+ GrAssert(NULL == fTexture);
GrAssert(GrGLUniformManager::kInvalidUniformHandle == fSamplerUniform);
GrAssert(NULL != builder);
@@ -57,9 +60,27 @@ 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
@@ -76,29 +97,30 @@ 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. The vec length and swizzle order of the result
- depends on the GrTextureAccess associated with the TextureSampler. */
+ interpreted as projective texture coords. */
void appendTextureLookup(SkString* out,
const TextureSampler&,
const char* coordName = NULL,
GrSLType coordType = kVec2f_GrSLType) const;
- /** 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. */
+ /** 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. */
void appendTextureLookupAndModulate(SkString* out,
const char* modulation,
const TextureSampler&,
const char* coordName = NULL,
- GrSLType coordType = kVec2f_GrSLType) const;
+ GrSLType varyingType = kVec2f_GrSLType) const;
/** Gets the name of the default texture coords which are always kVec2f */
const char* defaultTexCoordsName() const { return fDefaultTexCoordsName.c_str(); }
@@ -109,6 +131,16 @@ 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,
@@ -202,6 +234,13 @@ public:
SkString fFSCode;
bool fUsesGS;
+ /// Per-stage settings - only valid while we're inside GrGLProgram::genStageCode().
+ //@{
+
+ SkString fSwizzle;
+
+ //@}
+
private:
enum {
kNonStageIdx = -1,
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index e39b05374f..7e62f93cbb 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -722,7 +722,13 @@ 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.
- stage.fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag;
+ 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;
+ }
}
}
}
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 54f900ce9d..c99d66adea 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -78,6 +78,7 @@ bool GrGpuGL::programUnitTest() {
static const int IN_CONFIG_FLAGS[] = {
StageDesc::kNone_InConfigFlag,
StageDesc::kSmearAlpha_InConfigFlag,
+ StageDesc::kSmearRed_InConfigFlag,
};
static const int NUM_TESTS = 512;