diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-02-12 16:47:41 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-02-12 16:47:41 +0000 |
commit | 2b446734cfa8201e5478648988de86b646cb9544 (patch) | |
tree | 10c54603344d4c80e99cfeaa488cd8e1ce12cb55 /src | |
parent | f186757aa82911196c5f04b5ed55dc4bde894b76 (diff) |
Move blend optimization functions to GrDrawState.
Review URL: https://codereview.appspot.com/7300089
git-svn-id: http://skia.googlecode.com/svn/trunk@7703 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrContext.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrDrawState.cpp | 128 | ||||
-rw-r--r-- | src/gpu/GrDrawState.h | 56 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 158 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 72 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 25 |
7 files changed, 211 insertions, 232 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index ef3fd6d2f3..70db25601f 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -647,7 +647,7 @@ static bool apply_aa_to_rect(GrDrawTarget* target, // In a shader implementation we can give a separate coverage input // TODO: remove this ugliness when we drop the fixed-pipe impl *useVertexCoverage = false; - if (!target->canTweakAlphaForCoverage()) { + if (!target->getDrawState().canTweakAlphaForCoverage()) { if (disable_coverage_aa_for_blend(target)) { #if GR_DEBUG //GrPrintf("Turning off AA to correctly apply blend.\n"); diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index 5b434c3d7f..f2c69778de 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -538,6 +538,134 @@ bool GrDrawState::hasSolidCoverage(GrVertexLayout layout) const { //////////////////////////////////////////////////////////////////////////////// +// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while +// others will blend incorrectly. +bool GrDrawState::canTweakAlphaForCoverage() const { + /* + The fractional coverage is f. + The src and dst coeffs are Cs and Cd. + The dst and src colors are S and D. + We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha + we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second + term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we + find that only 1, ISA, and ISC produce the correct destination when applied to S' and D. + Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as + color by definition. + */ + return kOne_GrBlendCoeff == fCommon.fDstBlend || + kISA_GrBlendCoeff == fCommon.fDstBlend || + kISC_GrBlendCoeff == fCommon.fDstBlend || + this->isCoverageDrawing(); +} + +GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, + GrBlendCoeff* srcCoeff, + GrBlendCoeff* dstCoeff) const { + GrVertexLayout layout = this->getVertexLayout(); + + GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; + if (NULL == srcCoeff) { + srcCoeff = &bogusSrcCoeff; + } + *srcCoeff = this->getSrcBlendCoeff(); + + if (NULL == dstCoeff) { + dstCoeff = &bogusDstCoeff; + } + *dstCoeff = this->getDstBlendCoeff(); + + if (this->isColorWriteDisabled()) { + *srcCoeff = kZero_GrBlendCoeff; + *dstCoeff = kOne_GrBlendCoeff; + } + + bool srcAIsOne = this->srcAlphaWillBeOne(layout); + bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || + (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); + bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || + (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); + + bool covIsZero = !this->isCoverageDrawing() && + !(layout & GrDrawState::kCoverage_VertexLayoutBit) && + 0 == this->getCoverage(); + // When coeffs are (0,1) there is no reason to draw at all, unless + // stenciling is enabled. Having color writes disabled is effectively + // (0,1). The same applies when coverage is known to be 0. + if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) { + if (this->getStencil().doesWrite()) { + return kDisableBlend_BlendOptFlag | + kEmitTransBlack_BlendOptFlag; + } else { + return kSkipDraw_BlendOptFlag; + } + } + + // check for coverage due to constant coverage, per-vertex coverage, + // edge aa or coverage stage + bool hasCoverage = forceCoverage || + 0xffffffff != this->getCoverage() || + (layout & GrDrawState::kCoverage_VertexLayoutBit) || + (layout & GrDrawState::kEdge_VertexLayoutBit); + for (int s = this->getFirstCoverageStage(); + !hasCoverage && s < GrDrawState::kNumStages; + ++s) { + if (this->isStageEnabled(s)) { + hasCoverage = true; + } + } + + // if we don't have coverage we can check whether the dst + // has to read at all. If not, we'll disable blending. + if (!hasCoverage) { + if (dstCoeffIsZero) { + if (kOne_GrBlendCoeff == *srcCoeff) { + // if there is no coverage and coeffs are (1,0) then we + // won't need to read the dst at all, it gets replaced by src + return kDisableBlend_BlendOptFlag; + } else if (kZero_GrBlendCoeff == *srcCoeff) { + // if the op is "clear" then we don't need to emit a color + // or blend, just write transparent black into the dst. + *srcCoeff = kOne_GrBlendCoeff; + *dstCoeff = kZero_GrBlendCoeff; + return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag; + } + } + } else if (this->isCoverageDrawing()) { + // we have coverage but we aren't distinguishing it from alpha by request. + return kCoverageAsAlpha_BlendOptFlag; + } else { + // check whether coverage can be safely rolled into alpha + // of if we can skip color computation and just emit coverage + if (this->canTweakAlphaForCoverage()) { + return kCoverageAsAlpha_BlendOptFlag; + } + if (dstCoeffIsZero) { + if (kZero_GrBlendCoeff == *srcCoeff) { + // the source color is not included in the blend + // the dst coeff is effectively zero so blend works out to: + // (c)(0)D + (1-c)D = (1-c)D. + *dstCoeff = kISA_GrBlendCoeff; + return kEmitCoverage_BlendOptFlag; + } else if (srcAIsOne) { + // the dst coeff is effectively zero so blend works out to: + // cS + (c)(0)D + (1-c)D = cS + (1-c)D. + // If Sa is 1 then we can replace Sa with c + // and set dst coeff to 1-Sa. + *dstCoeff = kISA_GrBlendCoeff; + return kCoverageAsAlpha_BlendOptFlag; + } + } else if (dstCoeffIsOne) { + // the dst coeff is effectively one so blend works out to: + // cS + (c)(1)D + (1-c)D = cS + D. + *dstCoeff = kOne_GrBlendCoeff; + return kCoverageAsAlpha_BlendOptFlag; + } + } + return kNone_BlendOpt; +} + +//////////////////////////////////////////////////////////////////////////////// + void GrDrawState::AutoViewMatrixRestore::restore() { if (NULL != fDrawState) { fDrawState->setViewMatrix(fViewMatrix); diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 2245e05bd1..1124ebb368 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -690,6 +690,60 @@ public: */ GrColor getBlendConstant() const { return fCommon.fBlendConstant; } + /** + * Determines whether multiplying the computed per-pixel color by the pixel's fractional + * coverage before the blend will give the correct final destination color. In general it + * will not as coverage is applied after blending. + */ + bool canTweakAlphaForCoverage() const; + + /** + * Optimizations for blending / coverage to that can be applied based on the current state. + */ + enum BlendOptFlags { + /** + * No optimization + */ + kNone_BlendOpt = 0, + /** + * Don't draw at all + */ + kSkipDraw_BlendOptFlag = 0x1, + /** + * Emit the src color, disable HW blending (replace dst with src) + */ + kDisableBlend_BlendOptFlag = 0x2, + /** + * The coverage value does not have to be computed separately from alpha, the the output + * color can be the modulation of the two. + */ + kCoverageAsAlpha_BlendOptFlag = 0x4, + /** + * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are + * "don't cares". + */ + kEmitCoverage_BlendOptFlag = 0x8, + /** + * Emit transparent black instead of the src color, no need to compute coverage. + */ + kEmitTransBlack_BlendOptFlag = 0x10, + }; + GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags); + + /** + * Determines what optimizations can be applied based on the blend. The coefficients may have + * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional + * params that receive the tweaked coefficients. Normally the function looks at the current + * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively + * determine the blend optimizations that would be used if there was partial pixel coverage. + * + * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for + * playback) must call this function and respect the flags that replace the output color. + */ + BlendOptFlags getBlendOpts(bool forceCoverage = false, + GrBlendCoeff* srcCoeff = NULL, + GrBlendCoeff* dstCoeff = NULL) const; + /// @} /////////////////////////////////////////////////////////////////////////// @@ -1278,4 +1332,6 @@ private: typedef GrRefCnt INHERITED; }; +GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags); + #endif diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 3282f13263..c00a5ce509 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -454,168 +454,24 @@ void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, Sk //////////////////////////////////////////////////////////////////////////////// -// Some blend modes allow folding a partial coverage value into the color's -// alpha channel, while others will blend incorrectly. -bool GrDrawTarget::canTweakAlphaForCoverage() const { - /** - * The fractional coverage is f - * The src and dst coeffs are Cs and Cd - * The dst and src colors are S and D - * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D - * By tweaking the source color's alpha we're replacing S with S'=fS. It's - * obvious that that first term will always be ok. The second term can be - * rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities - * for Cd we find that only 1, ISA, and ISC produce the correct depth - * coefficient in terms of S' and D. - */ - GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff(); - return kOne_GrBlendCoeff == dstCoeff || - kISA_GrBlendCoeff == dstCoeff || - kISC_GrBlendCoeff == dstCoeff || - this->getDrawState().isCoverageDrawing(); -} - -namespace { -GrVertexLayout default_blend_opts_vertex_layout() { - GrVertexLayout layout = 0; - return layout; -} -} - -GrDrawTarget::BlendOptFlags -GrDrawTarget::getBlendOpts(bool forceCoverage, - GrBlendCoeff* srcCoeff, - GrBlendCoeff* dstCoeff) const { - - const GrDrawState& drawState = this->getDrawState(); - - GrVertexLayout layout; - if (kNone_GeometrySrcType == this->getGeomSrc().fVertexSrc) { - layout = default_blend_opts_vertex_layout(); - } else { - layout = drawState.getVertexLayout(); - } - - GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; - if (NULL == srcCoeff) { - srcCoeff = &bogusSrcCoeff; - } - *srcCoeff = drawState.getSrcBlendCoeff(); - - if (NULL == dstCoeff) { - dstCoeff = &bogusDstCoeff; - } - *dstCoeff = drawState.getDstBlendCoeff(); - - if (drawState.isColorWriteDisabled()) { - *srcCoeff = kZero_GrBlendCoeff; - *dstCoeff = kOne_GrBlendCoeff; - } - - bool srcAIsOne = drawState.srcAlphaWillBeOne(layout); - bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || - (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); - bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || - (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); - - bool covIsZero = !drawState.isCoverageDrawing() && - !(layout & GrDrawState::kCoverage_VertexLayoutBit) && - 0 == drawState.getCoverage(); - // When coeffs are (0,1) there is no reason to draw at all, unless - // stenciling is enabled. Having color writes disabled is effectively - // (0,1). The same applies when coverage is known to be 0. - if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) { - if (drawState.getStencil().doesWrite()) { - return kDisableBlend_BlendOptFlag | - kEmitTransBlack_BlendOptFlag; - } else { - return kSkipDraw_BlendOptFlag; - } - } - - // check for coverage due to constant coverage, per-vertex coverage, - // edge aa or coverage stage - bool hasCoverage = forceCoverage || - 0xffffffff != drawState.getCoverage() || - (layout & GrDrawState::kCoverage_VertexLayoutBit) || - (layout & GrDrawState::kEdge_VertexLayoutBit); - for (int s = drawState.getFirstCoverageStage(); - !hasCoverage && s < GrDrawState::kNumStages; - ++s) { - if (drawState.isStageEnabled(s)) { - hasCoverage = true; - } - } - - // if we don't have coverage we can check whether the dst - // has to read at all. If not, we'll disable blending. - if (!hasCoverage) { - if (dstCoeffIsZero) { - if (kOne_GrBlendCoeff == *srcCoeff) { - // if there is no coverage and coeffs are (1,0) then we - // won't need to read the dst at all, it gets replaced by src - return kDisableBlend_BlendOptFlag; - } else if (kZero_GrBlendCoeff == *srcCoeff) { - // if the op is "clear" then we don't need to emit a color - // or blend, just write transparent black into the dst. - *srcCoeff = kOne_GrBlendCoeff; - *dstCoeff = kZero_GrBlendCoeff; - return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag; - } - } - } else if (drawState.isCoverageDrawing()) { - // we have coverage but we aren't distinguishing it from alpha by request. - return kCoverageAsAlpha_BlendOptFlag; - } else { - // check whether coverage can be safely rolled into alpha - // of if we can skip color computation and just emit coverage - if (this->canTweakAlphaForCoverage()) { - return kCoverageAsAlpha_BlendOptFlag; - } - if (dstCoeffIsZero) { - if (kZero_GrBlendCoeff == *srcCoeff) { - // the source color is not included in the blend - // the dst coeff is effectively zero so blend works out to: - // (c)(0)D + (1-c)D = (1-c)D. - *dstCoeff = kISA_GrBlendCoeff; - return kEmitCoverage_BlendOptFlag; - } else if (srcAIsOne) { - // the dst coeff is effectively zero so blend works out to: - // cS + (c)(0)D + (1-c)D = cS + (1-c)D. - // If Sa is 1 then we can replace Sa with c - // and set dst coeff to 1-Sa. - *dstCoeff = kISA_GrBlendCoeff; - return kCoverageAsAlpha_BlendOptFlag; - } - } else if (dstCoeffIsOne) { - // the dst coeff is effectively one so blend works out to: - // cS + (c)(1)D + (1-c)D = cS + D. - *dstCoeff = kOne_GrBlendCoeff; - return kCoverageAsAlpha_BlendOptFlag; - } - } - return kNone_BlendOpt; -} - bool GrDrawTarget::willUseHWAALines() const { - // there is a conflict between using smooth lines and our use of - // premultiplied alpha. Smooth lines tweak the incoming alpha value - // but not in a premul-alpha way. So we only use them when our alpha - // is 0xff and tweaking the color for partial coverage is OK + // There is a conflict between using smooth lines and our use of premultiplied alpha. Smooth + // lines tweak the incoming alpha value but not in a premul-alpha way. So we only use them when + // our alpha is 0xff and tweaking the color for partial coverage is OK if (!fCaps.hwAALineSupport() || !this->getDrawState().isHWAntialiasState()) { return false; } - BlendOptFlags opts = this->getBlendOpts(); - return (kDisableBlend_BlendOptFlag & opts) && - (kCoverageAsAlpha_BlendOptFlag & opts); + GrDrawState::BlendOptFlags opts = this->getDrawState().getBlendOpts(); + return (GrDrawState::kDisableBlend_BlendOptFlag & opts) && + (GrDrawState::kCoverageAsAlpha_BlendOptFlag & opts); } bool GrDrawTarget::canApplyCoverage() const { // we can correctly apply coverage if a) we have dual source blending // or b) one of our blend optimizations applies. return this->getCaps().dualSourceBlendingSupport() || - kNone_BlendOpt != this->getBlendOpts(true); + GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 5a558ed6db..1f4189145b 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -145,27 +145,15 @@ public: * 1. The caller intends to somehow specify coverage. This can be * specified either by enabling a coverage stage on the GrDrawState or * via the vertex layout. - * 2. Other than enabling coverage stages, the current configuration of - * the target's GrDrawState is as it will be at draw time. - * 3. If a vertex source has not yet been specified then all stages with - * non-NULL textures will be referenced by the vertex layout. + * 2. Other than enabling coverage stages or enabling coverage in the + * layout, the current configuration of the target's GrDrawState is as + * it will be at draw time. */ bool canApplyCoverage() const; /** - * Determines whether incorporating partial pixel coverage into the constant - * color specified by setColor or per-vertex colors will give the right - * blending result. If a vertex source has not yet been specified then - * the function assumes that all stages with non-NULL textures will be - * referenced by the vertex layout. - */ - bool canTweakAlphaForCoverage() const; - - /** - * Given the current draw state and hw support, will HW AA lines be used - * (if line primitive type is drawn)? If a vertex source has not yet been - * specified then the function assumes that all stages with non-NULL - * textures will be referenced by the vertex layout. + * Given the current draw state and hw support, will HW AA lines be used (if + * a line primitive type is drawn)? */ bool willUseHWAALines() const; @@ -616,54 +604,6 @@ public: protected: - /** - * Optimizations for blending / coverage to be applied based on the current - * state. - * Subclasses that actually draw (as opposed to those that just buffer for - * playback) must implement the flags that replace the output color. - */ - enum BlendOptFlags { - /** - * No optimization - */ - kNone_BlendOpt = 0, - /** - * Don't draw at all - */ - kSkipDraw_BlendOptFlag = 0x2, - /** - * Emit the src color, disable HW blending (replace dst with src) - */ - kDisableBlend_BlendOptFlag = 0x4, - /** - * The coverage value does not have to be computed separately from - * alpha, the the output color can be the modulation of the two. - */ - kCoverageAsAlpha_BlendOptFlag = 0x1, - /** - * Instead of emitting a src color, emit coverage in the alpha channel - * and r,g,b are "don't cares". - */ - kEmitCoverage_BlendOptFlag = 0x10, - /** - * Emit transparent black instead of the src color, no need to compute - * coverage. - */ - kEmitTransBlack_BlendOptFlag = 0x8, - }; - GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags); - - /** - * Determines what optimizations can be applied based on the blend. The coefficients may have - * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional - * params that receive the tweaked coefficients. Normally the function looks at the current - * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively - * determine the blend optimizations that would be used if there was partial pixel coverage. - */ - BlendOptFlags getBlendOpts(bool forceCoverage = false, - GrBlendCoeff* srcCoeff = NULL, - GrBlendCoeff* dstCoeff = NULL) const; - enum GeometrySrcType { kNone_GeometrySrcType, //<! src has not been specified kReserved_GeometrySrcType, //<! src was set using reserve*Space @@ -837,6 +777,4 @@ private: typedef GrRefCnt INHERITED; }; -GR_MAKE_BITFIELD_OPS(GrDrawTarget::BlendOptFlags); - #endif diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index d9ad1f49d2..7bb458d7ea 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -202,7 +202,7 @@ private: void flushScissor(); void buildProgram(bool isPoints, - BlendOptFlags blendOpts, + GrDrawState::BlendOptFlags blendOpts, GrBlendCoeff dstCoeff, ProgramDesc* desc); diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index a566f3f7fb..570ca19fd8 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -281,8 +281,8 @@ bool GrGpuGL::flushGraphicsState(DrawType type) { GrBlendCoeff srcCoeff; GrBlendCoeff dstCoeff; - BlendOptFlags blendOpts = this->getBlendOpts(false, &srcCoeff, &dstCoeff); - if (kSkipDraw_BlendOptFlag & blendOpts) { + GrDrawState::BlendOptFlags blendOpts = drawState.getBlendOpts(false, &srcCoeff, &dstCoeff); + if (GrDrawState::kSkipDraw_BlendOptFlag & blendOpts) { return false; } @@ -309,10 +309,10 @@ bool GrGpuGL::flushGraphicsState(DrawType type) { GrColor color; GrColor coverage; - if (blendOpts & kEmitTransBlack_BlendOptFlag) { + if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) { color = 0; coverage = 0; - } else if (blendOpts & kEmitCoverage_BlendOptFlag) { + } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) { color = 0xffffffff; coverage = drawState.getCoverage(); } else { @@ -444,18 +444,18 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, int* startIndexOffset) { } void GrGpuGL::buildProgram(bool isPoints, - BlendOptFlags blendOpts, + GrDrawState::BlendOptFlags blendOpts, GrBlendCoeff dstCoeff, ProgramDesc* desc) { const GrDrawState& drawState = this->getDrawState(); // This should already have been caught - GrAssert(!(kSkipDraw_BlendOptFlag & blendOpts)); + GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts)); - bool skipCoverage = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag); + bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag); - bool skipColor = SkToBool(blendOpts & (kEmitTransBlack_BlendOptFlag | - kEmitCoverage_BlendOptFlag)); + bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag | + GrDrawState::kEmitCoverage_BlendOptFlag)); // The descriptor is used as a cache key. Thus when a field of the // descriptor will not affect program generation (because of the vertex @@ -487,8 +487,8 @@ void GrGpuGL::buildProgram(bool isPoints, desc->fVertexLayout &= ~(GrDrawState::kEdge_VertexLayoutBit | GrDrawState::kCoverage_VertexLayoutBit); } - bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag); - bool colorIsSolidWhite = (blendOpts & kEmitCoverage_BlendOptFlag) || + bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag); + bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) || (!requiresAttributeColors && 0xffffffff == drawState.getColor()); if (colorIsTransBlack) { desc->fColorInput = ProgramDesc::kTransBlack_ColorInput; @@ -567,7 +567,8 @@ void GrGpuGL::buildProgram(bool isPoints, } if (this->getCaps().dualSourceBlendingSupport() && - !(blendOpts & (kEmitCoverage_BlendOptFlag | kCoverageAsAlpha_BlendOptFlag))) { + !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag | + GrDrawState::kCoverageAsAlpha_BlendOptFlag))) { if (kZero_GrBlendCoeff == dstCoeff) { // write the coverage value to second color desc->fDualSrcOutput = ProgramDesc::kCoverage_DualSrcOutput; |