diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h index 5845573c42..16375499e5 100644 --- a/include/core/SkColorFilter.h +++ b/include/core/SkColorFilter.h @@ -74,8 +74,7 @@ public: virtual void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const = 0; - bool appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, - bool shaderIsOpaque) const; + void appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool shaderIsOpaque) const; enum Flags { /** If set the filter methods will not change the alpha channel of the colors. @@ -161,9 +160,6 @@ public: protected: SkColorFilter() {} - virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, - bool shaderIsOpaque) const; - sk_sp makeColorSpace(SkColorSpaceXformer* xformer) const { return this->onMakeColorSpace(xformer); } @@ -189,6 +185,10 @@ private: return false; } + virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, + bool shaderIsOpaque) const; + + friend class SkColorSpaceXformer; friend class SkComposeColorFilter; 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 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 cf; + }; + auto ctx = alloc->make(); + 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?