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>
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index 2925fe3..3d60d75 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -25,17 +25,14 @@
// This is our common entrypoint for creating the blitter once we've sorted out shaders.
static SkBlitter* Create(const SkPixmap&, const SkPaint&, SkArenaAlloc*,
const SkRasterPipeline& shaderPipeline,
- SkShaderBase::Context* shaderCtx,
bool is_opaque, bool is_constant, bool wants_dither);
SkRasterPipelineBlitter(SkPixmap dst,
SkBlendMode blend,
- SkArenaAlloc* alloc,
- SkShaderBase::Context* shaderCtx)
+ SkArenaAlloc* alloc)
: fDst(dst)
, fBlend(blend)
, fAlloc(alloc)
- , fShaderCtx(shaderCtx)
, fColorPipeline(alloc)
{}
@@ -53,13 +50,9 @@
void maybe_clamp (SkRasterPipeline*) const;
void append_store (SkRasterPipeline*) const;
- // If we have an SkShader::Context, use it to fill our shader buffer.
- void maybe_shade(int x, int y, int w);
-
SkPixmap fDst;
SkBlendMode fBlend;
SkArenaAlloc* fAlloc;
- SkShaderBase::Context* fShaderCtx;
SkRasterPipeline fColorPipeline;
// We may be able to specialize blitH() into a memset.
@@ -74,14 +67,11 @@
// These values are pointed to by the blit pipelines above,
// which allows us to adjust them from call to call.
- void* fShaderOutput = nullptr;
void* fDstPtr = nullptr;
const void* fMaskPtr = nullptr;
float fCurrentCoverage = 0.0f;
float fDitherRate = 0.0f;
- std::vector<SkPM4f> fShaderBuffer;
-
typedef SkBlitter INHERITED;
};
@@ -105,42 +95,21 @@
bool is_opaque = paintColor->a() == 1.0f,
is_constant = true;
return SkRasterPipelineBlitter::Create(dst, paint, alloc,
- shaderPipeline, nullptr,
+ shaderPipeline,
is_opaque, is_constant, wants_dither);
}
bool is_opaque = shader->isOpaque() && paintColor->a() == 1.0f;
bool is_constant = shader->isConstant();
-
- // See if the shader can express itself by appending pipeline stages.
if (shader->appendStages(&shaderPipeline, dstCS, alloc, ctm, paint)) {
if (paintColor->a() != 1.0f) {
shaderPipeline.append(SkRasterPipeline::scale_1_float, &paintColor->fVec[SkPM4f::A]);
}
- return SkRasterPipelineBlitter::Create(dst, paint, alloc,
- shaderPipeline, nullptr,
+ return SkRasterPipelineBlitter::Create(dst, paint, alloc, shaderPipeline,
is_opaque, is_constant, wants_dither);
}
- // No, the shader wants us to create a context and call shadeSpan4f().
- SkASSERT(!is_constant); // All constant shaders should be able to appendStages().
-
- if (dstCS) {
- // We need to transform the shader into the dst color space, and extend its lifetime.
- sk_sp<SkShader> in_dstCS = SkColorSpaceXformer::Make(sk_ref_sp(dstCS))->apply(shader);
- shader = as_SB(in_dstCS.get());
- alloc->make<sk_sp<SkShader>>(std::move(in_dstCS));
- }
- SkShaderBase::ContextRec rec(paint, ctm, nullptr, SkShaderBase::ContextRec::kPM4f_DstType,
- dstCS);
- SkShaderBase::Context* shaderCtx = shader->makeContext(rec, alloc);
- if (!shaderCtx) {
- // When a shader fails to create a context, it has vetoed drawing entirely.
- return alloc->make<SkNullBlitter>();
- }
- return SkRasterPipelineBlitter::Create(dst, paint, alloc,
- shaderPipeline, shaderCtx,
- is_opaque, is_constant, wants_dither);
+ return alloc->make<SkNullBlitter>();
}
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
@@ -150,8 +119,7 @@
bool wants_dither,
SkArenaAlloc* alloc) {
bool is_constant = false; // If this were the case, it'd be better to just set a paint color.
- return SkRasterPipelineBlitter::Create(dst, paint, alloc,
- shaderPipeline, nullptr,
+ return SkRasterPipelineBlitter::Create(dst, paint, alloc, shaderPipeline,
is_opaque, is_constant, wants_dither);
}
@@ -159,14 +127,12 @@
const SkPaint& paint,
SkArenaAlloc* alloc,
const SkRasterPipeline& shaderPipeline,
- SkShaderBase::Context* shaderCtx,
bool is_opaque,
bool is_constant,
bool wants_dither) {
auto blitter = alloc->make<SkRasterPipelineBlitter>(dst,
paint.getBlendMode(),
- alloc,
- shaderCtx);
+ alloc);
// Our job in this factory is to fill out the blitter's color pipeline.
// This is the common front of the full blit pipelines, each constructed lazily on first use.
@@ -174,11 +140,7 @@
auto colorPipeline = &blitter->fColorPipeline;
// Let's get the shader in first.
- if (shaderCtx) {
- colorPipeline->append(SkRasterPipeline::load_f32, &blitter->fShaderOutput);
- } else {
- colorPipeline->extend(shaderPipeline);
- }
+ colorPipeline->extend(shaderPipeline);
// If there's a color filter it comes next.
if (auto colorFilter = paint.getColorFilter()) {
@@ -287,17 +249,6 @@
}
}
-void SkRasterPipelineBlitter::maybe_shade(int x, int y, int w) {
- if (fShaderCtx) {
- if (w > SkToInt(fShaderBuffer.size())) {
- fShaderBuffer.resize(w);
- }
- fShaderCtx->shadeSpan4f(x,y, fShaderBuffer.data(), w);
- // We'll be reading from fShaderOutput + x.
- fShaderOutput = fShaderBuffer.data() - x;
- }
-}
-
void SkRasterPipelineBlitter::blitH(int x, int y, int w) {
fDstPtr = fDst.writable_addr(0,y);
@@ -329,7 +280,6 @@
}
fBlitH = p.compile();
}
- this->maybe_shade(x,y,w);
fBlitH(x,y,w);
}
@@ -357,7 +307,6 @@
case 0x00: break;
case 0xff: this->blitH(x,y,run); break;
default:
- this->maybe_shade(x,y,run);
fCurrentCoverage = *aa * (1/255.0f);
fBlitAntiH(x,y,run);
}
@@ -405,7 +354,6 @@
for (int y = clip.top(); y < clip.bottom(); y++) {
fDstPtr = fDst.writable_addr(0,y);
- this->maybe_shade(x,y,clip.width());
switch (mask.fFormat) {
case SkMask::kA8_Format:
fMaskPtr = mask.getAddr8(x,y)-x;