Index: src/gpu/effects/GrPorterDuffXferProcessor.cpp |
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp |
index ecaa87f941cb80f840d74f7f45ca589fcc4cfc21..df44a1b555380ce3468a17bfe85bf36d1b78f293 100644 |
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp |
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp |
@@ -288,21 +288,23 @@ static const BlendFormula gBlendTable[2][2][SkXfermode::kLastCoeffMode + 1] = { |
/* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff), |
}}}; |
-static BlendFormula get_blend_formula(SkXfermode::Mode xfermode, |
- const GrProcOptInfo& colorPOI, |
- const GrProcOptInfo& coveragePOI) { |
+static BlendFormula get_blend_formula(const GrProcOptInfo& colorPOI, |
+ const GrProcOptInfo& coveragePOI, |
+ bool hasMixedSamples, |
+ SkXfermode::Mode xfermode) { |
SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode); |
SkASSERT(!coveragePOI.isFourChannelOutput()); |
- return gBlendTable[colorPOI.isOpaque()][!coveragePOI.isSolidWhite()][xfermode]; |
+ bool conflatesCoverage = !coveragePOI.isSolidWhite() || hasMixedSamples; |
+ return gBlendTable[colorPOI.isOpaque()][conflatesCoverage][xfermode]; |
} |
/////////////////////////////////////////////////////////////////////////////// |
class PorterDuffXferProcessor : public GrXferProcessor { |
public: |
- static GrXferProcessor* Create(BlendFormula blendFormula) { |
- return SkNEW_ARGS(PorterDuffXferProcessor, (blendFormula)); |
+ PorterDuffXferProcessor(BlendFormula blendFormula) : fBlendFormula(blendFormula) { |
+ this->initClassID<PorterDuffXferProcessor>(); |
} |
const char* name() const override { return "Porter Duff"; } |
@@ -312,10 +314,6 @@ public: |
BlendFormula getBlendFormula() const { return fBlendFormula; } |
private: |
- PorterDuffXferProcessor(BlendFormula blendFormula) : fBlendFormula(blendFormula) { |
- this->initClassID<PorterDuffXferProcessor>(); |
- } |
- |
GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, |
const GrProcOptInfo& coveragePOI, |
bool doesStencilWrite, |
@@ -353,6 +351,7 @@ static void append_color_output(const PorterDuffXferProcessor& xp, GrGLXPFragmen |
fsBuilder->codeAppendf("%s = vec4(0.0);", output); |
break; |
case BlendFormula::kCoverage_OutputType: |
+ // We can have a coverage formula while not reading coverage if there are mixed samples. |
fsBuilder->codeAppendf("%s = %s;", |
output, xp.readsCoverage() ? inCoverage : "vec4(1.0)"); |
break; |
@@ -455,8 +454,12 @@ PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, |
class ShaderPDXferProcessor : public GrXferProcessor { |
public: |
- static GrXferProcessor* Create(SkXfermode::Mode xfermode, const DstTexture* dstTexture) { |
- return SkNEW_ARGS(ShaderPDXferProcessor, (xfermode, dstTexture)); |
+ ShaderPDXferProcessor(const DstTexture* dstTexture, |
+ bool hasMixedSamples, |
+ SkXfermode::Mode xfermode) |
+ : INHERITED(dstTexture, true, hasMixedSamples) |
+ , fXfermode(xfermode) { |
+ this->initClassID<ShaderPDXferProcessor>(); |
} |
const char* name() const override { return "Porter Duff Shader"; } |
@@ -466,12 +469,6 @@ public: |
SkXfermode::Mode getXfermode() const { return fXfermode; } |
private: |
- ShaderPDXferProcessor(SkXfermode::Mode xfermode, const DstTexture* dstTexture) |
- : INHERITED(dstTexture, true) |
- , fXfermode(xfermode) { |
- this->initClassID<ShaderPDXferProcessor>(); |
- } |
- |
GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo&, const GrProcOptInfo&, |
bool, GrColor*, const GrCaps&) override { |
return kNone_Opt; |
@@ -738,19 +735,20 @@ GrXferProcessor* |
GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, |
const GrProcOptInfo& colorPOI, |
const GrProcOptInfo& covPOI, |
+ bool hasMixedSamples, |
const DstTexture* dstTexture) const { |
if (covPOI.isFourChannelOutput()) { |
SkASSERT(!dstTexture || !dstTexture->texture()); |
return PDLCDXferProcessor::Create(fXfermode, colorPOI); |
} |
- BlendFormula blendFormula = get_blend_formula(fXfermode, colorPOI, covPOI); |
+ BlendFormula blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode); |
if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) { |
- return ShaderPDXferProcessor::Create(fXfermode, dstTexture); |
+ return SkNEW_ARGS(ShaderPDXferProcessor, (dstTexture, hasMixedSamples, fXfermode)); |
} |
SkASSERT(!dstTexture || !dstTexture->texture()); |
- return PorterDuffXferProcessor::Create(blendFormula); |
+ return SkNEW_ARGS(PorterDuffXferProcessor, (blendFormula)); |
} |
bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, |
@@ -795,15 +793,17 @@ void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP |
bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, |
const GrProcOptInfo& colorPOI, |
- const GrProcOptInfo& coveragePOI) const { |
- if (coveragePOI.isFourChannelOutput()) { |
- return false; // The LCD XP never does a dst read. |
+ const GrProcOptInfo& covPOI, |
+ bool hasMixedSamples) const { |
+ if (caps.shaderCaps()->dualSourceBlendingSupport()) { |
+ return false; |
+ } |
+ if (covPOI.isFourChannelOutput()) { |
+ return false; // The LCD XP will abort rather than doing a dst read. |
} |
- |
// We fallback on the shader XP when the blend formula would use dual source blending but we |
// don't have support for it. |
- return !caps.shaderCaps()->dualSourceBlendingSupport() && |
- get_blend_formula(fXfermode, colorPOI, coveragePOI).hasSecondaryOutput(); |
+ return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSecondaryOutput(); |
} |
GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); |