aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/shaders
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-06-02 13:25:15 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-02 17:51:24 +0000
commit6867eee44d33948c900f7b00444a303f6a5a09c2 (patch)
treea0fd5e83989e224945eb0c55df79c2accaa69728 /src/shaders
parent3ea1798829df1a5d163b1851783046b624c29ea2 (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.h5
-rw-r--r--src/shaders/SkShader.cpp30
-rw-r--r--src/shaders/SkShaderBase.h2
-rw-r--r--src/shaders/gradients/SkGradientShader.cpp2
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);