Only discard for XP dstCopies if we have a coverage value. TBR=bsalomon@google.com BUG=skia: Review URL: https://codereview.chromium.org/1125283005
diff --git a/include/gpu/GrXferProcessor.h b/include/gpu/GrXferProcessor.h index 7c07b80..812ce5c 100644 --- a/include/gpu/GrXferProcessor.h +++ b/include/gpu/GrXferProcessor.h
@@ -164,11 +164,11 @@ * A caller who calls this function on a XP is required to honor the returned OptFlags * and color values for its draw. */ - virtual OptFlags getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* overrideColor, - const GrDrawTargetCaps& caps) = 0; + OptFlags getOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps); /** * Returns whether this XP will require an Xfer barrier on the given rt. If true, outBarrierType @@ -217,6 +217,11 @@ return fDstCopyTextureOffset; } + /** + * Returns whether or not the XP will look at coverage when doing its blending. + */ + bool readsCoverage() const { return fReadsCoverage; } + /** * Returns whether or not this xferProcossor will set a secondary output to be used with dual * source blending. @@ -237,6 +242,9 @@ if (this->fWillReadDstColor != that.fWillReadDstColor) { return false; } + if (this->fReadsCoverage != that.fReadsCoverage) { + return false; + } if (this->fDstCopy.getTexture() != that.fDstCopy.getTexture()) { return false; } @@ -251,6 +259,12 @@ GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); private: + virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) = 0; + /** * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer * processor's GL backend implementation. @@ -278,6 +292,7 @@ virtual bool onIsEqual(const GrXferProcessor&) const = 0; bool fWillReadDstColor; + bool fReadsCoverage; SkIPoint fDstCopyTextureOffset; GrTextureAccess fDstCopy;
diff --git a/src/effects/SkArithmeticMode_gpu.cpp b/src/effects/SkArithmeticMode_gpu.cpp index bd87931..69c2d7c 100644 --- a/src/effects/SkArithmeticMode_gpu.cpp +++ b/src/effects/SkArithmeticMode_gpu.cpp
@@ -175,12 +175,6 @@ bool hasSecondaryOutput() const override { return false; } - GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* overrideColor, - const GrDrawTargetCaps& caps) override; - float k1() const { return fK1; } float k2() const { return fK2; } float k3() const { return fK3; } @@ -191,6 +185,12 @@ ArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); + GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) override; + void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; bool onIsEqual(const GrXferProcessor& xpBase) const override { @@ -281,11 +281,11 @@ return SkNEW_ARGS(GLArithmeticXP, (*this)); } -GrXferProcessor::OptFlags ArithmeticXP::getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* overrideColor, - const GrDrawTargetCaps& caps) { +GrXferProcessor::OptFlags ArithmeticXP::onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) { return GrXferProcessor::kNone_Opt; }
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp index 243b9fe..bc79b2d 100644 --- a/src/gpu/GrXferProcessor.cpp +++ b/src/gpu/GrXferProcessor.cpp
@@ -8,11 +8,13 @@ #include "GrXferProcessor.h" #include "gl/GrGLCaps.h" -GrXferProcessor::GrXferProcessor() : fWillReadDstColor(false), fDstCopyTextureOffset() { +GrXferProcessor::GrXferProcessor() + : fWillReadDstColor(false), fReadsCoverage(true), fDstCopyTextureOffset() { } GrXferProcessor::GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor) : fWillReadDstColor(willReadDstColor) + , fReadsCoverage(true) , fDstCopyTextureOffset() { if (dstCopy && dstCopy->texture()) { fDstCopy.reset(dstCopy->texture()); @@ -22,6 +24,23 @@ } } +GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) { + GrXferProcessor::OptFlags flags = this->onGetOptimizations(colorPOI, + coveragePOI, + doesStencilWrite, + overrideColor, + caps); + + if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) { + fReadsCoverage = false; + } + return flags; +} + void GrXferProcessor::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const { uint32_t key = this->willReadDstColor() ? 0x1 : 0x0; if (this->getDstCopyTexture() &&
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp index 69b9ea4..02552b3 100644 --- a/src/gpu/effects/GrCoverageSetOpXP.cpp +++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -29,17 +29,17 @@ bool hasSecondaryOutput() const override { return false; } - GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* color, - const GrDrawTargetCaps& caps) override; - bool invertCoverage() const { return fInvertCoverage; } private: CoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage); + GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* color, + const GrDrawTargetCaps& caps) override; + void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override; @@ -108,11 +108,11 @@ } GrXferProcessor::OptFlags -CoverageSetOpXP::getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* color, - const GrDrawTargetCaps& caps) { +CoverageSetOpXP::onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* color, + const GrDrawTargetCaps& caps) { // We never look at the color input return GrXferProcessor::kIgnoreColor_OptFlag; }
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index b15e2c2..0a525b4 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -525,14 +525,7 @@ bool hasSecondaryOutput() const override { return false; } - GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* overrideColor, - const GrDrawTargetCaps& caps) override; - SkXfermode::Mode mode() const { return fMode; } - bool hasCoverage() const { return fHasCoverage; } bool hasHWBlendEquation() const { return kInvalid_GrBlendEquation != fHWBlendEquation; } GrBlendEquation hwBlendEquation() const { @@ -543,6 +536,12 @@ private: CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); + GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) override; + void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; bool onWillNeedXferBarrier(const GrRenderTarget* rt, @@ -554,7 +553,6 @@ bool onIsEqual(const GrXferProcessor& xpBase) const override; SkXfermode::Mode fMode; - bool fHasCoverage; GrBlendEquation fHWBlendEquation; typedef GrXferProcessor INHERITED; @@ -581,7 +579,7 @@ const CustomXP& xp = p.cast<CustomXP>(); uint32_t key = xp.numTextures(); SkASSERT(key <= 1); - key |= xp.hasCoverage() << 1; + key |= xp.readsCoverage() << 1; if (xp.hasHWBlendEquation()) { SkASSERT(caps.advBlendEqInteraction() > 0); // 0 will mean !xp.hasHWBlendEquation(). key |= caps.advBlendEqInteraction() << 2; @@ -601,7 +599,7 @@ if (xp.hasHWBlendEquation()) { // The blend mode will be implemented in hardware; only output the src color. fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation()); - if (xp.hasCoverage()) { + if (xp.readsCoverage()) { // Do coverage modulation by multiplying it into the src color before blending. // (See getOptimizations()) fsBuilder->codeAppendf("%s = %s * %s;", @@ -613,7 +611,7 @@ const char* dstColor = fsBuilder->dstColor(); emit_custom_xfermode_code(xp.mode(), fsBuilder, args.fOutputPrimary, args.fInputColor, dstColor); - if (xp.hasCoverage()) { + if (xp.readsCoverage()) { fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;", args.fOutputPrimary, args.fOutputPrimary, args.fInputCoverage, args.fInputCoverage, dstColor); @@ -632,7 +630,6 @@ bool willReadDstColor) : INHERITED(dstCopy, willReadDstColor), fMode(mode), - fHasCoverage(true), fHWBlendEquation(kInvalid_GrBlendEquation) { this->initClassID<CustomXP>(); } @@ -648,12 +645,10 @@ bool CustomXP::onIsEqual(const GrXferProcessor& other) const { const CustomXP& s = other.cast<CustomXP>(); - return fMode == s.fMode && - fHasCoverage == s.fHasCoverage && - fHWBlendEquation == s.fHWBlendEquation; + return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation; } -GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorPOI, +GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, bool doesStencilWrite, GrColor* overrideColor, @@ -760,7 +755,6 @@ } if (coveragePOI.isSolidWhite()) { flags = flags | kIgnoreCoverage_OptFlag; - fHasCoverage = false; } if (caps.advancedBlendEquationSupport() && !coveragePOI.isFourChannelOutput()) { // This blend mode can be implemented in hardware.
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp index 261100d..9b513f6 100644 --- a/src/gpu/effects/GrDisableColorXP.cpp +++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -29,17 +29,17 @@ bool hasSecondaryOutput() const override { return false; } - GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* color, - const GrDrawTargetCaps& caps) override { - return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag; - } - private: DisableColorXP(); + GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* color, + const GrDrawTargetCaps& caps) override { + return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag; + } + void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override;
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp index 73d5824..543a515 100644 --- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp +++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -84,12 +84,6 @@ PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; } SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputType; } - GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* overrideColor, - const GrDrawTargetCaps& caps) override; - GrBlendCoeff getSrcBlend() const { return fSrcBlend; } GrBlendCoeff getDstBlend() const { return fDstBlend; } @@ -97,6 +91,12 @@ PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor); + GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) override; + void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override { @@ -301,11 +301,11 @@ } GrXferProcessor::OptFlags -PorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, - const GrProcOptInfo& coveragePOI, - bool doesStencilWrite, - GrColor* overrideColor, - const GrDrawTargetCaps& caps) { +PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI, + const GrProcOptInfo& coveragePOI, + bool doesStencilWrite, + GrColor* overrideColor, + const GrDrawTargetCaps& caps) { GrXferProcessor::OptFlags optFlags; // Optimizations when doing RGB Coverage if (coveragePOI.isFourChannelOutput()) {
diff --git a/src/gpu/gl/GrGLXferProcessor.cpp b/src/gpu/gl/GrGLXferProcessor.cpp index c517381..657da41 100644 --- a/src/gpu/gl/GrGLXferProcessor.cpp +++ b/src/gpu/gl/GrGLXferProcessor.cpp
@@ -17,11 +17,14 @@ GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); - // We don't think any shaders actually output negative coverage, but just as a safety check - // for floating point precision errors we compare with <= here - fsBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {" - " discard;" - "}", args.fInputCoverage); + if (args.fXP.readsCoverage()) { + // We don't think any shaders actually output negative coverage, but just as a safety + // check for floating point precision errors we compare with <= here + fsBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {" + " discard;" + "}", args.fInputCoverage); + } + const char* dstColor = fsBuilder->dstColor(); const char* dstCopyTopLeftName;