SkRasterPipelineBlitter simplifications
The main idea here is to simplify, mainly to reduce the number of SkRasterPipeline objects the blitter holds.
- Use SkBlendMode instead of SkXfermode, just store SkBlendMode.
- Fuse the shader and color filter together into one SkRasterPipeline
during blitter creation.
- I noticed all calls to append_load_d() and append_store() now have the same ctx argument, so I folded that through.
I'll be following up with more of this sort of refactoring... I think I can fold everything into a single SkRasterPipeline during blitter creation now, but I'll want to make sure I've got my ducks in a row for how that works with pipeline strength reduction (like skipping dst loads when drawing in Src mode).
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4021
Change-Id: I88252ab8ad16f102c71bad871f8b6aec2fc1f226
Reviewed-on: https://skia-review.googlesource.com/4021
Reviewed-by: Herb Derby <herb@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index 51c2fc1..daf34a2 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -6,6 +6,7 @@
*/
#include "SkBlitter.h"
+#include "SkBlendModePriv.h"
#include "SkColor.h"
#include "SkColorFilter.h"
#include "SkOpts.h"
@@ -21,13 +22,11 @@
SkRasterPipelineBlitter(SkPixmap dst,
SkRasterPipeline shader,
- SkRasterPipeline colorFilter,
- SkRasterPipeline xfermode,
+ SkBlendMode blend,
SkPM4f paintColor)
: fDst(dst)
, fShader(shader)
- , fColorFilter(colorFilter)
- , fXfermode(xfermode)
+ , fBlend(blend)
, fPaintColor(paintColor)
{}
@@ -40,11 +39,13 @@
// blits using something like a SkRasterPipeline::runFew() method.
private:
- void append_load_d(SkRasterPipeline*, const void*) const;
- void append_store (SkRasterPipeline*, void*) const;
+ void append_load_d(SkRasterPipeline*) const;
+ void append_store (SkRasterPipeline*) const;
+ void append_blend (SkRasterPipeline*) const;
SkPixmap fDst;
- SkRasterPipeline fShader, fColorFilter, fXfermode;
+ SkRasterPipeline fShader;
+ SkBlendMode fBlend;
SkPM4f fPaintColor;
// These functions are compiled lazily when first used.
@@ -92,10 +93,13 @@
if (paint.getShader()) {
return nullptr; // TODO: need to work out how shaders and their contexts work
}
+ SkBlendMode blend = paint.getBlendMode();
+ if (!SkBlendMode_AppendStages(blend)) {
+ return nullptr; // TODO
+ }
- SkRasterPipeline shader, colorFilter, xfermode;
- if (!append_effect_stages(paint.getColorFilter(), &colorFilter) ||
- !append_effect_stages(SkXfermode::Peek(paint.getBlendMode()), &xfermode )) {
+ SkRasterPipeline shader, colorFilter;
+ if (paint.getColorFilter() && !paint.getColorFilter()->appendStages(&colorFilter)) {
return nullptr;
}
@@ -108,69 +112,65 @@
swizzle_rb(SkNx_cast<float>(Sk4b::Load(&paintColor)) * (1/255.0f)).store(&color);
}
- auto blitter = alloc->createT<SkRasterPipelineBlitter>(
- dst,
- shader, colorFilter, xfermode,
- color.premul());
+ auto blitter = alloc->createT<SkRasterPipelineBlitter>(dst, shader, blend, color.premul());
if (!paint.getShader()) {
blitter->fShader.append(SkRasterPipeline::constant_color, &blitter->fPaintColor);
}
- if (paint.isSrcOver()) {
- blitter->fXfermode.append(SkRasterPipeline::srcover);
- }
+ blitter->fShader.extend(colorFilter);
return blitter;
}
-void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p, const void* dst) const {
+void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p) const {
SkASSERT(supported(fDst.info()));
switch (fDst.info().colorType()) {
case kN32_SkColorType:
if (fDst.info().gammaCloseToSRGB()) {
- p->append(SkRasterPipeline::load_d_srgb, dst);
+ p->append(SkRasterPipeline::load_d_srgb, &fDstPtr);
}
break;
case kRGBA_F16_SkColorType:
- p->append(SkRasterPipeline::load_d_f16, dst);
+ p->append(SkRasterPipeline::load_d_f16, &fDstPtr);
break;
case kRGB_565_SkColorType:
- p->append(SkRasterPipeline::load_d_565, dst);
+ p->append(SkRasterPipeline::load_d_565, &fDstPtr);
break;
default: break;
}
}
-void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p, void* dst) const {
+void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p) const {
SkASSERT(supported(fDst.info()));
switch (fDst.info().colorType()) {
case kN32_SkColorType:
if (fDst.info().gammaCloseToSRGB()) {
- p->append(SkRasterPipeline::store_srgb, dst);
+ p->append(SkRasterPipeline::store_srgb, &fDstPtr);
}
break;
case kRGBA_F16_SkColorType:
- p->append(SkRasterPipeline::store_f16, dst);
+ p->append(SkRasterPipeline::store_f16, &fDstPtr);
break;
case kRGB_565_SkColorType:
- p->append(SkRasterPipeline::store_565, dst);
+ p->append(SkRasterPipeline::store_565, &fDstPtr);
break;
default: break;
}
}
-// TODO: Figure out how to cache some of the compiled pipelines.
+void SkRasterPipelineBlitter::append_blend(SkRasterPipeline* p) const {
+ SkAssertResult(SkBlendMode_AppendStages(fBlend, p));
+}
void SkRasterPipelineBlitter::blitH(int x, int y, int w) {
if (!fBlitH) {
SkRasterPipeline p;
p.extend(fShader);
- p.extend(fColorFilter);
- this->append_load_d(&p, &fDstPtr);
- p.extend(fXfermode);
- this->append_store(&p, &fDstPtr);
+ this->append_load_d(&p);
+ this->append_blend(&p);
+ this->append_store(&p);
fBlitH = p.compile();
}
@@ -182,11 +182,10 @@
if (!fBlitAntiH) {
SkRasterPipeline p;
p.extend(fShader);
- p.extend(fColorFilter);
- this->append_load_d(&p, &fDstPtr);
- p.extend(fXfermode);
+ this->append_load_d(&p);
+ this->append_blend(&p);
p.append(SkRasterPipeline::lerp_constant_float, &fConstantCoverage);
- this->append_store(&p, &fDstPtr);
+ this->append_store(&p);
fBlitAntiH = p.compile();
}
@@ -210,22 +209,20 @@
if (mask.fFormat == SkMask::kA8_Format && !fBlitMaskA8) {
SkRasterPipeline p;
p.extend(fShader);
- p.extend(fColorFilter);
- this->append_load_d(&p, &fDstPtr);
- p.extend(fXfermode);
+ this->append_load_d(&p);
+ this->append_blend(&p);
p.append(SkRasterPipeline::lerp_u8, &fMaskPtr);
- this->append_store(&p, &fDstPtr);
+ this->append_store(&p);
fBlitMaskA8 = p.compile();
}
if (mask.fFormat == SkMask::kLCD16_Format && !fBlitMaskLCD16) {
SkRasterPipeline p;
p.extend(fShader);
- p.extend(fColorFilter);
- this->append_load_d(&p, &fDstPtr);
- p.extend(fXfermode);
+ this->append_load_d(&p);
+ this->append_blend(&p);
p.append(SkRasterPipeline::lerp_565, &fMaskPtr);
- this->append_store(&p, &fDstPtr);
+ this->append_store(&p);
fBlitMaskLCD16 = p.compile();
}