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

#include "SkArenaAlloc.h"
#include "SkBitmapController.h"
#include "SkBitmapProcShader.h"
#include "SkBitmapProvider.h"
#include "SkColorTable.h"
#include "SkEmptyShader.h"
#include "SkImage_Base.h"
#include "SkImageShader.h"
#include "SkImageShaderContext.h"
#include "SkPM4fPriv.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"

SkImageShader::SkImageShader(sk_sp<SkImage> img, TileMode tmx, TileMode tmy, const SkMatrix* matrix)
    : INHERITED(matrix)
    , fImage(std::move(img))
    , fTileModeX(tmx)
    , fTileModeY(tmy)
{}

sk_sp<SkFlattenable> SkImageShader::CreateProc(SkReadBuffer& buffer) {
    const TileMode tx = (TileMode)buffer.readUInt();
    const TileMode ty = (TileMode)buffer.readUInt();
    SkMatrix matrix;
    buffer.readMatrix(&matrix);
    sk_sp<SkImage> img = buffer.readImage();
    if (!img) {
        return nullptr;
    }
    return SkImageShader::Make(std::move(img), tx, ty, &matrix);
}

void SkImageShader::flatten(SkWriteBuffer& buffer) const {
    buffer.writeUInt(fTileModeX);
    buffer.writeUInt(fTileModeY);
    buffer.writeMatrix(this->getLocalMatrix());
    buffer.writeImage(fImage.get());
}

bool SkImageShader::isOpaque() const {
    return fImage->isOpaque();
}

size_t SkImageShader::onContextSize(const ContextRec& rec) const {
    return SkBitmapProcLegacyShader::ContextSize(rec, as_IB(fImage)->onImageInfo());
}

SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* storage) const {
    return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY,
                                                 SkBitmapProvider(fImage.get(), rec.fDstColorSpace),
                                                 rec, storage);
}

SkImage* SkImageShader::onIsAImage(SkMatrix* texM, TileMode xy[]) const {
    if (texM) {
        *texM = this->getLocalMatrix();
    }
    if (xy) {
        xy[0] = (TileMode)fTileModeX;
        xy[1] = (TileMode)fTileModeY;
    }
    return const_cast<SkImage*>(fImage.get());
}

#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
bool SkImageShader::onIsABitmap(SkBitmap* texture, SkMatrix* texM, TileMode xy[]) const {
    const SkBitmap* bm = as_IB(fImage)->onPeekBitmap();
    if (!bm) {
        return false;
    }

    if (texture) {
        *texture = *bm;
    }
    if (texM) {
        *texM = this->getLocalMatrix();
    }
    if (xy) {
        xy[0] = (TileMode)fTileModeX;
        xy[1] = (TileMode)fTileModeY;
    }
    return true;
}
#endif

static bool bitmap_is_too_big(int w, int h) {
    // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it
    // communicates between its matrix-proc and its sampler-proc. Until we can
    // widen that, we have to reject bitmaps that are larger.
    //
    static const int kMaxSize = 65535;

    return w > kMaxSize || h > kMaxSize;
}

sk_sp<SkShader> SkImageShader::Make(sk_sp<SkImage> image, TileMode tx, TileMode ty,
                                    const SkMatrix* localMatrix,
                                    SkTBlitterAllocator* allocator) {
    SkShader* shader;
    if (!image || bitmap_is_too_big(image->width(), image->height())) {
        if (nullptr == allocator) {
            shader = new SkEmptyShader;
        } else {
            shader = allocator->createT<SkEmptyShader>();
        }
    } else {
        if (nullptr == allocator) {
            shader = new SkImageShader(image, tx, ty, localMatrix);
        } else {
            shader = allocator->createT<SkImageShader>(image, tx, ty, localMatrix);
        }
    }
    return sk_sp<SkShader>(shader);
}

#ifndef SK_IGNORE_TO_STRING
void SkImageShader::toString(SkString* str) const {
    const char* gTileModeName[SkShader::kTileModeCount] = {
        "clamp", "repeat", "mirror"
    };

    str->appendf("ImageShader: ((%s %s) ", gTileModeName[fTileModeX], gTileModeName[fTileModeY]);
    fImage->toString(str);
    this->INHERITED::toString(str);
    str->append(")");
}
#endif

///////////////////////////////////////////////////////////////////////////////////////////////////

#if SK_SUPPORT_GPU

#include "SkGr.h"
#include "SkGrPriv.h"
#include "effects/GrSimpleTextureEffect.h"
#include "effects/GrBicubicEffect.h"
#include "effects/GrSimpleTextureEffect.h"

sk_sp<GrFragmentProcessor> SkImageShader::asFragmentProcessor(const AsFPArgs& args) const {
    SkMatrix matrix;
    matrix.setIDiv(fImage->width(), fImage->height());

    SkMatrix lmInverse;
    if (!this->getLocalMatrix().invert(&lmInverse)) {
        return nullptr;
    }
    if (args.fLocalMatrix) {
        SkMatrix inv;
        if (!args.fLocalMatrix->invert(&inv)) {
            return nullptr;
        }
        lmInverse.postConcat(inv);
    }
    matrix.preConcat(lmInverse);

    SkShader::TileMode tm[] = { fTileModeX, fTileModeY };

    // Must set wrap and filter on the sampler before requesting a texture. In two places below
    // we check the matrix scale factors to determine how to interpret the filter quality setting.
    // This completely ignores the complexity of the drawVertices case where explicit local coords
    // are provided by the caller.
    bool doBicubic;
    GrSamplerParams::FilterMode textureFilterMode =
    GrSkFilterQualityToGrFilterMode(args.fFilterQuality, *args.fViewMatrix, this->getLocalMatrix(),
                                    &doBicubic);
    GrSamplerParams params(tm, textureFilterMode);
    sk_sp<SkColorSpace> texColorSpace;
    sk_sp<GrTexture> texture(as_IB(fImage)->asTextureRef(args.fContext, params, args.fDstColorSpace,
                                                         &texColorSpace));
    if (!texture) {
        return nullptr;
    }

    sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
                                                                       args.fDstColorSpace);
    sk_sp<GrFragmentProcessor> inner;
    if (doBicubic) {
        inner = GrBicubicEffect::Make(texture.get(), std::move(colorSpaceXform), matrix, tm);
    } else {
        inner = GrSimpleTextureEffect::Make(texture.get(), std::move(colorSpaceXform),
                                            matrix, params);
    }

    if (GrPixelConfigIsAlphaOnly(texture->config())) {
        return inner;
    }
    return sk_sp<GrFragmentProcessor>(GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)));
}

#endif

///////////////////////////////////////////////////////////////////////////////////////////////////
#include "SkImagePriv.h"

sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkShader::TileMode tmx,
                                   SkShader::TileMode tmy, const SkMatrix* localMatrix,
                                   SkCopyPixelsMode cpm, SkTBlitterAllocator* allocator) {
    // Until we learn otherwise, it seems that any caller that is passing an allocator must be
    // assuming that the returned shader will have a stack-frame lifetime, so we assert that
    // they are also asking for kNever_SkCopyPixelsMode. If that proves otherwise, we can remove
    // or modify this assert.
    SkASSERT(!allocator || (kNever_SkCopyPixelsMode == cpm));

    return SkImageShader::Make(SkMakeImageFromRasterBitmap(src, cpm, allocator),
                               tmx, tmy, localMatrix, allocator);
}

static sk_sp<SkFlattenable> SkBitmapProcShader_CreateProc(SkReadBuffer& buffer) {
    SkMatrix lm;
    buffer.readMatrix(&lm);
    sk_sp<SkImage> image = buffer.readBitmapAsImage();
    SkShader::TileMode mx = (SkShader::TileMode)buffer.readUInt();
    SkShader::TileMode my = (SkShader::TileMode)buffer.readUInt();
    return image ? image->makeShader(mx, my, &lm) : nullptr;
}

SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShader)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkImageShader)
SkFlattenable::Register("SkBitmapProcShader", SkBitmapProcShader_CreateProc, kSkShader_Type);
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END


bool SkImageShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* dst, SkArenaAlloc* scratch,
                                   const SkMatrix& ctm, const SkPaint& paint) const {
    auto matrix = SkMatrix::Concat(ctm, this->getLocalMatrix());
    if (!matrix.invert(&matrix)) {
        return false;
    }
    auto quality = paint.getFilterQuality();

    SkBitmapProvider provider(fImage.get(), dst);
    SkDefaultBitmapController controller(SkDefaultBitmapController::CanShadeHQ::kYes);
    std::unique_ptr<SkBitmapController::State> state {
        controller.requestBitmap(provider, matrix, quality)
    };
    if (!state) {
        return false;
    }

    const SkPixmap& pm = state->pixmap();
    matrix  = state->invMatrix();
    quality = state->quality();
    auto info = pm.info();

    // When the matrix is just an integer translate, bilerp == nearest neighbor.
    if (quality == kLow_SkFilterQuality &&
        matrix.getType() <= SkMatrix::kTranslate_Mask &&
        matrix.getTranslateX() == (int)matrix.getTranslateX() &&
        matrix.getTranslateY() == (int)matrix.getTranslateY()) {
        quality = kNone_SkFilterQuality;
    }

    // See skia:4649 and the GM image_scale_aligned.
    if (quality == kNone_SkFilterQuality) {
        if (matrix.getScaleX() >= 0) {
            matrix.setTranslateX(nextafterf(matrix.getTranslateX(),
                                            floorf(matrix.getTranslateX())));
        }
        if (matrix.getScaleY() >= 0) {
            matrix.setTranslateY(nextafterf(matrix.getTranslateY(),
                                            floorf(matrix.getTranslateY())));
        }
    }

    auto ctx = scratch->make<SkImageShaderContext>();
    ctx->state   = std::move(state);  // Extend lifetime to match the pipeline's.
    ctx->pixels  = pm.addr();
    ctx->ctable  = pm.ctable();
    ctx->color4f = SkColor4f_from_SkColor(paint.getColor(), dst);
    ctx->stride  = pm.rowBytesAsPixels();
    ctx->width   = (float)pm.width();
    ctx->height  = (float)pm.height();
    if (matrix.asAffine(ctx->matrix)) {
        p->append(SkRasterPipeline::matrix_2x3, ctx->matrix);
    } else {
        matrix.get9(ctx->matrix);
        p->append(SkRasterPipeline::matrix_perspective, ctx->matrix);
    }

    auto append_tiling_and_gather = [&] {
        switch (fTileModeX) {
            case kClamp_TileMode:  p->append(SkRasterPipeline::clamp_x,  &ctx->width); break;
            case kMirror_TileMode: p->append(SkRasterPipeline::mirror_x, &ctx->width); break;
            case kRepeat_TileMode: p->append(SkRasterPipeline::repeat_x, &ctx->width); break;
        }
        switch (fTileModeY) {
            case kClamp_TileMode:  p->append(SkRasterPipeline::clamp_y,  &ctx->height); break;
            case kMirror_TileMode: p->append(SkRasterPipeline::mirror_y, &ctx->height); break;
            case kRepeat_TileMode: p->append(SkRasterPipeline::repeat_y, &ctx->height); break;
        }
        switch (info.colorType()) {
            case kAlpha_8_SkColorType:   p->append(SkRasterPipeline::gather_a8,   ctx); break;
            case kIndex_8_SkColorType:   p->append(SkRasterPipeline::gather_i8,   ctx); break;
            case kGray_8_SkColorType:    p->append(SkRasterPipeline::gather_g8,   ctx); break;
            case kRGB_565_SkColorType:   p->append(SkRasterPipeline::gather_565,  ctx); break;
            case kARGB_4444_SkColorType: p->append(SkRasterPipeline::gather_4444, ctx); break;
            case kRGBA_8888_SkColorType:
            case kBGRA_8888_SkColorType: p->append(SkRasterPipeline::gather_8888, ctx); break;
            case kRGBA_F16_SkColorType:  p->append(SkRasterPipeline::gather_f16,  ctx); break;
            default: SkASSERT(false);
        }
        if (info.gammaCloseToSRGB() && dst != nullptr) {
            p->append_from_srgb(info.alphaType());
        }
    };

    auto sample = [&](SkRasterPipeline::StockStage setup_x,
                      SkRasterPipeline::StockStage setup_y) {
        p->append(setup_x, ctx);
        p->append(setup_y, ctx);
        append_tiling_and_gather();
        p->append(SkRasterPipeline::accumulate, ctx);
    };

    if (quality == kNone_SkFilterQuality) {
        append_tiling_and_gather();
    } else if (quality == kLow_SkFilterQuality) {
        p->append(SkRasterPipeline::save_xy, ctx);

        sample(SkRasterPipeline::bilinear_nx, SkRasterPipeline::bilinear_ny);
        sample(SkRasterPipeline::bilinear_px, SkRasterPipeline::bilinear_ny);
        sample(SkRasterPipeline::bilinear_nx, SkRasterPipeline::bilinear_py);
        sample(SkRasterPipeline::bilinear_px, SkRasterPipeline::bilinear_py);

        p->append(SkRasterPipeline::move_dst_src);
    } else {
        p->append(SkRasterPipeline::save_xy, ctx);

        sample(SkRasterPipeline::bicubic_n3x, SkRasterPipeline::bicubic_n3y);
        sample(SkRasterPipeline::bicubic_n1x, SkRasterPipeline::bicubic_n3y);
        sample(SkRasterPipeline::bicubic_p1x, SkRasterPipeline::bicubic_n3y);
        sample(SkRasterPipeline::bicubic_p3x, SkRasterPipeline::bicubic_n3y);

        sample(SkRasterPipeline::bicubic_n3x, SkRasterPipeline::bicubic_n1y);
        sample(SkRasterPipeline::bicubic_n1x, SkRasterPipeline::bicubic_n1y);
        sample(SkRasterPipeline::bicubic_p1x, SkRasterPipeline::bicubic_n1y);
        sample(SkRasterPipeline::bicubic_p3x, SkRasterPipeline::bicubic_n1y);

        sample(SkRasterPipeline::bicubic_n3x, SkRasterPipeline::bicubic_p1y);
        sample(SkRasterPipeline::bicubic_n1x, SkRasterPipeline::bicubic_p1y);
        sample(SkRasterPipeline::bicubic_p1x, SkRasterPipeline::bicubic_p1y);
        sample(SkRasterPipeline::bicubic_p3x, SkRasterPipeline::bicubic_p1y);

        sample(SkRasterPipeline::bicubic_n3x, SkRasterPipeline::bicubic_p3y);
        sample(SkRasterPipeline::bicubic_n1x, SkRasterPipeline::bicubic_p3y);
        sample(SkRasterPipeline::bicubic_p1x, SkRasterPipeline::bicubic_p3y);
        sample(SkRasterPipeline::bicubic_p3x, SkRasterPipeline::bicubic_p3y);

        p->append(SkRasterPipeline::move_dst_src);
    }

    auto effective_color_type = [](SkColorType ct) {
        return ct == kIndex_8_SkColorType ? kN32_SkColorType : ct;
    };

    if (effective_color_type(info.colorType()) == kBGRA_8888_SkColorType) {
        p->append(SkRasterPipeline::swap_rb);
    }
    if (info.colorType() == kAlpha_8_SkColorType) {
        p->append(SkRasterPipeline::set_rgb, &ctx->color4f);
    }
    if (info.colorType() == kAlpha_8_SkColorType || info.alphaType() == kUnpremul_SkAlphaType) {
        p->append(SkRasterPipeline::premul);
    }
    if (quality > kLow_SkFilterQuality) {
        // Bicubic filtering naturally produces out of range values on both sides.
        p->append(SkRasterPipeline::clamp_0);
        p->append(SkRasterPipeline::clamp_a);
    }
    return append_gamut_transform(p, scratch, info.colorSpace(), dst);
}
