/*
 * 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 "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFilterQuality.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkImageSource.h"

namespace skiagm {

// This GM reproduces the issue in crbug.com/472795. The SkImageSource image
// is shifted for high quality mode between cpu and gpu.
class ImageSourceGM : public GM {
public:
    ImageSourceGM(const char* suffix, SkFilterQuality filter) : fSuffix(suffix), fFilter(filter) {
        this->setBGColor(0xFFFFFFFF);
    }

protected:
    SkString onShortName() override {
        SkString name("imagesrc2_");
        name.append(fSuffix);
        return name;
    }

    SkISize onISize() override { return SkISize::Make(256, 256); }

    // Create an image with high frequency vertical stripes
    void onOnceBeforeDraw() override {
        constexpr SkPMColor gColors[] = {
            SK_ColorRED,     SK_ColorGRAY,
            SK_ColorGREEN,   SK_ColorGRAY,
            SK_ColorBLUE,    SK_ColorGRAY,
            SK_ColorCYAN,    SK_ColorGRAY,
            SK_ColorMAGENTA, SK_ColorGRAY,
            SK_ColorYELLOW,  SK_ColorGRAY,
            SK_ColorWHITE,   SK_ColorGRAY,
        };

        auto surface(SkSurface::MakeRasterN32Premul(kImageSize, kImageSize));
        SkCanvas* canvas = surface->getCanvas();

        int curColor = 0;

        for (int x = 0; x < kImageSize; x += 3) {
            SkRect r = SkRect::MakeXYWH(SkIntToScalar(x), SkIntToScalar(0),
                                        SkIntToScalar(3), SkIntToScalar(kImageSize));
            SkPaint p;
            p.setColor(gColors[curColor]);
            canvas->drawRect(r, p);

            curColor = (curColor+1) % SK_ARRAY_COUNT(gColors);
        }

        fImage = surface->makeImageSnapshot();
    }

    void onDraw(SkCanvas* canvas) override {
        const SkRect srcRect = SkRect::MakeLTRB(0, 0,
                                                SkIntToScalar(kImageSize),
                                                SkIntToScalar(kImageSize));
        const SkRect dstRect = SkRect::MakeLTRB(0.75f, 0.75f, 225.75f, 225.75f);

        SkPaint p;
        p.setImageFilter(SkImageSource::Make(fImage, srcRect, dstRect, fFilter));

        canvas->saveLayer(nullptr, &p);
        canvas->restore();
    }

private:
    static constexpr int kImageSize = 503;

    SkString fSuffix;
    SkFilterQuality fFilter;
    sk_sp<SkImage>  fImage;

    typedef GM INHERITED;
};

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

DEF_GM(return new ImageSourceGM("none", kNone_SkFilterQuality);)
DEF_GM(return new ImageSourceGM("low", kLow_SkFilterQuality);)
DEF_GM(return new ImageSourceGM("med", kMedium_SkFilterQuality);)
DEF_GM(return new ImageSourceGM("high", kHigh_SkFilterQuality);)
}
