/*
 * Copyright 2013 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/SkBitmap.h"
#include "include/core/SkBlurTypes.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkShader.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTiledImageUtils.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrContextOptions.h"
#include "include/private/base/SkTDArray.h"
#include "src/core/SkBlurMask.h"
#include "tools/ToolUtils.h"

#if defined(SK_GRAPHITE)
#include "include/gpu/graphite/ContextOptions.h"
#include "include/private/gpu/graphite/ContextOptionsPriv.h"
#endif

/** Creates an image with two one-pixel wide borders around a checkerboard. The checkerboard is 2x2
    checks where each check has as many pixels as is necessary to fill the interior. It returns
    the image and a src rect that bounds the checkerboard portion. */
std::tuple<sk_sp<SkImage>, SkRect> make_ringed_image(SkCanvas* canvas, int width, int height) {

    // These are kRGBA_8888_SkColorType values.
    static constexpr uint32_t kOuterRingColor = 0xFFFF0000,
                              kInnerRingColor = 0xFF0000FF,
                              kCheckColor1    = 0xFF000000,
                              kCheckColor2    = 0xFFFFFFFF;

    SkASSERT(0 == width % 2 && 0 == height % 2);
    SkASSERT(width >= 6 && height >= 6);

    SkImageInfo info = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType,
                                         kPremul_SkAlphaType);
    size_t rowBytes = SkAlign4(info.minRowBytes());
    SkBitmap bitmap;
    bitmap.allocPixels(info, rowBytes);

    uint32_t* scanline = bitmap.getAddr32(0, 0);
    for (int x = 0; x < width; ++x) {
        scanline[x] = kOuterRingColor;
    }
    scanline = bitmap.getAddr32(0, 1);
    scanline[0] = kOuterRingColor;
    for (int x = 1; x < width - 1; ++x) {
        scanline[x] = kInnerRingColor;
    }
    scanline[width - 1] = kOuterRingColor;

    for (int y = 2; y < height / 2; ++y) {
        scanline = bitmap.getAddr32(0, y);
        scanline[0] = kOuterRingColor;
        scanline[1] = kInnerRingColor;
        for (int x = 2; x < width / 2; ++x) {
            scanline[x] = kCheckColor1;
        }
        for (int x = width / 2; x < width - 2; ++x) {
            scanline[x] = kCheckColor2;
        }
        scanline[width - 2] = kInnerRingColor;
        scanline[width - 1] = kOuterRingColor;
    }

    for (int y = height / 2; y < height - 2; ++y) {
        scanline = bitmap.getAddr32(0, y);
        scanline[0] = kOuterRingColor;
        scanline[1] = kInnerRingColor;
        for (int x = 2; x < width / 2; ++x) {
            scanline[x] = kCheckColor2;
        }
        for (int x = width / 2; x < width - 2; ++x) {
            scanline[x] = kCheckColor1;
        }
        scanline[width - 2] = kInnerRingColor;
        scanline[width - 1] = kOuterRingColor;
    }

    scanline = bitmap.getAddr32(0, height - 2);
    scanline[0] = kOuterRingColor;
    for (int x = 1; x < width - 1; ++x) {
        scanline[x] = kInnerRingColor;
    }
    scanline[width - 1] = kOuterRingColor;

    scanline = bitmap.getAddr32(0, height - 1);
    for (int x = 0; x < width; ++x) {
        scanline[x] = kOuterRingColor;
    }
    bitmap.setImmutable();
    return { bitmap.asImage(), SkRect::Make({2, 2, width - 2, height - 2})};
}

/**
 * These GMs exercise the behavior of the drawImageRect and its SrcRectConstraint parameter. They
 * tests various matrices, filter qualities, and interaction with mask filters. They also exercise
 * the tiling image draws of SkGpuDevice by overriding the maximum texture size of the GrContext.
 */
class SrcRectConstraintGM : public skiagm::GM {
public:
    SrcRectConstraintGM(const char* shortName, SkCanvas::SrcRectConstraint constraint, bool manual)
        : fShortName(shortName)
        , fConstraint(constraint)
        , fManual(manual) {
        // Make sure GPU SkSurfaces can be created for this GM.
        SkASSERT(this->getISize().width() <= kMaxTextureSize &&
                 this->getISize().height() <= kMaxTextureSize);
    }

protected:
    SkString getName() const override { return fShortName; }
    SkISize getISize() override { return SkISize::Make(800, 1000); }

    void drawImage(SkCanvas* canvas, sk_sp<SkImage> image, SkRect srcRect, SkRect dstRect,
                   const SkSamplingOptions& sampling, SkPaint* paint) {
        if (fManual) {
            SkTiledImageUtils::DrawImageRect(canvas, image.get(), srcRect, dstRect,
                                             sampling, paint, fConstraint);
        } else {
            canvas->drawImageRect(image.get(), srcRect, dstRect, sampling, paint, fConstraint);
        }
    }

    // Draw the area of interest of the small image
    void drawCase1(SkCanvas* canvas, int transX, int transY, bool aa,
                   const SkSamplingOptions& sampling) {
        SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(transY),
                                      SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));

        SkPaint paint;
        paint.setColor(SK_ColorBLUE);
        paint.setAntiAlias(aa);

        this->drawImage(canvas, fSmallImage, fSmallSrcRect, dst, sampling, &paint);
    }

    // Draw the area of interest of the large image
    void drawCase2(SkCanvas* canvas, int transX, int transY, bool aa,
                   const SkSamplingOptions& sampling) {
        SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(transY),
                                      SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));

        SkPaint paint;
        paint.setColor(SK_ColorBLUE);
        paint.setAntiAlias(aa);

        this->drawImage(canvas, fBigImage, fBigSrcRect, dst, sampling, &paint);
    }

    // Draw upper-left 1/4 of the area of interest of the large image
    void drawCase3(SkCanvas* canvas, int transX, int transY, bool aa,
                   const SkSamplingOptions& sampling) {
        SkRect src = SkRect::MakeXYWH(fBigSrcRect.fLeft,
                                      fBigSrcRect.fTop,
                                      fBigSrcRect.width()/2,
                                      fBigSrcRect.height()/2);
        SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(transY),
                                      SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));

        SkPaint paint;
        paint.setColor(SK_ColorBLUE);
        paint.setAntiAlias(aa);

        this->drawImage(canvas, fBigImage, src, dst, sampling, &paint);
    }

    // Draw the area of interest of the small image with a normal blur
    void drawCase4(SkCanvas* canvas, int transX, int transY, bool aa,
                   const SkSamplingOptions& sampling) {
        SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(transY),
                                      SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));

        SkPaint paint;
        paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle,
                                                   SkBlurMask::ConvertRadiusToSigma(3)));
        paint.setColor(SK_ColorBLUE);
        paint.setAntiAlias(aa);

        this->drawImage(canvas, fSmallImage, fSmallSrcRect, dst, sampling, &paint);
    }

    // Draw the area of interest of the small image with a outer blur
    void drawCase5(SkCanvas* canvas, int transX, int transY, bool aa,
                   const SkSamplingOptions& sampling) {
        SkRect dst = SkRect::MakeXYWH(SkIntToScalar(transX), SkIntToScalar(transY),
                                      SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));

        SkPaint paint;
        paint.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle,
                                                   SkBlurMask::ConvertRadiusToSigma(7)));
        paint.setColor(SK_ColorBLUE);
        paint.setAntiAlias(aa);

        this->drawImage(canvas, fSmallImage, fSmallSrcRect, dst, sampling, &paint);
    }

    void onDraw(SkCanvas* canvas) override {
        if (!fSmallImage) {
            std::tie(fBigImage, fBigSrcRect) = make_ringed_image(canvas,
                                                                 2*kMaxTextureSize,
                                                                 2*kMaxTextureSize);
            std::tie(fSmallImage, fSmallSrcRect) = make_ringed_image(canvas,
                                                                     kSmallSize, kSmallSize);
        }

        canvas->clear(SK_ColorGRAY);
        std::vector<SkMatrix> matrices;
        // Draw with identity
        matrices.push_back(SkMatrix::I());

        // Draw with rotation and scale down in x, up in y.
        SkMatrix m;
        constexpr SkScalar kBottom = SkIntToScalar(kRow4Y + kBlockSize + kBlockSpacing);
        m.setTranslate(0, kBottom);
        m.preRotate(15.f, 0, kBottom + kBlockSpacing);
        m.preScale(0.71f, 1.22f);
        matrices.push_back(m);

        // Align the next set with the middle of the previous in y, translated to the right in x.
        SkPoint corners[] = {{0, 0}, {0, kBottom}, {kWidth, kBottom}, {kWidth, 0}};
        matrices.back().mapPoints(corners, 4);
        m.setTranslate(std::max({corners[0].fX, corners[1].fX, corners[2].fX, corners[3].fX}),
                       (corners[0].fY + corners[1].fY + corners[2].fY + corners[3].fY) / 4);
        m.preScale(0.2f, 0.2f);
        matrices.push_back(m);

        const SkSamplingOptions none(SkFilterMode::kNearest);
        const SkSamplingOptions  low(SkFilterMode::kLinear);
        const SkSamplingOptions high(SkCubicResampler::Mitchell());

        SkScalar maxX = 0;
        for (bool antiAlias : {false, true}) {
            canvas->save();
            canvas->translate(maxX, 0);
            for (const SkMatrix& matrix : matrices) {
                canvas->save();
                canvas->concat(matrix);

                // First draw a column with no filtering
                this->drawCase1(canvas, kCol0X, kRow0Y, antiAlias, none);
                this->drawCase2(canvas, kCol0X, kRow1Y, antiAlias, none);
                this->drawCase3(canvas, kCol0X, kRow2Y, antiAlias, none);
                this->drawCase4(canvas, kCol0X, kRow3Y, antiAlias, none);
                this->drawCase5(canvas, kCol0X, kRow4Y, antiAlias, none);

                // Then draw a column with low filtering
                this->drawCase1(canvas, kCol1X, kRow0Y, antiAlias, low);
                this->drawCase2(canvas, kCol1X, kRow1Y, antiAlias, low);
                this->drawCase3(canvas, kCol1X, kRow2Y, antiAlias, low);
                this->drawCase4(canvas, kCol1X, kRow3Y, antiAlias, low);
                this->drawCase5(canvas, kCol1X, kRow4Y, antiAlias, low);

                // Then draw a column with high filtering. Skip it if in kStrict mode and MIP
                // mapping will be used. On GPU we allow bleeding at non-base levels because
                // building a new MIP chain for the subset is expensive.
                SkScalar scales[2];
                SkAssertResult(matrix.getMinMaxScales(scales));
                if (fConstraint != SkCanvas::kStrict_SrcRectConstraint || scales[0] >= 1.f) {
                    this->drawCase1(canvas, kCol2X, kRow0Y, antiAlias, high);
                    this->drawCase2(canvas, kCol2X, kRow1Y, antiAlias, high);
                    this->drawCase3(canvas, kCol2X, kRow2Y, antiAlias, high);
                    this->drawCase4(canvas, kCol2X, kRow3Y, antiAlias, high);
                    this->drawCase5(canvas, kCol2X, kRow4Y, antiAlias, high);
                }

                SkPoint innerCorners[] = {{0, 0}, {0, kBottom}, {kWidth, kBottom}, {kWidth, 0}};
                matrix.mapPoints(innerCorners, 4);
                SkScalar x = kBlockSize + std::max({innerCorners[0].fX, innerCorners[1].fX,
                                                    innerCorners[2].fX, innerCorners[3].fX});
                maxX = std::max(maxX, x);
                canvas->restore();
            }
            canvas->restore();
        }
    }

    void modifyGrContextOptions(GrContextOptions* options) override {
        options->fMaxTextureSizeOverride = kMaxTextureSize;
    }

#if defined(SK_GRAPHITE)
    void modifyGraphiteContextOptions(skgpu::graphite::ContextOptions* options) const override {
        SkASSERT(options->fOptionsPriv);
        options->fOptionsPriv->fMaxTextureSizeOverride = kMaxTextureSize;
    }
#endif

private:
    inline static constexpr int kBlockSize = 70;
    inline static constexpr int kBlockSpacing = 12;

    inline static constexpr int kCol0X = kBlockSpacing;
    inline static constexpr int kCol1X = 2*kBlockSpacing + kBlockSize;
    inline static constexpr int kCol2X = 3*kBlockSpacing + 2*kBlockSize;
    inline static constexpr int kWidth = 4*kBlockSpacing + 3*kBlockSize;

    inline static constexpr int kRow0Y = kBlockSpacing;
    inline static constexpr int kRow1Y = 2*kBlockSpacing + kBlockSize;
    inline static constexpr int kRow2Y = 3*kBlockSpacing + 2*kBlockSize;
    inline static constexpr int kRow3Y = 4*kBlockSpacing + 3*kBlockSize;
    inline static constexpr int kRow4Y = 5*kBlockSpacing + 4*kBlockSize;

    inline static constexpr int kSmallSize = 6;
    // This must be at least as large as the GM width and height so that a surface can be made.
    inline static constexpr int kMaxTextureSize = 1000;

    SkString fShortName;
    sk_sp<SkImage> fBigImage;
    sk_sp<SkImage> fSmallImage;
    SkRect fBigSrcRect;
    SkRect fSmallSrcRect;
    SkCanvas::SrcRectConstraint fConstraint;
    bool fManual;
    using INHERITED = GM;
};

DEF_GM(return new SrcRectConstraintGM("strict_constraint_no_red_allowed",
                                      SkCanvas::kStrict_SrcRectConstraint,
                                      /* manual= */ false););
DEF_GM(return new SrcRectConstraintGM("strict_constraint_no_red_allowed_manual",
                                      SkCanvas::kStrict_SrcRectConstraint,
                                      /* manual= */ true););

DEF_GM(return new SrcRectConstraintGM("strict_constraint_batch_no_red_allowed",
                                      SkCanvas::kStrict_SrcRectConstraint,
                                      /* manual= */ false););
DEF_GM(return new SrcRectConstraintGM("strict_constraint_batch_no_red_allowed_manual",
                                      SkCanvas::kStrict_SrcRectConstraint,
                                      /* manual= */ true););

DEF_GM(return new SrcRectConstraintGM("fast_constraint_red_is_allowed",
                                      SkCanvas::kFast_SrcRectConstraint,
                                      /* manual= */ false););
DEF_GM(return new SrcRectConstraintGM("fast_constraint_red_is_allowed_manual",
                                      SkCanvas::kFast_SrcRectConstraint,
                                      /* manual= */ true););

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

// Construct an image and return the inner "src" rect. Build the image such that the interior is
// blue, with a margin of blue (2px) but then an outer margin of red.
//
// Show that kFast_SrcRectConstraint sees even the red margin (due to mipmapping) when the image
// is scaled down far enough.
//
static sk_sp<SkImage> make_image(SkCanvas* canvas, SkRect* srcR) {
    // Intentially making the size a power of 2 to avoid the noise from how different GPUs will
    // produce different mipmap filtering when we have an odd sized texture.
    const int N = 10 + 2 + 8 + 2 + 10;
    SkImageInfo info = SkImageInfo::MakeN32Premul(N, N);
    auto        surface = ToolUtils::makeSurface(canvas, info);
    SkCanvas* c = surface->getCanvas();
    SkRect r = SkRect::MakeIWH(info.width(), info.height());
    SkPaint paint;

    paint.setColor(SK_ColorRED);
    c->drawRect(r, paint);
    r.inset(10, 10);
    paint.setColor(SK_ColorBLUE);
    c->drawRect(r, paint);

    *srcR = r.makeInset(2, 2);
    return surface->makeImageSnapshot();
}

DEF_SIMPLE_GM(bleed_downscale, canvas, 360, 240) {
    SkRect src;
    sk_sp<SkImage> img = make_image(canvas, &src);
    SkPaint paint;

    canvas->translate(10, 10);

    const SkCanvas::SrcRectConstraint constraints[] = {
        SkCanvas::kStrict_SrcRectConstraint, SkCanvas::kFast_SrcRectConstraint
    };
    const SkSamplingOptions samplings[] = {
        SkSamplingOptions(SkFilterMode::kNearest),
        SkSamplingOptions(SkFilterMode::kLinear),
        SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear),
    };
    for (auto constraint : constraints) {
        canvas->save();
        for (auto sampling : samplings) {
            auto surf = ToolUtils::makeSurface(canvas, SkImageInfo::MakeN32Premul(1, 1));
            surf->getCanvas()->drawImageRect(img, src, SkRect::MakeWH(1, 1), sampling,
                                             nullptr, constraint);
            // now blow up the 1 pixel result
            canvas->drawImageRect(surf->makeImageSnapshot(), SkRect::MakeWH(100, 100),
                                  SkSamplingOptions());
            canvas->translate(120, 0);
        }
        canvas->restore();
        canvas->translate(0, 120);
    }
}
