stage version of vertices
This CL, just to limit its size/complexity, only handles
colors but not textures. Future CLs will cover everything.
Performance is pretty exciting. Its faster than the old code-path,
and when we fix a bug in pathutils to preserve opaqueness, it gets
a lot faster (8 -> 5)
Bug: skia:
Change-Id: I4113060e25fe25fe4e6a0ea59bd4fa5e33abc668
Reviewed-on: https://skia-review.googlesource.com/17276
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Florin Malita <fmalita@chromium.org>
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index 363324b..b62b43f 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -22,6 +22,10 @@
public:
static SkBlitter* Create(const SkPixmap&, const SkPaint&, const SkMatrix& ctm,
SkArenaAlloc*);
+ static SkBlitter* Create(const SkPixmap&, const SkPaint&, const SkMatrix& ctm,
+ const SkRasterPipeline& shaderPipeline,
+ bool is_opaque, bool wants_dither,
+ SkArenaAlloc*);
SkRasterPipelineBlitter(SkPixmap dst, SkBlendMode blend, SkPM4f paintColor)
: fDst(dst)
@@ -38,6 +42,9 @@
// blits using something like a SkRasterPipeline::runFew() method.
private:
+ void finishBuilding(const SkPaint& paint, const SkMatrix& ctm, bool is_oapque,
+ bool is_constant, bool wants_dither, SkArenaAlloc* alloc);
+
void append_load_d(SkRasterPipeline*) const;
void append_blend (SkRasterPipeline*) const;
void maybe_clamp (SkRasterPipeline*) const;
@@ -85,48 +92,100 @@
paint.getBlendMode(),
SkPM4f_from_SkColor(paint.getColor(), dst.colorSpace()));
-
- SkBlendMode* blend = &blitter->fBlend;
SkPM4f* paintColor = &blitter->fPaintColor;
SkRasterPipeline* pipeline = &blitter->fShader;
+ SkShader* shader = paint.getShader();
- SkShader* shader = paint.getShader();
- SkColorFilter* colorFilter = paint.getColorFilter();
+ bool is_opaque = paintColor->a() == 1.0f,
+ is_constant = true,
+ wants_dither = false;
- // TODO: Think more about under what conditions we dither:
- // - if we're drawing anything into 565 and the user has asked us to dither, or
- // - if we're drawing a gradient into 565 or 8888.
- if ((paint.isDither() && dst.info().colorType() == kRGB_565_SkColorType) ||
- (shader && shader->asAGradient(nullptr) >= SkShader::kLinear_GradientType)) {
- switch (dst.info().colorType()) {
- default: blitter->fDitherCtx.rate = 0.0f; break;
- case kRGB_565_SkColorType: blitter->fDitherCtx.rate = 1/63.0f; break;
- case kRGBA_8888_SkColorType:
- case kBGRA_8888_SkColorType: blitter->fDitherCtx.rate = 1/255.0f; break;
- }
- }
-
- bool is_opaque = paintColor->a() == 1.0f,
- is_constant = blitter->fDitherCtx.rate == 0.0f;
if (shader) {
pipeline->append(SkRasterPipeline::seed_shader, &blitter->fCurrentY);
if (!shader->appendStages(pipeline, dst.colorSpace(), alloc, ctm, paint)) {
// When a shader fails to append stages, it means it has vetoed drawing entirely.
return alloc->make<SkNullBlitter>();
}
- if (!is_opaque) {
- pipeline->append(SkRasterPipeline::scale_1_float,
- &paintColor->fVec[SkPM4f::A]);
- }
- is_opaque = is_opaque && shader->isOpaque();
- is_constant = is_constant && shader->isConstant();
+ if (!is_opaque) {
+ pipeline->append(SkRasterPipeline::scale_1_float, &paintColor->fVec[SkPM4f::A]);
+ }
+ is_opaque = is_opaque && shader->isOpaque();
+ is_constant = shader->isConstant();
+ wants_dither = shader->asAGradient(nullptr) >= SkShader::kLinear_GradientType;
+
} else {
pipeline->append(SkRasterPipeline::constant_color, paintColor);
}
+ blitter->finishBuilding(paint, ctm, is_opaque, is_constant, wants_dither, alloc);
+ return blitter;
+}
+
+SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
+ const SkPaint& paint,
+ const SkMatrix& ctm,
+ const SkRasterPipeline& shaderPipeline,
+ bool is_opaque, bool wants_dither,
+ SkArenaAlloc* alloc) {
+ return SkRasterPipelineBlitter::Create(dst, paint, ctm, shaderPipeline,
+ is_opaque, wants_dither, alloc);
+}
+
+SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
+ const SkPaint& paint,
+ const SkMatrix& ctm,
+ const SkRasterPipeline& shaderPipeline,
+ bool is_opaque, bool wants_dither,
+ SkArenaAlloc* alloc) {
+ auto blitter = alloc->make<SkRasterPipelineBlitter>(
+ dst,
+ paint.getBlendMode(),
+ SkPM4f_from_SkColor(paint.getColor(), dst.colorSpace()));
+
+ bool is_constant = false; // we figure a custom shaderPipeline is never constant
+ SkPM4f* paintColor = &blitter->fPaintColor;
+ SkRasterPipeline* pipeline = &blitter->fShader;
+
+ pipeline->append(SkRasterPipeline::seed_shader, &blitter->fCurrentY);
+ pipeline->extend(shaderPipeline);
+
+ if (paintColor->a() != 1.0f) {
+ pipeline->append(SkRasterPipeline::scale_1_float, &paintColor->fVec[SkPM4f::A]);
+ is_opaque = false;
+ }
+
+ blitter->finishBuilding(paint, ctm, is_opaque, is_constant, wants_dither, alloc);
+ return blitter;
+}
+
+void SkRasterPipelineBlitter::finishBuilding(const SkPaint& paint, const SkMatrix& ctm,
+ bool is_opaque, bool is_constant, bool wants_dither,
+ SkArenaAlloc* alloc) {
+ SkBlendMode* blend = &fBlend;
+ SkPM4f* paintColor = &fPaintColor;
+ SkRasterPipeline* pipeline = &fShader;
+ SkColorFilter* colorFilter = paint.getColorFilter();
+
+ SkASSERT(fDitherCtx.rate == 0);
+ if ((paint.isDither() && fDst.info().colorType() == kRGB_565_SkColorType) || wants_dither) {
+ switch (fDst.info().colorType()) {
+ case kRGB_565_SkColorType:
+ fDitherCtx.rate = 1/63.0f;
+ is_constant = false;
+ break;
+ case kRGBA_8888_SkColorType:
+ case kBGRA_8888_SkColorType:
+ fDitherCtx.rate = 1/255.0f;
+ is_constant = false;
+ break;
+ default:
+ break;
+ }
+ }
+
if (colorFilter) {
- colorFilter->appendStages(pipeline, dst.colorSpace(), alloc, is_opaque);
+ colorFilter->appendStages(pipeline, fDst.colorSpace(), alloc, is_opaque);
is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
}
@@ -147,14 +206,12 @@
if (is_constant && *blend == SkBlendMode::kSrc) {
SkRasterPipeline p;
p.extend(*pipeline);
- blitter->fDstPtr = &blitter->fMemsetColor;
- blitter->append_store(&p);
+ fDstPtr = &fMemsetColor;
+ this->append_store(&p);
p.run(0,1);
- blitter->fCanMemsetInBlitH = true;
+ fCanMemsetInBlitH = true;
}
-
- return blitter;
}
void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p) const {