diff --git a/src/gpu/effects/GrColorTableEffect.cpp b/src/gpu/effects/GrColorTableEffect.cpp index 56c51090b..d662398d4 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->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); } diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index ffaab35ed..a5385ac99 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -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); diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 934c4fc79..dfe5277fb 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -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; } diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index e32238b47..0dd1cb10d 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -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) | diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index b10f4e67a..17c00834f 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -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; diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index c5ac07807..e02d53d00 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -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, diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index 7e62f93cb..e39b05374 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -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; } } } diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp index c99d66ade..54f900ce9 100644 --- a/tests/GLProgramsTest.cpp +++ b/tests/GLProgramsTest.cpp @@ -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;