| Index: src/gpu/effects/GrPorterDuffXferProcessor.cpp
|
| diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
|
| index 83c72f934255f9bd6ac674b77313bf52cb802e41..17bc912f87ce56c7791f9ece8107f8ed96b2f9c3 100644
|
| --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
|
| +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
|
| @@ -9,6 +9,7 @@
|
|
|
| #include "GrBlend.h"
|
| #include "GrCaps.h"
|
| +#include "GrPipelineBuilder.h"
|
| #include "GrProcessor.h"
|
| #include "GrProcOptInfo.h"
|
| #include "GrTypes.h"
|
| @@ -288,35 +289,32 @@ static const BlendFormula gBlendTable[2][2][SkXfermode::kLastCoeffMode + 1] = {
|
| /* screen */ COEFF_FORMULA( kOne_GrBlendCoeff, kISC_GrBlendCoeff),
|
| }}};
|
|
|
| -static BlendFormula get_blend_formula(SkXfermode::Mode xfermode,
|
| +static BlendFormula get_blend_formula(const GrPipelineBuilder& builder,
|
| const GrProcOptInfo& colorPOI,
|
| - const GrProcOptInfo& coveragePOI) {
|
| + const GrProcOptInfo& coveragePOI,
|
| + SkXfermode::Mode xfermode) {
|
| SkASSERT(xfermode >= 0 && xfermode <= SkXfermode::kLastCoeffMode);
|
| SkASSERT(!coveragePOI.isFourChannelOutput());
|
|
|
| - return gBlendTable[colorPOI.isOpaque()][!coveragePOI.isSolidWhite()][xfermode];
|
| + bool conflatesCoverage = !coveragePOI.isSolidWhite() || builder.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"; }
|
| - bool hasSecondaryOutput() const override { return fBlendFormula.hasSecondaryOutput(); }
|
|
|
| GrGLXferProcessor* createGLInstance() const override;
|
|
|
| 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,
|
| @@ -325,6 +323,8 @@ private:
|
|
|
| void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
|
|
|
| + bool onHasSecondaryOutput() const override { return fBlendFormula.hasSecondaryOutput(); }
|
| +
|
| void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override {
|
| blendInfo->fEquation = fBlendFormula.fBlendEquation;
|
| blendInfo->fSrcBlend = fBlendFormula.fSrcCoeff;
|
| @@ -352,6 +352,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;
|
| @@ -454,24 +455,21 @@ 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 GrPipelineBuilder& builder,
|
| + const DstTexture* dstTexture,
|
| + SkXfermode::Mode xfermode)
|
| + : INHERITED(builder, dstTexture, true)
|
| + , fXfermode(xfermode) {
|
| + this->initClassID<ShaderPDXferProcessor>();
|
| }
|
|
|
| const char* name() const override { return "Porter Duff Shader"; }
|
| - bool hasSecondaryOutput() const override { return false; }
|
|
|
| GrGLXferProcessor* createGLInstance() const override;
|
|
|
| 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;
|
| @@ -596,8 +594,6 @@ public:
|
|
|
| GrGLXferProcessor* createGLInstance() const override;
|
|
|
| - bool hasSecondaryOutput() const override { return false; }
|
| -
|
| private:
|
| PDLCDXferProcessor(GrColor blendConstant, uint8_t alpha);
|
|
|
| @@ -745,6 +741,7 @@ GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode xfermode) {
|
|
|
| GrXferProcessor*
|
| GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
| + const GrPipelineBuilder& builder,
|
| const GrProcOptInfo& colorPOI,
|
| const GrProcOptInfo& covPOI,
|
| const DstTexture* dstTexture) const {
|
| @@ -753,13 +750,13 @@ GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps,
|
| return PDLCDXferProcessor::Create(fXfermode, colorPOI);
|
| }
|
|
|
| - BlendFormula blendFormula = get_blend_formula(fXfermode, colorPOI, covPOI);
|
| + BlendFormula blendFormula = get_blend_formula(builder, colorPOI, covPOI, fXfermode);
|
| if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlendingSupport()) {
|
| - return ShaderPDXferProcessor::Create(fXfermode, dstTexture);
|
| + return SkNEW_ARGS(ShaderPDXferProcessor, (builder, dstTexture, fXfermode));
|
| }
|
|
|
| SkASSERT(!dstTexture || !dstTexture->texture());
|
| - return PorterDuffXferProcessor::Create(blendFormula);
|
| + return SkNEW_ARGS(PorterDuffXferProcessor, (blendFormula));
|
| }
|
|
|
| bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/,
|
| @@ -803,16 +800,18 @@ void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP
|
| }
|
|
|
| bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps,
|
| + const GrPipelineBuilder& builder,
|
| const GrProcOptInfo& colorPOI,
|
| const GrProcOptInfo& coveragePOI) const {
|
| + if (caps.shaderCaps()->dualSourceBlendingSupport()) {
|
| + return false;
|
| + }
|
| if (coveragePOI.isFourChannelOutput()) {
|
| - return false; // The LCD XP never does a dst read.
|
| + 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(builder, colorPOI, coveragePOI, fXfermode).hasSecondaryOutput();
|
| }
|
|
|
| GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
|
|
|