diff options
author | Mike Reed <reed@google.com> | 2018-02-05 15:59:23 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-02-05 21:17:51 +0000 |
commit | 547c8590a553efef7bcfb4c04e52072eb1271bea (patch) | |
tree | 73186b27c47a20059dfa97111e75288f4ad11b93 /src | |
parent | ca9c879900a5bc8e7b12dafca5922a05570da6b1 (diff) |
gpu impl for compose and combine maskfilters
remove "warning" in GrProcessorSet about coverage-as-alpha (we think the current behavior is correct)
update gpudevice::drawImage to check for maskfilter before trying to create its mask
Bug: skia:
Change-Id: I9ecb6cd25dd003bc19fa1e33edf6614a5ba4acb7
Reviewed-on: https://skia-review.googlesource.com/103761
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkBlendMode.cpp | 17 | ||||
-rw-r--r-- | src/core/SkCoverageModePriv.h | 8 | ||||
-rw-r--r-- | src/core/SkMaskFilter.cpp | 38 | ||||
-rw-r--r-- | src/gpu/GrProcessorSet.cpp | 3 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice_drawTexture.cpp | 3 |
5 files changed, 58 insertions, 11 deletions
diff --git a/src/core/SkBlendMode.cpp b/src/core/SkBlendMode.cpp index 548106f1c4..661ade6188 100644 --- a/src/core/SkBlendMode.cpp +++ b/src/core/SkBlendMode.cpp @@ -6,6 +6,7 @@ */ #include "SkBlendModePriv.h" +#include "SkCoverageModePriv.h" #include "SkRasterPipeline.h" #include "../jumper/SkJumper.h" @@ -148,3 +149,19 @@ SkPM4f SkBlendMode_Apply(SkBlendMode mode, const SkPM4f& src, const SkPM4f& dst) p.run(0,0, 1,1); return res_storage; } + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +const SkBlendMode gUncorrelatedCoverageToBlend[] = { + SkBlendMode::kSrcOver, // or DstOver + SkBlendMode::kSrcIn, // or kDstIn + SkBlendMode::kSrcOut, + SkBlendMode::kDstOut, + SkBlendMode::kXor, +}; + +SkBlendMode SkUncorrelatedCoverageModeToBlendMode(SkCoverageMode cm) { + unsigned index = static_cast<unsigned>(cm); + SkASSERT(index < SK_ARRAY_COUNT(gUncorrelatedCoverageToBlend)); + return gUncorrelatedCoverageToBlend[index]; +} diff --git a/src/core/SkCoverageModePriv.h b/src/core/SkCoverageModePriv.h index d019e60bda..e8b8939ade 100644 --- a/src/core/SkCoverageModePriv.h +++ b/src/core/SkCoverageModePriv.h @@ -11,13 +11,7 @@ #include "SkBlendMode.h" #include "SkCoverageMode.h" -const SkBlendMode gUncorrelatedCoverageToBlend[] = { - SkBlendMode::kSrcOver, // or DstOver - SkBlendMode::kSrcIn, // or kDstIn - SkBlendMode::kSrcOut, - SkBlendMode::kDstOut, - SkBlendMode::kXor, -}; +SkBlendMode SkUncorrelatedCoverageModeToBlendMode(SkCoverageMode); #if 0 // Experimental idea to extend to overlap types diff --git a/src/core/SkMaskFilter.cpp b/src/core/SkMaskFilter.cpp index 59baa4fbff..83d5608ecf 100644 --- a/src/core/SkMaskFilter.cpp +++ b/src/core/SkMaskFilter.cpp @@ -21,6 +21,7 @@ #if SK_SUPPORT_GPU #include "GrTextureProxy.h" #include "GrFragmentProcessor.h" +#include "effects/GrXfermodeFragmentProcessor.h" #endif SkMaskFilterBase::NinePatch::~NinePatch() { @@ -411,6 +412,24 @@ public: SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeMF) +protected: +#if SK_SUPPORT_GPU + std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(const GrFPArgs& args) const override{ + std::unique_ptr<GrFragmentProcessor> array[2] = { + as_MFB(fInner)->asFragmentProcessor(args), + as_MFB(fOuter)->asFragmentProcessor(args), + }; + if (!array[0] || !array[1]) { + return nullptr; + } + return GrFragmentProcessor::RunInSeries(array, 2); + } + + bool onHasFragmentProcessor() const override { + return as_MFB(fInner)->hasFragmentProcessor() && as_MFB(fOuter)->hasFragmentProcessor(); + } +#endif + private: sk_sp<SkMaskFilter> fOuter; sk_sp<SkMaskFilter> fInner; @@ -488,6 +507,23 @@ public: SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkCombineMF) +protected: +#if SK_SUPPORT_GPU + std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(const GrFPArgs& args) const override{ + auto src = as_MFB(fSrc)->asFragmentProcessor(args); + auto dst = as_MFB(fDst)->asFragmentProcessor(args); + if (!src || !dst) { + return nullptr; + } + return GrXfermodeFragmentProcessor::MakeFromTwoProcessors(std::move(src), std::move(dst), + SkUncorrelatedCoverageModeToBlendMode(fMode)); + } + + bool onHasFragmentProcessor() const override { + return as_MFB(fSrc)->hasFragmentProcessor() && as_MFB(fDst)->hasFragmentProcessor(); + } +#endif + private: sk_sp<SkMaskFilter> fDst; sk_sp<SkMaskFilter> fSrc; @@ -570,7 +606,7 @@ bool SkCombineMF::filterMask(SkMask* dst, const SkMask& src, const SkMatrix& ctm p.setBlendMode(SkBlendMode::kSrc); dstM.fBounds.offset(-dst->fBounds.fLeft, -dst->fBounds.fTop); md.drawAsBitmap(dstM, p); - p.setBlendMode(gUncorrelatedCoverageToBlend[static_cast<int>(fMode)]); + p.setBlendMode(SkUncorrelatedCoverageModeToBlendMode(fMode)); srcM.fBounds.offset(-dst->fBounds.fLeft, -dst->fBounds.fTop); md.drawAsBitmap(srcM, p); diff --git a/src/gpu/GrProcessorSet.cpp b/src/gpu/GrProcessorSet.cpp index 0601d92db8..919ff47e3f 100644 --- a/src/gpu/GrProcessorSet.cpp +++ b/src/gpu/GrProcessorSet.cpp @@ -181,9 +181,6 @@ GrProcessorSet::Analysis GrProcessorSet::finalize(const GrProcessorAnalysisColor for (int i = 0; i < n; ++i) { if (!fps[i]->compatibleWithCoverageAsAlpha()) { analysis.fCompatibleWithCoverageAsAlpha = false; - // Other than tests that exercise atypical behavior we expect all coverage FPs to be - // compatible with the coverage-as-alpha optimization. - GrCapsDebugf(&caps, "Coverage FP is not compatible with coverage as alpha.\n"); } coverageUsesLocalCoords |= fps[i]->usesLocalCoords(); } diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp index 0798f1e012..b6b1e619c0 100644 --- a/src/gpu/SkGpuDevice_drawTexture.cpp +++ b/src/gpu/SkGpuDevice_drawTexture.cpp @@ -248,6 +248,9 @@ void SkGpuDevice::drawTextureProducerImpl(GrTextureProducer* producer, // FP. In the future this should be an opaque optimization enabled by the combination of // GrDrawOp/GP and FP. const SkMaskFilter* mf = paint.getMaskFilter(); + if (mf && as_MFB(mf)->hasFragmentProcessor()) { + mf = nullptr; + } // The shader expects proper local coords, so we can't replace local coords with texture coords // if the shader will be used. If we have a mask filter we will change the underlying geometry // that is rendered. |