Index: src/gpu/effects/GrCoverageSetOpXP.cpp |
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp |
index 43bb4887cfa985c701111ba5d608a3c2d679e49f..219ed0b505c98b1052b82ae9b3b99ccf4b590efe 100644 |
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp |
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp |
@@ -11,6 +11,7 @@ |
#include "GrColor.h" |
#include "GrProcessor.h" |
#include "GrProcOptInfo.h" |
+#include "glsl/GrGLSLBlend.h" |
#include "glsl/GrGLSLProgramBuilder.h" |
#include "glsl/GrGLSLFragmentShaderBuilder.h" |
#include "glsl/GrGLSLXferProcessor.h" |
@@ -146,6 +147,96 @@ void CoverageSetOpXP::onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) cons |
/////////////////////////////////////////////////////////////////////////////// |
+class ShaderCSOXferProcessor : public GrXferProcessor { |
+public: |
+ ShaderCSOXferProcessor(const DstTexture* dstTexture, |
+ bool hasMixedSamples, |
+ SkXfermode::Mode xfermode, |
+ SkRegion::Op regionOp, |
+ bool invertCoverage) |
+ : INHERITED(dstTexture, true, hasMixedSamples) |
+ , fRegionOp(regionOp) |
+ , fInvertCoverage(invertCoverage) { |
+ this->initClassID<ShaderCSOXferProcessor>(); |
+ } |
+ |
+ const char* name() const override { return "Coverage Set Op Shader"; } |
+ |
+ GrGLSLXferProcessor* createGLSLInstance() const override; |
+ |
+ SkRegion::Op regionOp() const { return fRegionOp; } |
+ bool invertCoverage() const { return fInvertCoverage; } |
+ |
+private: |
+ GrXferProcessor::OptFlags onGetOptimizations(const GrPipelineOptimizations&, bool, GrColor*, |
+ const GrCaps&) const override { |
+ // We never look at the color input |
+ return GrXferProcessor::kIgnoreColor_OptFlag; |
+ } |
+ |
+ void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; |
+ |
+ bool onIsEqual(const GrXferProcessor& xpBase) const override { |
+ const ShaderCSOXferProcessor& xp = xpBase.cast<ShaderCSOXferProcessor>(); |
+ return (fRegionOp == xp.fRegionOp && |
+ fInvertCoverage == xp.fInvertCoverage); |
+ } |
+ |
+ SkRegion::Op fRegionOp; |
+ bool fInvertCoverage; |
+ |
+ typedef GrXferProcessor INHERITED; |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+class GLShaderCSOXferProcessor : public GrGLSLXferProcessor { |
+public: |
+ static void GenKey(const GrProcessor& processor, GrProcessorKeyBuilder* b) { |
+ const ShaderCSOXferProcessor& xp = processor.cast<ShaderCSOXferProcessor>(); |
+ b->add32(xp.regionOp()); |
+ uint32_t key = xp.invertCoverage() ? 0x0 : 0x1; |
+ b->add32(key); |
+ } |
+ |
+private: |
+ void emitBlendCodeForDstRead(GrGLSLXPBuilder* pb, |
+ GrGLSLXPFragmentBuilder* fragBuilder, |
+ const char* srcColor, |
+ const char* srcCoverage, |
+ const char* dstColor, |
+ const char* outColor, |
+ const char* outColorSecondary, |
+ const GrXferProcessor& proc) override { |
+ const ShaderCSOXferProcessor& xp = proc.cast<ShaderCSOXferProcessor>(); |
+ |
+ if (xp.invertCoverage()) { |
+ fragBuilder->codeAppendf("%s = 1.0 - %s;", outColor, srcCoverage); |
+ } else { |
+ fragBuilder->codeAppendf("%s = %s;", outColor, srcCoverage); |
+ } |
+ |
+ GrGLSLBlend::AppendRegionOp(fragBuilder, outColor, dstColor, outColor, xp.regionOp()); |
+ } |
+ |
+ void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {} |
+ |
+ typedef GrGLSLXferProcessor INHERITED; |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+void ShaderCSOXferProcessor::onGetGLSLProcessorKey(const GrGLSLCaps&, |
+ GrProcessorKeyBuilder* b) const { |
+ GLShaderCSOXferProcessor::GenKey(*this, b); |
+} |
+ |
+GrGLSLXferProcessor* ShaderCSOXferProcessor::createGLSLInstance() const { |
+ return new GLShaderCSOXferProcessor; |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// |
GrCoverageSetOpXPFactory::GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage) |
: fRegionOp(regionOp) |
, fInvertCoverage(invertCoverage) { |