From 2b816bacc0696f03d88c8060b21eda1e5cc7e8b1 Mon Sep 17 00:00:00 2001 From: egdaniel Date: Fri, 13 Feb 2015 11:07:54 -0800 Subject: Revert of Use dst copies in porter duffer XP to correctly render certain blends. (patchset #4 id:60001 of https://codereview.chromium.org/914003003/) Reason for revert: Failing GLProgramTest passing in stupid coeffs Original issue's description: > Use dst copies in porter duffer XP to correctly render certain blends. > > BUG=skia: > > Committed: https://skia.googlesource.com/skia/+/997c6358d94e188b1a7b89a4f86e24cbe0f5a164 TBR=bsalomon@google.com,joshualitt@google.com NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/923153003 --- src/gpu/effects/GrCoverageSetOpXP.cpp | 3 +- src/gpu/effects/GrCoverageSetOpXP.h | 6 +- src/gpu/effects/GrCustomXfermode.cpp | 5 +- src/gpu/effects/GrCustomXfermodePriv.h | 6 +- src/gpu/effects/GrDisableColorXP.cpp | 3 +- src/gpu/effects/GrDisableColorXP.h | 6 +- src/gpu/effects/GrPorterDuffXferProcessor.cpp | 216 ++++++++------------------ 7 files changed, 75 insertions(+), 170 deletions(-) (limited to 'src/gpu/effects') diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp index 40998d5033..f0ec1f9b00 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.cpp +++ b/src/gpu/effects/GrCoverageSetOpXP.cpp @@ -228,8 +228,7 @@ GrXPFactory* GrCoverageSetOpXPFactory::Create(SkRegion::Op regionOp, bool invert } GrXferProcessor* -GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, +GrCoverageSetOpXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, const GrDeviceCoordTexture* dstCopy) const { return CoverageSetOpXP::Create(fRegionOp, fInvertCoverage); diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h index e8900b3604..01dce95211 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.h +++ b/src/gpu/effects/GrCoverageSetOpXP.h @@ -35,13 +35,11 @@ public: private: GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage); - GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, + GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; - bool willReadDstColor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, + bool willReadDstColor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI) const SK_OVERRIDE { return false; } diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index e4d65e41e4..8d8f9f251d 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -608,11 +608,10 @@ GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode) } GrXferProcessor* -GrCustomXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, +GrCustomXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, const GrDeviceCoordTexture* dstCopy) const { - return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(caps, colorPOI, coveragePOI)); + return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(colorPOI, coveragePOI)); } diff --git a/src/gpu/effects/GrCustomXfermodePriv.h b/src/gpu/effects/GrCustomXfermodePriv.h index 8672529e45..959b079603 100644 --- a/src/gpu/effects/GrCustomXfermodePriv.h +++ b/src/gpu/effects/GrCustomXfermodePriv.h @@ -77,13 +77,11 @@ public: GrXPFactory::InvariantOutput*) const SK_OVERRIDE; private: - GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, + GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; - bool willReadDstColor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, + bool willReadDstColor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI) const SK_OVERRIDE { return true; } diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp index d97589dcb6..637f99baf1 100644 --- a/src/gpu/effects/GrDisableColorXP.cpp +++ b/src/gpu/effects/GrDisableColorXP.cpp @@ -100,8 +100,7 @@ GrDisableColorXPFactory::GrDisableColorXPFactory() { } GrXferProcessor* -GrDisableColorXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, +GrDisableColorXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, const GrDeviceCoordTexture* dstCopy) const { return DisableColorXP::Create(); diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h index 00675884a9..fe60b595a0 100644 --- a/src/gpu/effects/GrDisableColorXP.h +++ b/src/gpu/effects/GrDisableColorXP.h @@ -39,13 +39,11 @@ public: private: GrDisableColorXPFactory(); - GrXferProcessor* onCreateXferProcessor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, + GrXferProcessor* onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, const GrDeviceCoordTexture* dstCopy) const SK_OVERRIDE; - bool willReadDstColor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, + bool willReadDstColor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI) const SK_OVERRIDE { return false; } diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index 22029e1d14..6f2b63f5cb 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp @@ -59,10 +59,6 @@ public: kCoverage_PrimaryOutputType, // Modulate color and coverage, write result as the color output. kModulate_PrimaryOutputType, - // Custom Porter-Duff output, used for when we explictly are reading the dst and blending - // in the shader. Secondary Output must be none if you use this. The custom blend uses the - // equation: cov * (coeffS * S + coeffD * D) + (1 - cov) * D - kCustom_PrimaryOutputType }; enum SecondaryOutputType { @@ -91,19 +87,11 @@ public: const GrDrawTargetCaps& caps) SK_OVERRIDE; void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE { - if (!this->willReadDstColor()) { - blendInfo->fSrcBlend = fSrcBlend; - blendInfo->fDstBlend = fDstBlend; - } else { - blendInfo->fSrcBlend = kOne_GrBlendCoeff; - blendInfo->fDstBlend = kZero_GrBlendCoeff; - } + blendInfo->fSrcBlend = fSrcBlend; + blendInfo->fDstBlend = fDstBlend; blendInfo->fBlendConstant = fBlendConstant; } - GrBlendCoeff getSrcBlend() const { return fSrcBlend; } - GrBlendCoeff getDstBlend() const { return fDstBlend; } - private: PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); @@ -140,50 +128,6 @@ private: /////////////////////////////////////////////////////////////////////////////// -bool append_porterduff_term(GrGLFPFragmentBuilder* fsBuilder, GrBlendCoeff coeff, - const char* colorName, const char* srcColorName, - const char* dstColorName, bool hasPrevious) { - if (kZero_GrBlendCoeff == coeff) { - return hasPrevious; - } else { - if (hasPrevious) { - fsBuilder->codeAppend(" + "); - } - fsBuilder->codeAppendf("%s", colorName); - switch (coeff) { - case kOne_GrBlendCoeff: - break; - case kSC_GrBlendCoeff: - fsBuilder->codeAppendf(" * %s", srcColorName); - break; - case kISC_GrBlendCoeff: - fsBuilder->codeAppendf(" * (vec4(1.0) - %s)", srcColorName); - break; - case kDC_GrBlendCoeff: - fsBuilder->codeAppendf(" * %s", dstColorName); - break; - case kIDC_GrBlendCoeff: - fsBuilder->codeAppendf(" * (vec4(1.0) - %s)", dstColorName); - break; - case kSA_GrBlendCoeff: - fsBuilder->codeAppendf(" * %s.a", srcColorName); - break; - case kISA_GrBlendCoeff: - fsBuilder->codeAppendf(" * (1.0 - %s.a)", srcColorName); - break; - case kDA_GrBlendCoeff: - fsBuilder->codeAppendf(" * %s.a", dstColorName); - break; - case kIDA_GrBlendCoeff: - fsBuilder->codeAppendf(" * (1.0 - %s.a)", dstColorName); - break; - default: - SkFAIL("Unsupported Blend Coeff"); - } - return true; - } -} - class GLPorterDuffXferProcessor : public GrGLXferProcessor { public: GLPorterDuffXferProcessor(const GrProcessor&) {} @@ -195,24 +139,16 @@ public: const PorterDuffXferProcessor& xp = processor.cast(); b->add32(xp.primaryOutputType()); b->add32(xp.secondaryOutputType()); - if (xp.willReadDstColor()) { - b->add32(xp.getSrcBlend()); - b->add32(xp.getDstBlend()); - } }; private: void onEmitCode(const EmitArgs& args) SK_OVERRIDE { const PorterDuffXferProcessor& xp = args.fXP.cast(); GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); - if (PorterDuffXferProcessor::kCustom_PrimaryOutputType != xp.primaryOutputType()) { - SkASSERT(!xp.willReadDstColor()); + if (xp.hasSecondaryOutput()) { switch(xp.secondaryOutputType()) { - case PorterDuffXferProcessor::kNone_SecondaryOutputType: - break; case PorterDuffXferProcessor::kCoverage_SecondaryOutputType: - fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, - args.fInputCoverage); + fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage); break; case PorterDuffXferProcessor::kCoverageISA_SecondaryOutputType: fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;", @@ -227,43 +163,24 @@ private: default: SkFAIL("Unexpected Secondary Output"); } - - switch (xp.primaryOutputType()) { - case PorterDuffXferProcessor::kNone_PrimaryOutputType: - fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); - break; - case PorterDuffXferProcessor::kColor_PrimaryOutputType: - fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputColor); - break; - case PorterDuffXferProcessor::kCoverage_PrimaryOutputType: - fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage); - break; - case PorterDuffXferProcessor::kModulate_PrimaryOutputType: - fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor, - args.fInputCoverage); - break; - default: - SkFAIL("Unexpected Primary Output"); - } - } else { - SkASSERT(xp.willReadDstColor()); - - const char* dstColor = fsBuilder->dstColor(); - - fsBuilder->codeAppend("vec4 colorBlend ="); - // append src blend - bool didAppend = append_porterduff_term(fsBuilder, xp.getSrcBlend(), - args.fInputColor, args.fInputColor, - dstColor, false); - // append dst blend - SkAssertResult(append_porterduff_term(fsBuilder, xp.getDstBlend(), - dstColor, args.fInputColor, - dstColor, didAppend)); - fsBuilder->codeAppend(";"); - - fsBuilder->codeAppendf("%s = %s * colorBlend + (vec4(1.0) - %s) * %s;", - args.fOutputPrimary, args.fInputCoverage, args.fInputCoverage, - dstColor); + } + + switch (xp.primaryOutputType()) { + case PorterDuffXferProcessor::kNone_PrimaryOutputType: + fsBuilder->codeAppendf("%s = vec4(0);", args.fOutputPrimary); + break; + case PorterDuffXferProcessor::kColor_PrimaryOutputType: + fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputColor); + break; + case PorterDuffXferProcessor::kCoverage_PrimaryOutputType: + fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputCoverage); + break; + case PorterDuffXferProcessor::kModulate_PrimaryOutputType: + fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor, + args.fInputCoverage); + break; + default: + SkFAIL("Unexpected Primary Output"); } } @@ -279,8 +196,7 @@ PorterDuffXferProcessor::PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrColor constant, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor) - : INHERITED(dstCopy, willReadDstColor) - , fSrcBlend(srcBlend) + : fSrcBlend(srcBlend) , fDstBlend(dstBlend) , fBlendConstant(constant) , fPrimaryOutputType(kModulate_PrimaryOutputType) @@ -328,11 +244,6 @@ PorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, void PorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags, const GrDrawTargetCaps& caps, bool hasSolidCoverage) { - if (this->willReadDstColor()) { - fPrimaryOutputType = kCustom_PrimaryOutputType; - return; - } - if (optFlags & kIgnoreColor_OptFlag) { if (optFlags & kIgnoreCoverage_OptFlag) { fPrimaryOutputType = kNone_PrimaryOutputType; @@ -373,12 +284,11 @@ GrXferProcessor::OptFlags PorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, bool doesStencilWrite) { - if (this->willReadDstColor()) { - return GrXferProcessor::kNone_Opt; - } + bool srcAIsOne; + bool hasCoverage; - bool srcAIsOne = colorPOI.isOpaque(); - bool hasCoverage = !coveragePOI.isSolidWhite(); + srcAIsOne = colorPOI.isOpaque(); + hasCoverage = !coveragePOI.isSolidWhite(); bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend || (kSA_GrBlendCoeff == fDstBlend && srcAIsOne); @@ -543,20 +453,19 @@ GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode mode) { } GrXferProcessor* -GrPorterDuffXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, +GrPorterDuffXPFactory::onCreateXferProcessor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& covPOI, const GrDeviceCoordTexture* dstCopy) const { if (!covPOI.isFourChannelOutput()) { return PorterDuffXferProcessor::Create(fSrcCoeff, fDstCoeff, 0, dstCopy, - this->willReadDstColor(caps, colorPOI, covPOI)); + this->willReadDstColor(colorPOI, covPOI)); } else { if (this->supportsRGBCoverage(colorPOI.color(), colorPOI.validFlags())) { SkASSERT(kRGBA_GrColorComponentFlags == colorPOI.validFlags()); GrColor blendConstant = GrUnPreMulColor(colorPOI.color()); return PorterDuffXferProcessor::Create(kConstC_GrBlendCoeff, kISC_GrBlendCoeff, blendConstant, dstCopy, - this->willReadDstColor(caps, colorPOI, covPOI)); + this->willReadDstColor(colorPOI, covPOI)); } else { return NULL; } @@ -572,6 +481,39 @@ bool GrPorterDuffXPFactory::supportsRGBCoverage(GrColor /*knownColor*/, return false; } +bool GrPorterDuffXPFactory::canApplyCoverage(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI) const { + bool srcAIsOne = colorPOI.isOpaque(); + + bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstCoeff || + (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne); + bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstCoeff || + (kISA_GrBlendCoeff == fDstCoeff && srcAIsOne); + + if ((kZero_GrBlendCoeff == fSrcCoeff && dstCoeffIsOne)) { + return true; + } + + // if we don't have coverage we can check whether the dst + // has to read at all. + // check whether coverage can be safely rolled into alpha + // of if we can skip color computation and just emit coverage + if (this->canTweakAlphaForCoverage()) { + return true; + } + if (dstCoeffIsZero) { + if (kZero_GrBlendCoeff == fSrcCoeff) { + return true; + } else if (srcAIsOne) { + return true; + } + } else if (dstCoeffIsOne) { + return true; + } + + return false; +} + bool GrPorterDuffXPFactory::canTweakAlphaForCoverage() const { return can_tweak_alpha_for_coverage(fDstCoeff); } @@ -645,37 +587,9 @@ void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, output->fWillBlendWithDst = false; } -bool GrPorterDuffXPFactory::willReadDstColor(const GrDrawTargetCaps& caps, - const GrProcOptInfo& colorPOI, +bool GrPorterDuffXPFactory::willReadDstColor(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI) const { - // We can always blend correctly if we have dual source blending. - if (caps.dualSourceBlendingSupport()) { - return false; - } - - if (this->canTweakAlphaForCoverage()) { - return false; - } - - bool srcAIsOne = colorPOI.isOpaque(); - - if (kZero_GrBlendCoeff == fDstCoeff) { - if (kZero_GrBlendCoeff == fSrcCoeff || srcAIsOne) { - return false; - } - } - - // Reduces to: coeffS * (Cov*S) + D - if (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne) { - return false; - } - - // We can always blend correctly if we have solid coverage. - if (coveragePOI.isSolidWhite()) { - return false; - } - - return true; + return false; } GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); -- cgit v1.2.3