diff options
author | 2017-05-09 11:52:35 -0400 | |
---|---|---|
committer | 2017-05-09 17:46:29 +0000 | |
commit | 6dfcecad33c949e775a3fd0a58637721ab5e295e (patch) | |
tree | 79c46a7a355ff9fd7ebc91dd4423e56a055c208f /src | |
parent | 2a55c8ef495b5fd501a3dee7c199c9064ab7e6bc (diff) |
Make SkColorFilter::appendStages() not fail.
This makes SkColorFilter::appendStages() first try onAppendStages(),
and if it's unimplemented or fails, fall back to filterSpan4f().
This also makes onAppendStages() private to try to ensure that
appendStages() is now its only caller, ensuring everyone goes
through this fallback path.
The fallback uses the color filter transformed into the dst colorspace
using our new SkColorSpaceXformer... that seem ok Matt?
Change-Id: I4751a6859596fa4f7e844e69ef0d986f005b52c7
Reviewed-on: https://skia-review.googlesource.com/16031
Reviewed-by: Mike Reed <reed@google.com>
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkColorFilter.cpp | 31 | ||||
-rw-r--r-- | src/core/SkRasterPipelineBlitter.cpp | 4 | ||||
-rw-r--r-- | src/effects/SkColorMatrixFilter.cpp | 3 |
3 files changed, 28 insertions, 10 deletions
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp index 6dcee068ea..07e97919f5 100644 --- a/src/core/SkColorFilter.cpp +++ b/src/core/SkColorFilter.cpp @@ -10,12 +10,14 @@ #include "SkColorSpaceXformer.h" #include "SkNx.h" #include "SkPM4f.h" +#include "SkRasterPipeline.h" #include "SkReadBuffer.h" #include "SkRefCnt.h" #include "SkString.h" #include "SkTDArray.h" #include "SkUnPreMultiply.h" #include "SkWriteBuffer.h" +#include "../jumper/SkJumper.h" #if SK_SUPPORT_GPU #include "GrFragmentProcessor.h" @@ -39,11 +41,27 @@ sk_sp<GrFragmentProcessor> SkColorFilter::asFragmentProcessor(GrContext*, SkColo } #endif -bool SkColorFilter::appendStages(SkRasterPipeline* pipeline, - SkColorSpace* dst, - SkArenaAlloc* scratch, +void SkColorFilter::appendStages(SkRasterPipeline* p, + SkColorSpace* dstCS, + SkArenaAlloc* alloc, bool shaderIsOpaque) const { - return this->onAppendStages(pipeline, dst, scratch, shaderIsOpaque); + SkRasterPipeline subclass; + if (this->onAppendStages(&subclass, dstCS, alloc, shaderIsOpaque)) { + p->extend(subclass); + return; + } + + struct Ctx : SkJumper_CallbackCtx { + sk_sp<SkColorFilter> cf; + }; + auto ctx = alloc->make<Ctx>(); + ctx->cf = SkColorSpaceXformer::Make(sk_ref_sp(dstCS))->apply(this); + ctx->fn = [](SkJumper_CallbackCtx* arg, int active_pixels) { + auto ctx = (Ctx*)arg; + auto buf = (SkPM4f*)ctx->rgba; + ctx->cf->filterSpan4f(buf, active_pixels, buf); + }; + p->append(SkRasterPipeline::callback, ctx); } bool SkColorFilter::onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool) const { @@ -108,8 +126,9 @@ public: if (!(fInner->getFlags() & kAlphaUnchanged_Flag)) { innerIsOpaque = false; } - return fInner->appendStages(p, dst, scratch, shaderIsOpaque) && - fOuter->appendStages(p, dst, scratch, innerIsOpaque); + fInner->appendStages(p, dst, scratch, shaderIsOpaque); + fOuter->appendStages(p, dst, scratch, innerIsOpaque); + return true; } #if SK_SUPPORT_GPU diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp index 9b882c2ca1..badd83d73c 100644 --- a/src/core/SkRasterPipelineBlitter.cpp +++ b/src/core/SkRasterPipelineBlitter.cpp @@ -125,9 +125,7 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst, } if (colorFilter) { - if (!colorFilter->appendStages(pipeline, dst.colorSpace(), alloc, is_opaque)) { - return nullptr; - } + colorFilter->appendStages(pipeline, dst.colorSpace(), alloc, is_opaque); is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); } diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp index 52bf71eb70..ebd806e3c0 100644 --- a/src/effects/SkColorMatrixFilter.cpp +++ b/src/effects/SkColorMatrixFilter.cpp @@ -58,7 +58,8 @@ public: } bool onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkArenaAlloc* alloc, bool shaderIsOpaque) const override { - return fMatrixFilter->appendStages(p, cs, alloc, shaderIsOpaque); + fMatrixFilter->appendStages(p, cs, alloc, shaderIsOpaque); + return true; } // TODO: might want to remember we're a lighting color filter through serialization? |