diff options
author | 2013-01-11 21:08:55 +0000 | |
---|---|---|
committer | 2013-01-11 21:08:55 +0000 | |
commit | 371e105da5d9fdfff3b4242b37ff6fc09214c8c8 (patch) | |
tree | cfcca4200f2b8eb016f6ea3643f2602bc4076909 /src/gpu | |
parent | 95146ebc43175ae0c1cd3a116509d92aa1a445ab (diff) |
Add GrEffect::updateKnownColorComponents(). It is used to determine whether the output of an effect has a constant output value for r,g,b, or a.
Review URL: https://codereview.appspot.com/7064057
git-svn-id: http://skia.googlecode.com/svn/trunk@7144 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 62 | ||||
-rw-r--r-- | src/gpu/GrEffect.cpp | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrSingleTextureEffect.cpp | 11 | ||||
-rw-r--r-- | src/gpu/effects/GrSingleTextureEffect.h | 4 |
4 files changed, 52 insertions, 29 deletions
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 3c112871e5..e7609d88fc 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -827,40 +827,52 @@ bool GrDrawTarget::canTweakAlphaForCoverage() const { bool GrDrawTarget::srcAlphaWillBeOne(GrVertexLayout layout) const { const GrDrawState& drawState = this->getDrawState(); + uint32_t validComponentFlags; + GrColor color; // Check if per-vertex or constant color may have partial alpha - if ((layout & kColor_VertexLayoutBit) || - 0xff != GrColorUnpackA(drawState.getColor())) { - return false; - } - // Check if color filter could introduce an alpha - // (TODO: Consider being more aggressive with regards to detecting 0xff - // final alpha from color filter). - if (SkXfermode::kDst_Mode != drawState.getColorFilterMode()) { - return false; - } - int stageCnt; - // Check whether coverage is treated as color - if (drawState.isCoverageDrawing()) { - if (0xff != GrColorUnpackA(drawState.getCoverage())) { - return false; - } - stageCnt = GrDrawState::kNumStages; + if (layout & kColor_VertexLayoutBit) { + validComponentFlags = 0; } else { - stageCnt = drawState.getFirstCoverageStage(); + validComponentFlags = GrEffect::kAll_ValidComponentFlags; + color = drawState.getColor(); } - // Check if a color stage could create a partial alpha + + // Run through the color stages + int stageCnt = drawState.getFirstCoverageStage(); for (int s = 0; s < stageCnt; ++s) { const GrEffect* effect = drawState.getStage(s).getEffect(); if (NULL != effect) { - // FIXME: The param indicates whether the texture is opaque or not. However, the effect - // already controls its textures. It really needs to know whether the incoming color - // (from a uni, per-vertex colors, or previous stage) is opaque or not. - if (!effect->isOpaque(true)) { - return false; + effect->getConstantColorComponents(&color, &validComponentFlags); + } + } + + // Check if the color filter could introduce an alpha. + // We could skip the above work when this is true, but it is rare and the right fix is to make + // the color filter a GrEffect and implement getConstantColorComponents() for it. + if (SkXfermode::kDst_Mode != drawState.getColorFilterMode()) { + validComponentFlags = 0; + } + + // Check whether coverage is treated as color. If so we run through the coverage computation. + if (drawState.isCoverageDrawing()) { + GrColor coverageColor = drawState.getCoverage(); + GrColor oldColor = color; + color = 0; + for (int c = 0; c < 4; ++c) { + if (validComponentFlags & (1 << c)) { + U8CPU a = (oldColor >> (c * 8)) & 0xff; + U8CPU b = (coverageColor >> (c * 8)) & 0xff; + color |= (SkMulDiv255Round(a, b) << (c * 8)); + } + } + for (int s = drawState.getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) { + const GrEffect* effect = drawState.getStage(s).getEffect(); + if (NULL != effect) { + effect->getConstantColorComponents(&color, &validComponentFlags); } } } - return true; + return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color); } namespace { diff --git a/src/gpu/GrEffect.cpp b/src/gpu/GrEffect.cpp index dbfb6b014a..534489fd4e 100644 --- a/src/gpu/GrEffect.cpp +++ b/src/gpu/GrEffect.cpp @@ -61,10 +61,6 @@ int32_t GrBackendEffectFactory::fCurrEffectClassID = GrBackendEffectFactory::kIl GrEffect::~GrEffect() { } -bool GrEffect::isOpaque(bool inputTextureIsOpaque) const { - return false; -} - const char* GrEffect::name() const { return this->getFactory().name(); } diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp index 14f5b64472..2cf83472d7 100644 --- a/src/gpu/effects/GrSingleTextureEffect.cpp +++ b/src/gpu/effects/GrSingleTextureEffect.cpp @@ -98,6 +98,17 @@ GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, GrSingleTextureEffect::~GrSingleTextureEffect() { } +void GrSingleTextureEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { + // If the input alpha is 0xff and the texture has no alpha channel, then the output alpha is + // 0xff + if ((*validFlags & kA_ValidComponentFlag) && 0xFF == GrColorUnpackA(*color) && + GrPixelConfigIsOpaque(fTextureAccess.getTexture()->config())) { + *validFlags = kA_ValidComponentFlag; + } else { + *validFlags = 0; + } +} + const GrBackendEffectFactory& GrSingleTextureEffect::getFactory() const { return GrTBackendEffectFactory<GrSingleTextureEffect>::getInstance(); } diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h index fca5e93858..b732913c38 100644 --- a/src/gpu/effects/GrSingleTextureEffect.h +++ b/src/gpu/effects/GrSingleTextureEffect.h @@ -35,6 +35,10 @@ public: static const char* Name() { return "Single Texture"; } + /** Note that if this class is sub-classed, the subclass may have to override this function. + */ + virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; + const SkMatrix& getMatrix() const { return fMatrix; } typedef GrGLSingleTextureEffect GLEffect; |