Index: src/gpu/GrDrawState.cpp |
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp |
index 8c2d75f0b502715d2d8d0e25411b08530d1b4671..51ef6cf5d3c8302c815aacb2ba356278c35c25f5 100644 |
--- a/src/gpu/GrDrawState.cpp |
+++ b/src/gpu/GrDrawState.cpp |
@@ -14,8 +14,6 @@ |
#include "GrXferProcessor.h" |
#include "effects/GrPorterDuffXferProcessor.h" |
-/////////////////////////////////////////////////////////////////////////////// |
- |
bool GrDrawState::isEqual(const GrDrawState& that) const { |
bool usingVertexColors = this->hasColorVertexAttribute(); |
if (!usingVertexColors && this->fColor != that.fColor) { |
@@ -26,9 +24,6 @@ bool GrDrawState::isEqual(const GrDrawState& that) const { |
this->fColorStages.count() != that.fColorStages.count() || |
this->fCoverageStages.count() != that.fCoverageStages.count() || |
!this->fViewMatrix.cheapEqualTo(that.fViewMatrix) || |
- this->fSrcBlend != that.fSrcBlend || |
- this->fDstBlend != that.fDstBlend || |
- this->fBlendConstant != that.fBlendConstant || |
this->fFlagBits != that.fFlagBits || |
this->fStencilSettings != that.fStencilSettings || |
this->fDrawFace != that.fDrawFace) { |
@@ -90,9 +85,6 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) { |
fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get())); |
fColor = that.fColor; |
fViewMatrix = that.fViewMatrix; |
- fSrcBlend = that.fSrcBlend; |
- fDstBlend = that.fDstBlend; |
- fBlendConstant = that.fBlendConstant; |
fFlagBits = that.fFlagBits; |
fStencilSettings = that.fStencilSettings; |
fCoverage = that.fCoverage; |
@@ -130,9 +122,6 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { |
} else { |
fViewMatrix = *initialViewMatrix; |
} |
- fSrcBlend = kOne_GrBlendCoeff; |
- fDstBlend = kZero_GrBlendCoeff; |
- fBlendConstant = 0x0; |
fFlagBits = 0x0; |
fStencilSettings.setDisabled(); |
fCoverage = 0xff; |
@@ -179,13 +168,11 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende |
fXPFactory.reset(SkRef(paint.getXPFactory())); |
- this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
this->setRenderTarget(rt); |
fViewMatrix = vm; |
// These have no equivalent in GrPaint, set them to defaults |
- fBlendConstant = 0x0; |
fDrawFace = kBoth_DrawFace; |
fStencilSettings.setDisabled(); |
fFlagBits = 0; |
@@ -209,15 +196,11 @@ bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
if (caps.dualSourceBlendingSupport()) { |
return true; |
} |
- // we can correctly apply coverage if a) we have dual source blending |
- // or b) one of our blend optimizations applies |
- // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color |
- GrBlendCoeff srcCoeff; |
- GrBlendCoeff dstCoeff; |
- BlendOpt opt = this->getBlendOpt(true, &srcCoeff, &dstCoeff); |
- return GrDrawState::kNone_BlendOpt != opt || |
- (this->willEffectReadDstColor() && |
- kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); |
+ |
+ this->calcColorInvariantOutput(); |
+ this->calcCoverageInvariantOutput(); |
+ return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo, |
+ this->isCoverageDrawing(), this->isColorWriteDisabled()); |
} |
bool GrDrawState::hasSolidCoverage() const { |
@@ -237,13 +220,22 @@ bool GrDrawState::hasSolidCoverage() const { |
//////////////////////////////////////////////////////////////////////////////s |
bool GrDrawState::willEffectReadDstColor() const { |
+ this->calcColorInvariantOutput(); |
+ this->calcCoverageInvariantOutput(); |
+ // TODO: Remove need to create the XP here. |
+ // Also once all custom blends are turned into XPs we can remove the need |
+ // to check other stages since only xp's will be able to read dst |
+ SkAutoTUnref<GrXferProcessor> xferProcessor(fXPFactory->createXferProcessor(fColorProcInfo, |
+ fCoverageProcInfo)); |
+ if (xferProcessor && xferProcessor->willReadDstColor()) { |
+ return true; |
+ } |
+ |
if (!this->isColorWriteDisabled()) { |
- this->calcColorInvariantOutput(); |
if (fColorProcInfo.readsDst()) { |
return true; |
} |
} |
- this->calcCoverageInvariantOutput(); |
return fCoverageProcInfo.readsDst(); |
} |
@@ -288,21 +280,7 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
// 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 == fDstBlend || |
- kISA_GrBlendCoeff == fDstBlend || |
- kISC_GrBlendCoeff == fDstBlend || |
- this->isCoverageDrawing(); |
+ return fXPFactory->canTweakAlphaForCoverage(this->isCoverageDrawing()); |
} |
//////////////////////////////////////////////////////////////////////////////// |
@@ -400,97 +378,6 @@ GrDrawState::~GrDrawState() { |
//////////////////////////////////////////////////////////////////////////////// |
-GrDrawState::BlendOpt GrDrawState::getBlendOpt(bool forceCoverage, |
- GrBlendCoeff* srcCoeff, |
- GrBlendCoeff* dstCoeff) const { |
- GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; |
- if (NULL == srcCoeff) { |
- srcCoeff = &bogusSrcCoeff; |
- } |
- if (NULL == dstCoeff) { |
- dstCoeff = &bogusDstCoeff; |
- } |
- |
- *srcCoeff = this->getSrcBlendCoeff(); |
- *dstCoeff = this->getDstBlendCoeff(); |
- |
- if (this->isColorWriteDisabled()) { |
- *srcCoeff = kZero_GrBlendCoeff; |
- *dstCoeff = kOne_GrBlendCoeff; |
- } |
- |
- bool srcAIsOne = this->srcAlphaWillBeOne(); |
- bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || |
- (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
- bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || |
- (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
- |
- // 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). |
- if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) { |
- if (this->getStencil().doesWrite()) { |
- return kEmitCoverage_BlendOpt; |
- } else { |
- *dstCoeff = kOne_GrBlendCoeff; |
- return kSkipDraw_BlendOpt; |
- } |
- } |
- |
- bool hasCoverage = forceCoverage || !this->hasSolidCoverage(); |
- |
- // 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 |
- *dstCoeff = kZero_GrBlendCoeff; |
- return kNone_BlendOpt; |
- } 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 kEmitTransBlack_BlendOpt; |
- } |
- } |
- } else if (this->isCoverageDrawing()) { |
- // we have coverage but we aren't distinguishing it from alpha by request. |
- return kCoverageAsAlpha_BlendOpt; |
- } 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_BlendOpt; |
- } |
- 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_BlendOpt; |
- } 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_BlendOpt; |
- } |
- } 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_BlendOpt; |
- } |
- } |
- |
- return kNone_BlendOpt; |
-} |
- |
bool GrDrawState::srcAlphaWillBeOne() const { |
this->calcColorInvariantOutput(); |
if (this->isCoverageDrawing()) { |
@@ -501,25 +388,10 @@ bool GrDrawState::srcAlphaWillBeOne() const { |
} |
bool GrDrawState::willBlendWithDst() const { |
- if (!this->hasSolidCoverage()) { |
- return true; |
- } |
- |
- if (this->willEffectReadDstColor()) { |
- return true; |
- } |
- |
- if (GrBlendCoeffRefsDst(this->getSrcBlendCoeff())) { |
- return true; |
- } |
- |
- GrBlendCoeff dstCoeff = this->getDstBlendCoeff(); |
- if (!(kZero_GrBlendCoeff == dstCoeff || |
- (kISA_GrBlendCoeff == dstCoeff && this->srcAlphaWillBeOne()))) { |
- return true; |
- } |
- |
- return false; |
+ this->calcColorInvariantOutput(); |
+ this->calcCoverageInvariantOutput(); |
+ return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo, |
+ this->isCoverageDrawing(), this->isColorWriteDisabled()); |
} |
void GrDrawState::calcColorInvariantOutput() const { |
@@ -561,4 +433,3 @@ void GrDrawState::calcCoverageInvariantOutput() const { |
fCoverageProcInfoValid = true; |
} |
} |
- |