diff options
author | Mike Reed <reed@google.com> | 2017-06-02 13:25:15 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-06-02 17:51:24 +0000 |
commit | 6867eee44d33948c900f7b00444a303f6a5a09c2 (patch) | |
tree | a0fd5e83989e224945eb0c55df79c2accaa69728 /src/shaders | |
parent | 3ea1798829df1a5d163b1851783046b624c29ea2 (diff) |
default impl of appendStages now calls shaderContext
this is approximately a revert of https://skia-review.googlesource.com/c/17768/
I propose if/when we want to experiment with a fast-path for coherent shaders
(e.g. 2-color linear gradients, up-scaling images) that we just create a new
mechanism for shaders to opt into that, knowing that it will be driven by
the rasterpipeline (and never by the old context convention).
This CL now makes it legal/clear that a new shader subclass can *just* implement
stages for raster, and never needs to make a context.
Bug: skia:
Change-Id: I525a8b1cece100f0993f75e28128e0927a4ea35c
Reviewed-on: https://skia-review.googlesource.com/18481
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src/shaders')
-rw-r--r-- | src/shaders/SkEmptyShader.h | 5 | ||||
-rw-r--r-- | src/shaders/SkShader.cpp | 30 | ||||
-rw-r--r-- | src/shaders/SkShaderBase.h | 2 | ||||
-rw-r--r-- | src/shaders/gradients/SkGradientShader.cpp | 2 |
4 files changed, 38 insertions, 1 deletions
diff --git a/src/shaders/SkEmptyShader.h b/src/shaders/SkEmptyShader.h index d7187c4edf..d4809e09d3 100644 --- a/src/shaders/SkEmptyShader.h +++ b/src/shaders/SkEmptyShader.h @@ -34,6 +34,11 @@ protected: // which will write data we don't care to serialize or decode. } + bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, const SkMatrix&, + const SkPaint&, const SkMatrix*) const override { + return false; + } + private: typedef SkShaderBase INHERITED; }; diff --git a/src/shaders/SkShader.cpp b/src/shaders/SkShader.cpp index d04fbfe4df..d7587604af 100644 --- a/src/shaders/SkShader.cpp +++ b/src/shaders/SkShader.cpp @@ -283,6 +283,36 @@ bool SkShaderBase::onAppendStages(SkRasterPipeline* p, const SkMatrix& ctm, const SkPaint& paint, const SkMatrix* localM) const { + // SkShader::Context::shadeSpan4f() handles the paint opacity internally, + // but SkRasterPipelineBlitter applies it as a separate stage. + // We skip the internal shadeSpan4f() step by forcing the paint opaque. + SkTCopyOnFirstWrite<SkPaint> opaquePaint(paint); + if (paint.getAlpha() != SK_AlphaOPAQUE) { + opaquePaint.writable()->setAlpha(SK_AlphaOPAQUE); + } + + ContextRec rec(*opaquePaint, ctm, localM, ContextRec::kPM4f_DstType, dstCS); + + struct CallbackCtx : SkJumper_CallbackCtx { + sk_sp<SkShader> shader; + Context* ctx; + }; + auto cb = alloc->make<CallbackCtx>(); + cb->shader = dstCS ? SkColorSpaceXformer::Make(sk_ref_sp(dstCS))->apply(this) + : sk_ref_sp((SkShader*)this); + cb->ctx = as_SB(cb->shader)->makeContext(rec, alloc); + cb->fn = [](SkJumper_CallbackCtx* self, int active_pixels) { + auto c = (CallbackCtx*)self; + int x = (int)c->rgba[0], + y = (int)c->rgba[1]; + c->ctx->shadeSpan4f(x,y, (SkPM4f*)c->rgba, active_pixels); + }; + + if (cb->ctx) { + p->append(SkRasterPipeline::seed_shader); + p->append(SkRasterPipeline::callback, cb); + return true; + } return false; } diff --git a/src/shaders/SkShaderBase.h b/src/shaders/SkShaderBase.h index 94542321a3..ee8d5c02dc 100644 --- a/src/shaders/SkShaderBase.h +++ b/src/shaders/SkShaderBase.h @@ -204,6 +204,7 @@ public: virtual bool isRasterPipelineOnly() const { return false; } + // If this returns false, then we draw nothing (do not fall back to shader context) bool appendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*, const SkMatrix& ctm, const SkPaint&, const SkMatrix* localM=nullptr) const; @@ -247,6 +248,7 @@ protected: return sk_ref_sp(const_cast<SkShaderBase*>(this)); } + // Default impl creates shadercontext and calls that (not very efficient) virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*, const SkMatrix&, const SkPaint&, const SkMatrix* localM) const; diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp index d98c8c6c7e..a34a35acb2 100644 --- a/src/shaders/gradients/SkGradientShader.cpp +++ b/src/shaders/gradients/SkGradientShader.cpp @@ -419,7 +419,7 @@ bool SkGradientShaderBase::onAppendStages(SkRasterPipeline* p, SkRasterPipeline_<256> subclass; if (!this->adjustMatrixAndAppendStages(alloc, &matrix, &subclass)) { - return false; + return this->INHERITED::onAppendStages(p, dstCS, alloc, ctm, paint, localM); } p->append(SkRasterPipeline::seed_shader); |