Add detection of when partial pixel coverage (for aa or otherwise) will cause incorrect blend
Review URL http://codereview.appspot.com/5112042/
git-svn-id: http://skia.googlecode.com/svn/trunk@2323 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrDrawTarget.cpp b/gpu/src/GrDrawTarget.cpp
index bfcc07d..59661d8 100644
--- a/gpu/src/GrDrawTarget.cpp
+++ b/gpu/src/GrDrawTarget.cpp
@@ -744,6 +744,25 @@
////////////////////////////////////////////////////////////////////////////////
+// Some blend modes allow folding a partial coverage value into the color's
+// alpha channel, while others will blend incorrectly.
+bool GrDrawTarget::CanTweakAlphaForCoverage(GrBlendCoeff dstCoeff) {
+ /**
+ * 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 substituing in the various possbilities
+ * for Cd we find that only 1, ISA, and ISC produce the correct depth
+ * coeffecient in terms of S' and D.
+ */
+ return kOne_BlendCoeff == dstCoeff ||
+ kISA_BlendCoeff == dstCoeff ||
+ kISC_BlendCoeff == dstCoeff;
+}
+
bool GrDrawTarget::CanDisableBlend(GrVertexLayout layout, const DrState& state) {
// If we compute a coverage value (using edge AA or a coverage stage) then
// we can't force blending off.
@@ -808,9 +827,15 @@
// 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.
+ // is 0xff and tweaking the color for partial coverage is OK
return (kAntialias_StateBit & state.fFlagBits) &&
- CanDisableBlend(layout, state);
+ CanDisableBlend(layout, state) &&
+ CanTweakAlphaForCoverage(state.fDstBlend);
+}
+
+bool GrDrawTarget::canApplyCoverage() const {
+ return this->getCaps().fDualSourceBlendingSupport ||
+ CanTweakAlphaForCoverage(fCurrDrawState.fDstBlend);
}
bool GrDrawTarget::canDisableBlend() const {