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>
This commit is contained in:
parent
2a55c8ef49
commit
6dfcecad33
@ -74,8 +74,7 @@ public:
|
|||||||
|
|
||||||
virtual void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const = 0;
|
virtual void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const = 0;
|
||||||
|
|
||||||
bool appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
|
void appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool shaderIsOpaque) const;
|
||||||
bool shaderIsOpaque) const;
|
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
/** If set the filter methods will not change the alpha channel of the colors.
|
/** If set the filter methods will not change the alpha channel of the colors.
|
||||||
@ -161,9 +160,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
SkColorFilter() {}
|
SkColorFilter() {}
|
||||||
|
|
||||||
virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
|
|
||||||
bool shaderIsOpaque) const;
|
|
||||||
|
|
||||||
sk_sp<SkColorFilter> makeColorSpace(SkColorSpaceXformer* xformer) const {
|
sk_sp<SkColorFilter> makeColorSpace(SkColorSpaceXformer* xformer) const {
|
||||||
return this->onMakeColorSpace(xformer);
|
return this->onMakeColorSpace(xformer);
|
||||||
}
|
}
|
||||||
@ -189,6 +185,10 @@ private:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
|
||||||
|
bool shaderIsOpaque) const;
|
||||||
|
|
||||||
|
|
||||||
friend class SkColorSpaceXformer;
|
friend class SkColorSpaceXformer;
|
||||||
friend class SkComposeColorFilter;
|
friend class SkComposeColorFilter;
|
||||||
|
|
||||||
|
@ -10,12 +10,14 @@
|
|||||||
#include "SkColorSpaceXformer.h"
|
#include "SkColorSpaceXformer.h"
|
||||||
#include "SkNx.h"
|
#include "SkNx.h"
|
||||||
#include "SkPM4f.h"
|
#include "SkPM4f.h"
|
||||||
|
#include "SkRasterPipeline.h"
|
||||||
#include "SkReadBuffer.h"
|
#include "SkReadBuffer.h"
|
||||||
#include "SkRefCnt.h"
|
#include "SkRefCnt.h"
|
||||||
#include "SkString.h"
|
#include "SkString.h"
|
||||||
#include "SkTDArray.h"
|
#include "SkTDArray.h"
|
||||||
#include "SkUnPreMultiply.h"
|
#include "SkUnPreMultiply.h"
|
||||||
#include "SkWriteBuffer.h"
|
#include "SkWriteBuffer.h"
|
||||||
|
#include "../jumper/SkJumper.h"
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
#include "GrFragmentProcessor.h"
|
#include "GrFragmentProcessor.h"
|
||||||
@ -39,11 +41,27 @@ sk_sp<GrFragmentProcessor> SkColorFilter::asFragmentProcessor(GrContext*, SkColo
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool SkColorFilter::appendStages(SkRasterPipeline* pipeline,
|
void SkColorFilter::appendStages(SkRasterPipeline* p,
|
||||||
SkColorSpace* dst,
|
SkColorSpace* dstCS,
|
||||||
SkArenaAlloc* scratch,
|
SkArenaAlloc* alloc,
|
||||||
bool shaderIsOpaque) const {
|
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 {
|
bool SkColorFilter::onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool) const {
|
||||||
@ -108,8 +126,9 @@ public:
|
|||||||
if (!(fInner->getFlags() & kAlphaUnchanged_Flag)) {
|
if (!(fInner->getFlags() & kAlphaUnchanged_Flag)) {
|
||||||
innerIsOpaque = false;
|
innerIsOpaque = false;
|
||||||
}
|
}
|
||||||
return fInner->appendStages(p, dst, scratch, shaderIsOpaque) &&
|
fInner->appendStages(p, dst, scratch, shaderIsOpaque);
|
||||||
fOuter->appendStages(p, dst, scratch, innerIsOpaque);
|
fOuter->appendStages(p, dst, scratch, innerIsOpaque);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
|
@ -125,9 +125,7 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (colorFilter) {
|
if (colorFilter) {
|
||||||
if (!colorFilter->appendStages(pipeline, dst.colorSpace(), alloc, is_opaque)) {
|
colorFilter->appendStages(pipeline, dst.colorSpace(), alloc, is_opaque);
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
|
is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ public:
|
|||||||
}
|
}
|
||||||
bool onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkArenaAlloc* alloc,
|
bool onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkArenaAlloc* alloc,
|
||||||
bool shaderIsOpaque) const override {
|
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?
|
// TODO: might want to remember we're a lighting color filter through serialization?
|
||||||
|
Loading…
Reference in New Issue
Block a user