aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2018-02-05 15:59:23 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-05 21:17:51 +0000
commit547c8590a553efef7bcfb4c04e52072eb1271bea (patch)
tree73186b27c47a20059dfa97111e75288f4ad11b93 /src
parentca9c879900a5bc8e7b12dafca5922a05570da6b1 (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.cpp17
-rw-r--r--src/core/SkCoverageModePriv.h8
-rw-r--r--src/core/SkMaskFilter.cpp38
-rw-r--r--src/gpu/GrProcessorSet.cpp3
-rw-r--r--src/gpu/SkGpuDevice_drawTexture.cpp3
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.