| 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;
|
| }
|
|
|