/*
 * 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 "SkBitmapProcShader.h"
#include "SkBitmapProvider.h"
#include "SkImage_Base.h"
#include "SkImageShader.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"

SkImageShader::SkImageShader(const SkImage* img, TileMode tmx, TileMode tmy, const SkMatrix* matrix)
    : INHERITED(matrix)
    , fImage(SkRef(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);
    SkAutoTUnref<SkImage> img(buffer.readImage());
    if (!img) {
        return nullptr;
    }
    return SkImageShader::Make(img, tx, ty, &matrix);
}

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

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

size_t SkImageShader::onContextSize(const ContextRec& rec) const {
    return SkBitmapProcShader::ContextSize(rec, SkBitmapProvider(fImage).info());
}

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

sk_sp<SkShader> SkImageShader::Make(const SkImage* image, TileMode tx, TileMode ty,
                                    const SkMatrix* localMatrix) {
    if (!image) {
        return nullptr;
    }
    return sk_sp<SkShader>(new SkImageShader(image, tx, ty, localMatrix));
}

#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 "GrTextureAccess.h"
#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;
    GrTextureParams::FilterMode textureFilterMode =
    GrSkFilterQualityToGrFilterMode(args.fFilterQuality, *args.fViewMatrix, this->getLocalMatrix(),
                                    &doBicubic);
    GrTextureParams params(tm, textureFilterMode);
    SkAutoTUnref<GrTexture> texture(as_IB(fImage)->asTextureRef(args.fContext, params,
                                                                args.fGammaTreatment));
    if (!texture) {
        return nullptr;
    }

    sk_sp<GrFragmentProcessor> inner;
    if (doBicubic) {
        inner = GrBicubicEffect::Make(texture, nullptr, matrix, tm);
    } else {
        inner = GrSimpleTextureEffect::Make(texture, nullptr, matrix, params);
    }

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

#endif
