}
/**
+ * If we are performing a dst read, returns whether the base class will use mixed samples to
+ * antialias the shader's final output. If not doing a dst read, the subclass is responsible
+ * for antialiasing and this returns false.
+ */
+ bool dstReadUsesMixedSamples() const { return fDstReadUsesMixedSamples; }
+
+ /**
* Returns whether or not the XP will look at coverage when doing its blending.
*/
bool readsCoverage() const { return fReadsCoverage; }
if (this->fDstTextureOffset != that.fDstTextureOffset) {
return false;
}
+ if (this->fDstReadUsesMixedSamples != that.fDstReadUsesMixedSamples) {
+ return false;
+ }
return this->onIsEqual(that);
}
protected:
GrXferProcessor();
- GrXferProcessor(const DstTexture*, bool willReadDstColor);
+ GrXferProcessor(const DstTexture*, bool willReadDstColor, bool hasMixedSamples);
private:
virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
/**
* If we are not performing a dst read, returns whether the subclass will set a secondary
- * output. When using dst reads, the base class disables the secondary output and this method
+ * output. When using dst reads, the base class controls the secondary output and this method
* will not be called.
*/
virtual bool onHasSecondaryOutput() const { return false; }
/**
* If we are not performing a dst read, retrieves the fixed-function blend state required by the
- * subclass. When using dst reads, the base class disables fixed-function blending and this
- * method will not be called. The BlendInfo struct comes initialized to "no blending".
+ * subclass. When using dst reads, the base class controls the fixed-function blend state and
+ * this method will not be called. The BlendInfo struct comes initialized to "no blending".
*/
virtual void onGetBlendInfo(BlendInfo*) const {}
virtual bool onIsEqual(const GrXferProcessor&) const = 0;
bool fWillReadDstColor;
+ bool fDstReadUsesMixedSamples;
bool fReadsCoverage;
SkIPoint fDstTextureOffset;
GrTextureAccess fDstTexture;
typedef GrXferProcessor::DstTexture DstTexture;
GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture*,
const GrCaps& caps) const;
InvariantBlendedColor*) const = 0;
bool willNeedDstTexture(const GrCaps& caps, const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI) const;
+ const GrProcOptInfo& coveragePOI, bool hasMixedSamples) const;
bool isEqual(const GrXPFactory& that) const {
if (this->classID() != that.classID()) {
virtual GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture*) const = 0;
/**
* Returns true if the XP generated by this factory will explicitly read dst in the fragment
*/
virtual bool willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI) const = 0;
+ const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples) const = 0;
virtual bool onIsEqual(const GrXPFactory&) const = 0;
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture*) const override;
bool willReadDstColor(const GrCaps& /*caps*/,
const GrProcOptInfo& /*colorPOI*/,
- const GrProcOptInfo& /*coveragePOI*/) const override {
+ const GrProcOptInfo& /*coveragePOI*/,
+ bool /*hasMixedSamples*/) const override {
return false;
}
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture*) const override;
bool willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI) const override;
+ const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples) const override;
bool onIsEqual(const GrXPFactory& xpfBase) const override {
const GrPorterDuffXPFactory& xpf = xpfBase.cast<GrPorterDuffXPFactory>();
class ArithmeticXP : public GrXferProcessor {
public:
- static GrXferProcessor* Create(float k1, float k2, float k3, float k4, bool enforcePMColor,
- const DstTexture* dstTexture, bool willReadDstColor) {
- return SkNEW_ARGS(ArithmeticXP, (k1, k2, k3, k4, enforcePMColor, dstTexture,
- willReadDstColor));
- }
-
- ~ArithmeticXP() override {};
+ ArithmeticXP(const DstTexture*, bool hasMixedSamples,
+ float k1, float k2, float k3, float k4, bool enforcePMColor);
const char* name() const override { return "Arithmetic"; }
bool enforcePMColor() const { return fEnforcePMColor; }
private:
- ArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor,
- const DstTexture*, bool willReadDstColor);
-
GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
bool doesStencilWrite,
///////////////////////////////////////////////////////////////////////////////
-ArithmeticXP::ArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor,
- const DstTexture* dstTexture, bool willReadDstColor)
- : INHERITED(dstTexture, willReadDstColor)
+ArithmeticXP::ArithmeticXP(const DstTexture* dstTexture, bool hasMixedSamples,
+ float k1, float k2, float k3, float k4, bool enforcePMColor)
+ : INHERITED(dstTexture, true, hasMixedSamples)
, fK1(k1)
, fK2(k2)
, fK3(k3)
GrArithmeticXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture* dstTexture) const {
- return ArithmeticXP::Create(fK1, fK2, fK3, fK4, fEnforcePMColor, dstTexture,
- this->willReadDstColor(caps, colorPOI, coveragePOI));
+ return SkNEW_ARGS(ArithmeticXP, (dstTexture, hasMixedSamples, fK1, fK2, fK3, fK4,
+ fEnforcePMColor));
}
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture*) const override;
bool willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI) const override {
+ const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples) const override {
return true;
}
// Create XferProcessor from DS's XPFactory
SkAutoTUnref<GrXferProcessor> xferProcessor(
pipelineBuilder.getXPFactory()->createXferProcessor(
- colorPOI, coveragePOI, dstTexture, caps));
+ colorPOI, coveragePOI, pipelineBuilder.hasMixedSamples(), dstTexture, caps));
GrColor overrideColor = GrColor_ILLEGAL;
if (colorPOI.firstEffectiveStageIndex() != 0) {
bool GrPipelineBuilder::willXPNeedDstTexture(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI) const {
- return this->getXPFactory()->willNeedDstTexture(caps, colorPOI, coveragePOI);
+ return this->getXPFactory()->willNeedDstTexture(caps, colorPOI, coveragePOI,
+ this->hasMixedSamples());
}
void GrPipelineBuilder::AutoRestoreFragmentProcessors::set(GrPipelineBuilder* pipelineBuilder) {
*/
void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
+ /**
+ * Returns whether the rasterizer and stencil test (if any) will run at a higher sample rate
+ * than the color buffer. In is scenario, the higher sample rate is resolved during blending.
+ */
+ bool hasMixedSamples() const {
+ return this->isHWAntialias() && !fRenderTarget->isMultisampled();
+ }
+
/// @}
///////////////////////////////////////////////////////////////////////////
*/
#include "GrXferProcessor.h"
+#include "GrPipelineBuilder.h"
#include "GrProcOptInfo.h"
#include "gl/GrGLCaps.h"
GrXferProcessor::GrXferProcessor()
- : fWillReadDstColor(false), fReadsCoverage(true), fDstTextureOffset() {
+ : fWillReadDstColor(false)
+ , fDstReadUsesMixedSamples(false)
+ , fReadsCoverage(true)
+ , fDstTextureOffset() {
}
-GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture, bool willReadDstColor)
+GrXferProcessor::GrXferProcessor(const DstTexture* dstTexture,
+ bool willReadDstColor,
+ bool hasMixedSamples)
: fWillReadDstColor(willReadDstColor)
+ , fDstReadUsesMixedSamples(willReadDstColor && hasMixedSamples)
, fReadsCoverage(true)
, fDstTextureOffset() {
if (dstTexture && dstTexture->texture()) {
if (!this->willReadDstColor()) {
return this->onHasSecondaryOutput();
}
- return false;
+ return this->dstReadUsesMixedSamples();
}
void GrXferProcessor::getBlendInfo(BlendInfo* blendInfo) const {
blendInfo->reset();
if (!this->willReadDstColor()) {
this->onGetBlendInfo(blendInfo);
+ } else if (this->dstReadUsesMixedSamples()) {
+ blendInfo->fDstBlend = kIS2A_GrBlendCoeff;
}
}
if (this->readsCoverage()) {
key |= 0x8;
}
+ if (this->dstReadUsesMixedSamples()) {
+ key |= 0x10;
+ }
}
b->add32(key);
this->onGetGLProcessorKey(caps, b);
GrXferProcessor* GrXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture* dstTexture,
const GrCaps& caps) const {
#ifdef SK_DEBUG
- if (this->willReadDstColor(caps, colorPOI, coveragePOI)) {
+ if (this->willReadDstColor(caps, colorPOI, coveragePOI, hasMixedSamples)) {
if (!caps.shaderCaps()->dstReadInShaderSupport()) {
SkASSERT(dstTexture && dstTexture->texture());
} else {
} else {
SkASSERT(!dstTexture || !dstTexture->texture());
}
+ SkASSERT(!hasMixedSamples || caps.shaderCaps()->dualSourceBlendingSupport());
#endif
- return this->onCreateXferProcessor(caps, colorPOI, coveragePOI, dstTexture);
+ return this->onCreateXferProcessor(caps, colorPOI, coveragePOI, hasMixedSamples, dstTexture);
}
-bool GrXPFactory::willNeedDstTexture(const GrCaps& caps, const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI) const {
- return (this->willReadDstColor(caps, colorPOI, coveragePOI)
- && !caps.shaderCaps()->dstReadInShaderSupport());
+bool GrXPFactory::willNeedDstTexture(const GrCaps& caps,
+ const GrProcOptInfo& colorPOI,
+ const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples) const {
+ return (this->willReadDstColor(caps, colorPOI, coveragePOI, hasMixedSamples) &&
+ !caps.shaderCaps()->dstReadInShaderSupport());
}
GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI,
+ bool hasMixedSamples,
const DstTexture* dst) const {
+ // We don't support inverting coverage with mixed samples. We don't expect to ever want this in
+ // the future, however we could at some point make this work using an inverted coverage
+ // modulation table. Note that an inverted table still won't work if there are coverage procs.
+ if (fInvertCoverage && hasMixedSamples) {
+ SkASSERT(false);
+ return NULL;
+ }
+
return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage);
}
this->initClassID<CustomXP>();
}
- CustomXP(SkXfermode::Mode mode, const DstTexture* dstTexture)
- : INHERITED(dstTexture, true),
+ CustomXP(const DstTexture* dstTexture, bool hasMixedSamples, SkXfermode::Mode mode)
+ : INHERITED(dstTexture, true, hasMixedSamples),
fMode(mode),
fHWBlendEquation(static_cast<GrBlendEquation>(-1)) {
this->initClassID<CustomXP>();
GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation());
- // Apply coverage by multiplying it into the src color before blending.
- // (See onGetOptimizations())
+ // Apply coverage by multiplying it into the src color before blending. Mixed samples will
+ // "just work" automatically. (See onGetOptimizations())
if (xp.readsCoverage()) {
fsBuilder->codeAppendf("%s = %s * %s;",
args.fOutputPrimary, args.fInputCoverage, args.fInputColor);
GrCustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture* dstTexture) const {
if (can_use_hw_blend_equation(coveragePOI, caps)) {
SkASSERT(!dstTexture || !dstTexture->texture());
return SkNEW_ARGS(CustomXP, (fMode, fHWBlendEquation));
}
- return SkNEW_ARGS(CustomXP, (fMode, dstTexture));
+ return SkNEW_ARGS(CustomXP, (dstTexture, hasMixedSamples, fMode));
}
bool GrCustomXPFactory::willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI) const {
+ const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples) const {
return !can_use_hw_blend_equation(coveragePOI, caps);
}
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture*) const override;
bool willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI) const override;
+ const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples) const override;
bool onIsEqual(const GrXPFactory& xpfBase) const override {
const GrCustomXPFactory& xpf = xpfBase.cast<GrCustomXPFactory>();
GrDisableColorXPFactory::onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& covPOI,
+ bool hasMixedSamples,
const DstTexture* dst) const {
return DisableColorXP::Create();
}
GrXferProcessor* onCreateXferProcessor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples,
const DstTexture* dstTexture) const override;
bool willReadDstColor(const GrCaps& caps,
const GrProcOptInfo& colorPOI,
- const GrProcOptInfo& coveragePOI) const override {
+ const GrProcOptInfo& coveragePOI,
+ bool hasMixedSamples) const override {
return false;
}
/* 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"; }
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,
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;
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"; }
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;
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*/,
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);
args.fXP);
// Apply coverage.
- if (args.fXP.readsCoverage()) {
+ if (args.fXP.dstReadUsesMixedSamples()) {
+ if (args.fXP.readsCoverage()) {
+ fsBuilder->codeAppendf("%s *= %s;", args.fOutputPrimary, args.fInputCoverage);
+ fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage);
+ } else {
+ fsBuilder->codeAppendf("%s = vec4(1.0);", args.fOutputSecondary);
+ }
+ } else if (args.fXP.readsCoverage()) {
fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
args.fOutputPrimary, args.fInputCoverage,
args.fOutputPrimary, args.fInputCoverage, dstColor);
XPInfo(skiatest::Reporter* reporter, SkXfermode::Mode xfermode, const GrCaps& caps,
const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI) {
SkAutoTUnref<GrXPFactory> xpf(GrPorterDuffXPFactory::Create(xfermode));
- SkAutoTUnref<GrXferProcessor> xp(xpf->createXferProcessor(colorPOI, covPOI, 0, caps));
- TEST_ASSERT(!xpf->willNeedDstTexture(caps, colorPOI, covPOI));
+ SkAutoTUnref<GrXferProcessor> xp(
+ xpf->createXferProcessor(colorPOI, covPOI, false, NULL, caps));
+ TEST_ASSERT(!xpf->willNeedDstTexture(caps, colorPOI, covPOI, false));
xpf->getInvariantBlendedColor(colorPOI, &fBlendedColor);
- fOptFlags = xp->getOptimizations(colorPOI, covPOI, false, 0, caps);
+ fOptFlags = xp->getOptimizations(colorPOI, covPOI, false, NULL, caps);
GetXPOutputTypes(xp, &fPrimaryOutputType, &fSecondaryOutputType);
xp->getBlendInfo(&fBlendInfo);
TEST_ASSERT(!xp->willReadDstColor());
SkASSERT(covPOI.isFourChannelOutput());
SkAutoTUnref<GrXPFactory> xpf(GrPorterDuffXPFactory::Create(SkXfermode::kSrcOver_Mode));
- TEST_ASSERT(!xpf->willNeedDstTexture(caps, colorPOI, covPOI));
+ TEST_ASSERT(!xpf->willNeedDstTexture(caps, colorPOI, covPOI, false));
- SkAutoTUnref<GrXferProcessor> xp(xpf->createXferProcessor(colorPOI, covPOI, 0, caps));
+ SkAutoTUnref<GrXferProcessor> xp(
+ xpf->createXferProcessor(colorPOI, covPOI, false, NULL, caps));
if (!xp) {
ERRORF(reporter, "Failed to create an XP with LCD coverage.");
return;
for (int m = 0; m <= SkXfermode::kLastCoeffMode; m++) {
SkXfermode::Mode xfermode = static_cast<SkXfermode::Mode>(m);
SkAutoTUnref<GrXPFactory> xpf(GrPorterDuffXPFactory::Create(xfermode));
- SkAutoTUnref<GrXferProcessor> xp;
- if (xpf->willNeedDstTexture(caps, colorPOI, covPOI)) {
- xp.reset(xpf->createXferProcessor(colorPOI, covPOI, &fakeDstTexture, caps));
- } else {
- xp.reset(xpf->createXferProcessor(colorPOI, covPOI, NULL, caps));
- }
+ GrXferProcessor::DstTexture* dstTexture =
+ xpf->willNeedDstTexture(caps, colorPOI, covPOI, false) ? &fakeDstTexture : 0;
+ SkAutoTUnref<GrXferProcessor> xp(
+ xpf->createXferProcessor(colorPOI, covPOI, false, dstTexture, caps));
if (!xp) {
ERRORF(reporter, "Failed to create an XP without dual source blending.");
return;