/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "../jumper/SkJumper.h"
#include "SkArenaAlloc.h"
#include "SkBlendModePriv.h"
#include "SkBlitter.h"
#include "SkColor.h"
#include "SkColorFilter.h"
#include "SkColorSpacePriv.h"
#include "SkColorSpaceXformer.h"
#include "SkOpts.h"
#include "SkPM4f.h"
#include "SkPM4fPriv.h"
#include "SkRasterPipeline.h"
#include "SkShader.h"
#include "SkShaderBase.h"
#include "SkTo.h"
#include "SkUtils.h"

class SkRasterPipelineBlitter final : public SkBlitter {
public:
    // 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*,
                             bool is_opaque, bool is_constant);

    SkRasterPipelineBlitter(SkPixmap dst,
                            SkBlendMode blend,
                            SkArenaAlloc* alloc,
                            SkShaderBase::Context* burstCtx)
        : fDst(dst)
        , fBlend(blend)
        , fAlloc(alloc)
        , fBurstCtx(burstCtx)
        , fColorPipeline(alloc)
    {}

    void blitH     (int x, int y, int w)                            override;
    void blitAntiH (int x, int y, const SkAlpha[], const int16_t[]) override;
    void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1)               override;
    void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1)               override;
    void blitMask  (const SkMask&, const SkIRect& clip)             override;
    void blitRect  (int x, int y, int width, int height)            override;
    void blitV     (int x, int y, int height, SkAlpha alpha)        override;

private:
    void append_color_pipeline(SkRasterPipeline*) const;
    void append_load_dst      (SkRasterPipeline*) const;
    void append_store         (SkRasterPipeline*) const;

    // If we have an burst context, use it to fill our shader buffer.
    void burst_shade(int x, int y, int w);

    SkPixmap               fDst;
    SkBlendMode            fBlend;
    SkArenaAlloc*          fAlloc;
    SkShaderBase::Context* fBurstCtx;
    SkRasterPipeline       fColorPipeline;

    SkJumper_MemoryCtx fShaderOutput = {nullptr,0},  // Possibly updated each call to burst_shade().
                       fDstPtr       = {nullptr,0},  // Always points to the top-left of fDst.
                       fMaskPtr      = {nullptr,0};  // Updated each call to blitMask().

    // We may be able to specialize blitH() or blitRect() into a memset.
    bool     fCanMemsetInBlitRect = false;
    uint64_t fMemsetColor      = 0;     // Big enough for largest dst format, F16.

    // Built lazily on first use.
    std::function<void(size_t, size_t, size_t, size_t)> fBlitRect,
                                                        fBlitAntiH,
                                                        fBlitMaskA8,
                                                        fBlitMaskLCD16;

    // These values are pointed to by the blit pipelines above,
    // which allows us to adjust them from call to call.
    float fCurrentCoverage = 0.0f;
    float fDitherRate      = 0.0f;

    std::vector<SkPM4f> fShaderBuffer;

    typedef SkBlitter INHERITED;
};

SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
                                         const SkPaint& paint,
                                         const SkMatrix& ctm,
                                         SkArenaAlloc* alloc) {
    // For legacy/SkColorSpaceXformCanvas to keep working,
    // we need to sometimes still need to distinguish null dstCS from sRGB.
#if 0
    SkColorSpace* dstCS = dst.colorSpace() ? dst.colorSpace()
                                           : sk_srgb_singleton();
#else
    SkColorSpace* dstCS = dst.colorSpace();
#endif
    SkPM4f paintColor = premul_in_dst_colorspace(paint.getColor(), dstCS);

    auto shader = as_SB(paint.getShader());

    SkRasterPipeline_<256> shaderPipeline;
    if (!shader) {
        // Having no shader makes things nice and easy... just use the paint color.
        shaderPipeline.append_constant_color(alloc, paintColor);
        bool is_opaque    = paintColor.a() == 1.0f,
             is_constant  = true;
        return SkRasterPipelineBlitter::Create(dst, paint, alloc,
                                               shaderPipeline, nullptr,
                                               is_opaque, is_constant);
    }

    bool is_opaque    = shader->isOpaque() && paintColor.a() == 1.0f;
    bool is_constant  = shader->isConstant();

    // Check whether the shader prefers to run in burst mode.
    if (auto* burstCtx = shader->makeBurstPipelineContext(
        SkShaderBase::ContextRec(paint, ctm, nullptr, dstCS), alloc)) {
        return SkRasterPipelineBlitter::Create(dst, paint, alloc,
                                               shaderPipeline, burstCtx,
                                               is_opaque, is_constant);
    }

    if (shader->appendStages({&shaderPipeline, alloc, dstCS, paint, nullptr, ctm})) {
        if (paintColor.a() != 1.0f) {
            shaderPipeline.append(SkRasterPipeline::scale_1_float,
                                  alloc->make<float>(paintColor.a()));
        }
        return SkRasterPipelineBlitter::Create(dst, paint, alloc, shaderPipeline, nullptr,
                                               is_opaque, is_constant);
    }

    // The shader has opted out of drawing anything.
    return alloc->make<SkNullBlitter>();
}

SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
                                         const SkPaint& paint,
                                         const SkRasterPipeline& shaderPipeline,
                                         bool is_opaque,
                                         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,
                                           is_opaque, is_constant);
}

SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
                                           const SkPaint& paint,
                                           SkArenaAlloc* alloc,
                                           const SkRasterPipeline& shaderPipeline,
                                           SkShaderBase::Context* burstCtx,
                                           bool is_opaque,
                                           bool is_constant) {
    auto blitter = alloc->make<SkRasterPipelineBlitter>(dst,
                                                        paint.getBlendMode(),
                                                        alloc,
                                                        burstCtx);

    // 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.
    // The full blit pipelines handle reading and writing the dst, blending, coverage, dithering.
    auto colorPipeline = &blitter->fColorPipeline;

    // Let's get the shader in first.
    if (burstCtx) {
        colorPipeline->append(SkRasterPipeline::load_f32, &blitter->fShaderOutput);
    } else {
        colorPipeline->extend(shaderPipeline);
    }

    // If there's a color filter it comes next.
    if (auto colorFilter = paint.getColorFilter()) {
        colorFilter->appendStages(colorPipeline, dst.colorSpace(), alloc, is_opaque);
        is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
    }

    // Not all formats make sense to dither (think, F16).  We set their dither rate
    // to zero.  We need to decide if we're going to dither now to keep is_constant accurate.
    if (paint.isDither()) {
        switch (dst.info().colorType()) {
            default:                        blitter->fDitherRate =      0.0f; break;
            case kARGB_4444_SkColorType:    blitter->fDitherRate =   1/15.0f; break;
            case   kRGB_565_SkColorType:    blitter->fDitherRate =   1/63.0f; break;
            case    kGray_8_SkColorType:
            case  kRGB_888x_SkColorType:
            case kRGBA_8888_SkColorType:
            case kBGRA_8888_SkColorType:    blitter->fDitherRate =  1/255.0f; break;
            case kRGB_101010x_SkColorType:
            case kRGBA_1010102_SkColorType: blitter->fDitherRate = 1/1023.0f; break;
        }
        // TODO: for constant colors, we could try to measure the effect of dithering, and if
        //       it has no value (i.e. all variations result in the same 32bit color, then we
        //       could disable it (for speed, by not adding the stage).
    }
    is_constant = is_constant && (blitter->fDitherRate == 0.0f);

    // We're logically done here.  The code between here and return blitter is all optimization.

    // A pipeline that's still constant here can collapse back into a constant color.
    if (is_constant) {
        SkPM4f constantColor;
        SkJumper_MemoryCtx constantColorPtr = { &constantColor, 0 };
        colorPipeline->append(SkRasterPipeline::store_f32, &constantColorPtr);
        colorPipeline->run(0,0,1,1);
        colorPipeline->reset();
        colorPipeline->append_constant_color(alloc, constantColor);

        is_opaque = constantColor.a() == 1.0f;
    }

    // We can strength-reduce SrcOver into Src when opaque.
    if (is_opaque && blitter->fBlend == SkBlendMode::kSrcOver) {
        blitter->fBlend = SkBlendMode::kSrc;
    }

    // When we're drawing a constant color in Src mode, we can sometimes just memset.
    // (The previous two optimizations help find more opportunities for this one.)
    if (is_constant && blitter->fBlend == SkBlendMode::kSrc
                    && blitter->fDst.shiftPerPixel() <= 3 /*TODO: F32*/) {
        // Run our color pipeline all the way through to produce what we'd memset when we can.
        // Not all blits can memset, so we need to keep colorPipeline too.
        SkRasterPipeline_<256> p;
        p.extend(*colorPipeline);
        blitter->fDstPtr = SkJumper_MemoryCtx{&blitter->fMemsetColor, 0};
        blitter->append_store(&p);
        p.run(0,0,1,1);

        blitter->fCanMemsetInBlitRect = true;
    }

    blitter->fDstPtr = SkJumper_MemoryCtx{
        blitter->fDst.writable_addr(),
        blitter->fDst.rowBytesAsPixels(),
    };

    return blitter;
}

void SkRasterPipelineBlitter::append_color_pipeline(SkRasterPipeline* p) const {
    p->extend(fColorPipeline);

    // TODO: can we refine this condition further to avoid clamps when we're known in-gamut?
    // When opaque we could _probably_ get away without a clamp, but for consistency we keep it.
    if (fDst.info().colorType() != kRGBA_F16_SkColorType &&
        fDst.info().colorType() != kRGBA_F32_SkColorType &&
        fDst.info().alphaType() == kPremul_SkAlphaType)
    {
        // TODO: this will be common enough that we may want to fuse into ::clamp_premul.
        p->append(SkRasterPipeline::clamp_0);
        p->append(SkRasterPipeline::clamp_a);
    }
}

void SkRasterPipelineBlitter::append_load_dst(SkRasterPipeline* p) const {
    const void* ctx = &fDstPtr;
    switch (fDst.info().colorType()) {
        default: break;

        case kGray_8_SkColorType:       p->append(SkRasterPipeline::load_g8_dst,      ctx); break;
        case kAlpha_8_SkColorType:      p->append(SkRasterPipeline::load_a8_dst,      ctx); break;
        case kRGB_565_SkColorType:      p->append(SkRasterPipeline::load_565_dst,     ctx); break;
        case kARGB_4444_SkColorType:    p->append(SkRasterPipeline::load_4444_dst,    ctx); break;
        case kBGRA_8888_SkColorType:    p->append(SkRasterPipeline::load_bgra_dst,    ctx); break;
        case kRGBA_8888_SkColorType:    p->append(SkRasterPipeline::load_8888_dst,    ctx); break;
        case kRGBA_1010102_SkColorType: p->append(SkRasterPipeline::load_1010102_dst, ctx); break;
        case kRGBA_F16_SkColorType:     p->append(SkRasterPipeline::load_f16_dst,     ctx); break;
        case kRGBA_F32_SkColorType:     p->append(SkRasterPipeline::load_f32_dst,     ctx); break;

        case kRGB_888x_SkColorType:     p->append(SkRasterPipeline::load_8888_dst,    ctx);
                                        p->append(SkRasterPipeline::force_opaque_dst     ); break;
        case kRGB_101010x_SkColorType:  p->append(SkRasterPipeline::load_1010102_dst, ctx);
                                        p->append(SkRasterPipeline::force_opaque_dst     ); break;
    }
    if (fDst.info().alphaType() == kUnpremul_SkAlphaType) {
        p->append(SkRasterPipeline::premul_dst);
    }
}

void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p) const {
    if (fDst.info().alphaType() == kUnpremul_SkAlphaType) {
        p->append(SkRasterPipeline::unpremul);
    }
    if (fDitherRate > 0.0f) {
        p->append(SkRasterPipeline::dither, &fDitherRate);
    }

    const void* ctx = &fDstPtr;
    switch (fDst.info().colorType()) {
        default: break;

        case kGray_8_SkColorType:       p->append(SkRasterPipeline::luminance_to_alpha);
                                        p->append(SkRasterPipeline::store_a8,      ctx); break;
        case kAlpha_8_SkColorType:      p->append(SkRasterPipeline::store_a8,      ctx); break;
        case kRGB_565_SkColorType:      p->append(SkRasterPipeline::store_565,     ctx); break;
        case kARGB_4444_SkColorType:    p->append(SkRasterPipeline::store_4444,    ctx); break;
        case kBGRA_8888_SkColorType:    p->append(SkRasterPipeline::store_bgra,    ctx); break;
        case kRGBA_8888_SkColorType:    p->append(SkRasterPipeline::store_8888,    ctx); break;
        case kRGBA_1010102_SkColorType: p->append(SkRasterPipeline::store_1010102, ctx); break;
        case kRGBA_F16_SkColorType:     p->append(SkRasterPipeline::store_f16,     ctx); break;
        case kRGBA_F32_SkColorType:     p->append(SkRasterPipeline::store_f32,     ctx); break;

        case kRGB_888x_SkColorType:     p->append(SkRasterPipeline::force_opaque         );
                                        p->append(SkRasterPipeline::store_8888,       ctx); break;
        case kRGB_101010x_SkColorType:  p->append(SkRasterPipeline::force_opaque         );
                                        p->append(SkRasterPipeline::store_1010102,    ctx); break;
    }
}

void SkRasterPipelineBlitter::burst_shade(int x, int y, int w) {
    SkASSERT(fBurstCtx);
    if (w > SkToInt(fShaderBuffer.size())) {
        fShaderBuffer.resize(w);
    }
    fBurstCtx->shadeSpan4f(x,y, fShaderBuffer.data(), w);
    // We'll be reading from fShaderOutput.pixels + x, so back up by x.
    fShaderOutput = SkJumper_MemoryCtx{ fShaderBuffer.data() - x, 0 };
}

void SkRasterPipelineBlitter::blitH(int x, int y, int w) {
    this->blitRect(x,y,w,1);
}

void SkRasterPipelineBlitter::blitRect(int x, int y, int w, int h) {
    if (fCanMemsetInBlitRect) {
        for (int ylimit = y+h; y < ylimit; y++) {
            switch (fDst.shiftPerPixel()) {
                case 0:    memset  (fDst.writable_addr8 (x,y), fMemsetColor, w); break;
                case 1: sk_memset16(fDst.writable_addr16(x,y), fMemsetColor, w); break;
                case 2: sk_memset32(fDst.writable_addr32(x,y), fMemsetColor, w); break;
                case 3: sk_memset64(fDst.writable_addr64(x,y), fMemsetColor, w); break;
                default: SkASSERT(false); break;
            }
        }
        return;
    }

    if (!fBlitRect) {
        SkRasterPipeline p(fAlloc);
        this->append_color_pipeline(&p);
        if (fBlend == SkBlendMode::kSrcOver
                && (fDst.info().colorType() == kRGBA_8888_SkColorType ||
                    fDst.info().colorType() == kBGRA_8888_SkColorType)
                && !fDst.colorSpace()
                && fDst.info().alphaType() != kUnpremul_SkAlphaType
                && fDitherRate == 0.0f) {
            auto stage = fDst.info().colorType() == kRGBA_8888_SkColorType
                       ? SkRasterPipeline::srcover_rgba_8888
                       : SkRasterPipeline::srcover_bgra_8888;
            p.append(stage, &fDstPtr);
        } else {
            if (fBlend != SkBlendMode::kSrc) {
                this->append_load_dst(&p);
                SkBlendMode_AppendStages(fBlend, &p);
            }
            this->append_store(&p);
        }
        fBlitRect = p.compile();
    }

    if (fBurstCtx) {
        // We can only burst shade one row at a time.
        for (int ylimit = y+h; y < ylimit; y++) {
            this->burst_shade(x,y,w);
            fBlitRect(x,y, w,1);
        }
    } else {
        // If not bursting we can blit the entire rect at once.
        fBlitRect(x,y,w,h);
    }
}

void SkRasterPipelineBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[]) {
    if (!fBlitAntiH) {
        SkRasterPipeline p(fAlloc);
        this->append_color_pipeline(&p);
        if (SkBlendMode_ShouldPreScaleCoverage(fBlend, /*rgb_coverage=*/false)) {
            p.append(SkRasterPipeline::scale_1_float, &fCurrentCoverage);
            this->append_load_dst(&p);
            SkBlendMode_AppendStages(fBlend, &p);
        } else {
            this->append_load_dst(&p);
            SkBlendMode_AppendStages(fBlend, &p);
            p.append(SkRasterPipeline::lerp_1_float, &fCurrentCoverage);
        }

        this->append_store(&p);
        fBlitAntiH = p.compile();
    }

    for (int16_t run = *runs; run > 0; run = *runs) {
        switch (*aa) {
            case 0x00:                       break;
            case 0xff: this->blitH(x,y,run); break;
            default:
                fCurrentCoverage = *aa * (1/255.0f);
                if (fBurstCtx) {
                    this->burst_shade(x,y,run);
                }
                fBlitAntiH(x,y,run,1);
        }
        x    += run;
        runs += run;
        aa   += run;
    }
}

void SkRasterPipelineBlitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
    SkIRect clip = {x,y, x+2,y+1};
    uint8_t coverage[] = { (uint8_t)a0, (uint8_t)a1 };

    SkMask mask;
    mask.fImage    = coverage;
    mask.fBounds   = clip;
    mask.fRowBytes = 2;
    mask.fFormat   = SkMask::kA8_Format;

    this->blitMask(mask, clip);
}

void SkRasterPipelineBlitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
    SkIRect clip = {x,y, x+1,y+2};
    uint8_t coverage[] = { (uint8_t)a0, (uint8_t)a1 };

    SkMask mask;
    mask.fImage    = coverage;
    mask.fBounds   = clip;
    mask.fRowBytes = 1;
    mask.fFormat   = SkMask::kA8_Format;

    this->blitMask(mask, clip);
}

void SkRasterPipelineBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
    SkIRect clip = {x,y, x+1,y+height};

    SkMask mask;
    mask.fImage    = &alpha;
    mask.fBounds   = clip;
    mask.fRowBytes = 0;     // so we reuse the 1 "row" for all of height
    mask.fFormat   = SkMask::kA8_Format;

    this->blitMask(mask, clip);
}

void SkRasterPipelineBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
    if (mask.fFormat == SkMask::kBW_Format) {
        // TODO: native BW masks?
        return INHERITED::blitMask(mask, clip);
    }

    // We'll use the first (A8) plane of any mask and ignore the other two, just like Ganesh.
    SkMask::Format effectiveMaskFormat = mask.fFormat == SkMask::k3D_Format ? SkMask::kA8_Format
                                                                            : mask.fFormat;


    // Lazily build whichever pipeline we need, specialized for each mask format.
    if (effectiveMaskFormat == SkMask::kA8_Format && !fBlitMaskA8) {
        SkRasterPipeline p(fAlloc);
        this->append_color_pipeline(&p);
        if (SkBlendMode_ShouldPreScaleCoverage(fBlend, /*rgb_coverage=*/false)) {
            p.append(SkRasterPipeline::scale_u8, &fMaskPtr);
            this->append_load_dst(&p);
            SkBlendMode_AppendStages(fBlend, &p);
        } else {
            this->append_load_dst(&p);
            SkBlendMode_AppendStages(fBlend, &p);
            p.append(SkRasterPipeline::lerp_u8, &fMaskPtr);
        }
        this->append_store(&p);
        fBlitMaskA8 = p.compile();
    }
    if (effectiveMaskFormat == SkMask::kLCD16_Format && !fBlitMaskLCD16) {
        SkRasterPipeline p(fAlloc);
        this->append_color_pipeline(&p);
        if (SkBlendMode_ShouldPreScaleCoverage(fBlend, /*rgb_coverage=*/true)) {
            // Somewhat unusually, scale_565 needs dst loaded first.
            this->append_load_dst(&p);
            p.append(SkRasterPipeline::scale_565, &fMaskPtr);
            SkBlendMode_AppendStages(fBlend, &p);
        } else {
            this->append_load_dst(&p);
            SkBlendMode_AppendStages(fBlend, &p);
            p.append(SkRasterPipeline::lerp_565, &fMaskPtr);
        }
        this->append_store(&p);
        fBlitMaskLCD16 = p.compile();
    }

    std::function<void(size_t,size_t,size_t,size_t)>* blitter = nullptr;
    // Update fMaskPtr to point "into" this current mask, but lined up with fDstPtr at (0,0).
    // This sort of trickery upsets UBSAN (pointer-overflow) so we do our math in uintptr_t.

    // mask.fRowBytes is a uint32_t, which would break our addressing math on 64-bit builds.
    size_t rowBytes = mask.fRowBytes;
    switch (effectiveMaskFormat) {
        case SkMask::kA8_Format:
            fMaskPtr.stride = rowBytes;
            fMaskPtr.pixels = (void*)((uintptr_t)mask.fImage - mask.fBounds.left() * (size_t)1
                                                             - mask.fBounds.top()  * rowBytes);
            blitter = &fBlitMaskA8;
            break;
        case SkMask::kLCD16_Format:
            fMaskPtr.stride = rowBytes / 2;
            fMaskPtr.pixels = (void*)((uintptr_t)mask.fImage - mask.fBounds.left() * (size_t)2
                                                             - mask.fBounds.top()  * rowBytes);
            blitter = &fBlitMaskLCD16;
            break;
        default:
            return;
    }

    SkASSERT(blitter);
    if (fBurstCtx) {
        // We can only burst shade one row at a time.
        int x = clip.left();
        for (int y = clip.top(); y < clip.bottom(); y++) {
            this->burst_shade(x,y,clip.width());
            (*blitter)(x,y, clip.width(),1);
        }
    } else {
        // If not bursting we can blit the entire mask at once.
        (*blitter)(clip.left(),clip.top(), clip.width(),clip.height());
    }
}
