Index: src/core/SkRasterPipelineBlitter.cpp |
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp |
index 31c188e4f9afab98d53dad21ceae8162d3880876..8f9922d47e557b1e1f0e04e85969930067c7a6f9 100644 |
--- a/src/core/SkRasterPipelineBlitter.cpp |
+++ b/src/core/SkRasterPipelineBlitter.cpp |
@@ -20,12 +20,8 @@ class SkRasterPipelineBlitter : public SkBlitter { |
public: |
static SkBlitter* Create(const SkPixmap&, const SkPaint&, SkTBlitterAllocator*); |
- SkRasterPipelineBlitter(SkPixmap dst, |
- SkRasterPipeline shader, |
- SkBlendMode blend, |
- SkPM4f paintColor) |
+ SkRasterPipelineBlitter(SkPixmap dst, SkBlendMode blend, SkPM4f paintColor) |
: fDst(dst) |
- , fShader(shader) |
, fBlend(blend) |
, fPaintColor(paintColor) |
{} |
@@ -45,9 +41,9 @@ private: |
void maybe_clamp (SkRasterPipeline*) const; |
SkPixmap fDst; |
- SkRasterPipeline fShader; |
SkBlendMode fBlend; |
SkPM4f fPaintColor; |
+ SkRasterPipeline fShader; |
// These functions are compiled lazily when first used. |
std::function<void(size_t, size_t)> fBlitH = nullptr, |
@@ -84,52 +80,69 @@ static bool append_effect_stages(const Effect* effect, SkRasterPipeline* pipelin |
return !effect || effect->appendStages(pipeline); |
} |
+static SkPM4f paint_color(const SkPixmap& dst, const SkPaint& paint) { |
+ auto paintColor = paint.getColor(); |
+ SkColor4f color; |
+ if (dst.info().colorSpace()) { |
+ color = SkColor4f::FromColor(paintColor); |
+ // TODO: transform from sRGB to dst gamut. |
+ } else { |
+ swizzle_rb(SkNx_cast<float>(Sk4b::Load(&paintColor)) * (1/255.0f)).store(&color); |
+ } |
+ return color.premul(); |
+} |
SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst, |
const SkPaint& paint, |
SkTBlitterAllocator* alloc) { |
- if (!supported(dst.info())) { |
+ auto blitter = alloc->createT<SkRasterPipelineBlitter>(dst, |
+ paint.getBlendMode(), |
+ paint_color(dst, paint)); |
+ SkBlendMode* blend = &blitter->fBlend; |
+ SkPM4f* paintColor = &blitter->fPaintColor; |
+ SkRasterPipeline* pipeline = &blitter->fShader; |
+ |
+ SkShader* shader = paint.getShader(); |
+ SkColorFilter* colorFilter = paint.getColorFilter(); |
+ |
+ // TODO: all temporary |
+ if (!supported(dst.info()) || shader || !SkBlendMode_AppendStages(*blend)) { |
+ alloc->freeLast(); |
return nullptr; |
} |
- 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 |
- } |
- uint32_t paintColor = paint.getColor(); |
- bool shaderIsOpaque = (paintColor >> 24) == 0xff; |
- |
- SkRasterPipeline shader, colorFilter; |
- if (auto s = paint.getShader()) { |
- shaderIsOpaque = s->isOpaque(); |
+ bool is_opaque, is_constant; |
+ if (shader) { |
+ is_opaque = shader->isOpaque(); |
+ is_constant = false; // TODO: shader->isConstant() |
+ // TODO: append shader stages, of course! |
+ } else { |
+ is_opaque = paintColor->a() == 1.0f; |
+ is_constant = true; |
+ pipeline->append(SkRasterPipeline::constant_color, paintColor); |
} |
- if (auto cf = paint.getColorFilter()) { |
- if (!cf->appendStages(&colorFilter, shaderIsOpaque)) { |
+ |
+ if (colorFilter) { |
+ if (!colorFilter->appendStages(pipeline, is_opaque)) { |
+ alloc->freeLast(); |
return nullptr; |
} |
- shaderIsOpaque = shaderIsOpaque && (cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); |
+ is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); |
} |
- if (shaderIsOpaque && blend == SkBlendMode::kSrcOver) { |
- blend = SkBlendMode::kSrc; |
- } |
+ if (is_constant) { |
+ pipeline->append(SkRasterPipeline::store_f32, &paintColor); |
+ pipeline->compile()(0,1); |
- SkColor4f color; |
- if (dst.info().colorSpace()) { |
- color = SkColor4f::FromColor(paintColor); |
- } else { |
- swizzle_rb(SkNx_cast<float>(Sk4b::Load(&paintColor)) * (1/255.0f)).store(&color); |
- } |
+ *pipeline = SkRasterPipeline(); |
+ pipeline->append(SkRasterPipeline::constant_color, paintColor); |
- auto blitter = alloc->createT<SkRasterPipelineBlitter>(dst, shader, blend, color.premul()); |
+ is_opaque = paintColor->a() == 1.0f; |
+ } |
- if (!paint.getShader()) { |
- blitter->fShader.append(SkRasterPipeline::constant_color, &blitter->fPaintColor); |
+ if (is_opaque && *blend == SkBlendMode::kSrcOver) { |
+ *blend = SkBlendMode::kSrc; |
} |
- blitter->fShader.extend(colorFilter); |
return blitter; |
} |