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

// This test only works with the GL backend.

#include "gm/gm.h"

#ifdef SK_GL
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.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/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradient.h"
#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/GrTypes.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/gl/GrGLCaps.h"
#include "src/gpu/ganesh/gl/GrGLDefines.h"

#include <algorithm>
#include <array>
#include <cstdint>
#include <memory>

namespace skiagm {
class RectangleTexture : public GM {
public:
    RectangleTexture() {
        this->setBGColor(0xFFFFFFFF);
    }

private:
    enum class ImageType {
        kGradientCircle,
        k2x2
    };

    SkString getName() const override { return SkString("rectangle_texture"); }

    SkISize getISize() override { return SkISize::Make(1180, 710); }

    SkBitmap makeImagePixels(int size, ImageType type) {
        auto ii = SkImageInfo::Make(size, size, kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
        switch (type) {
            case ImageType::kGradientCircle: {
                SkBitmap bmp;
                bmp.allocPixels(ii);
                SkPaint paint;
                SkCanvas canvas(bmp);
                SkPoint pts[] = {{0, 0}, {0, SkIntToScalar(size)}};
                const SkColor4f colors0[] = {
                        SkColor4f::FromColor(0xFF1060B0), SkColor4f::FromColor(0xFF102030)};
                paint.setShader(
                        SkShaders::LinearGradient(pts, {{colors0, {}, SkTileMode::kClamp}, {}}));
                canvas.drawPaint(paint);
                const SkColor4f colors1[] = {
                        SkColor4f::FromColor(0xFFA07010), SkColor4f::FromColor(0xFFA02080)};
                paint.setAntiAlias(true);
                paint.setShader(
                        SkShaders::LinearGradient(pts, {{colors1, {}, SkTileMode::kClamp}, {}}));
                canvas.drawCircle(size/2.f, size/2.f, 2.f*size/5, paint);
                return bmp;
            }
            case ImageType::k2x2: {
                SkBitmap bmp;
                bmp.allocPixels(ii);
                *bmp.getAddr32(0, 0) = 0xFF0000FF;
                *bmp.getAddr32(1, 0) = 0xFF00FF00;
                *bmp.getAddr32(0, 1) = 0xFFFF0000;
                *bmp.getAddr32(1, 1) = 0xFFFFFFFF;
                return bmp;
            }
        }
        SkUNREACHABLE;
    }

    sk_sp<SkImage> createRectangleTextureImg(GrDirectContext* dContext, GrSurfaceOrigin origin,
                                             const SkBitmap content) {
        SkASSERT(content.colorType() == kRGBA_8888_SkColorType);
        auto format = GrBackendFormats::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_RECTANGLE);
        auto bet = dContext->createBackendTexture(content.width(),
                                                  content.height(),
                                                  format,
                                                  skgpu::Mipmapped::kNo,
                                                  GrRenderable::kNo,
                                                  GrProtected::kNo,
                                                  /*label=*/"CreateRectangleTextureImage");
        if (!bet.isValid()) {
            return nullptr;
        }
        if (!dContext->updateBackendTexture(bet, content.pixmap(), origin, nullptr, nullptr)) {
            dContext->deleteBackendTexture(bet);
        }
        return SkImages::AdoptTextureFrom(dContext, bet, origin, kRGBA_8888_SkColorType);
    }

    DrawResult onGpuSetup(SkCanvas* canvas, SkString* errorMsg, GraphiteTestContext*) override {
        auto context = GrAsDirectContext(canvas->recordingContext());
        if (!context || context->abandoned()) {
            return DrawResult::kSkip;
        }

        if (context->backend() != GrBackendApi::kOpenGL_GrBackend ||
            !static_cast<const GrGLCaps*>(context->priv().caps())->rectangleTextureSupport()) {
            *errorMsg = "This GM requires an OpenGL context that supports texture rectangles.";
            return DrawResult::kSkip;
        }

        auto gradCircle = this->makeImagePixels(50, ImageType::kGradientCircle);

        fGradImgs[0] = this->createRectangleTextureImg(context, kTopLeft_GrSurfaceOrigin,
                                                       gradCircle);
        fGradImgs[1] = this->createRectangleTextureImg(context, kBottomLeft_GrSurfaceOrigin,
                                                       gradCircle);
        SkASSERT(SkToBool(fGradImgs[0]) == SkToBool(fGradImgs[1]));
        if (!fGradImgs[0]) {
            *errorMsg = "Could not create gradient rectangle texture images.";
            return DrawResult::kFail;
        }

        fSmallImg = this->createRectangleTextureImg(context, kTopLeft_GrSurfaceOrigin,
                                                    this->makeImagePixels(2, ImageType::k2x2));
        if (!fSmallImg) {
            *errorMsg = "Could not create 2x2 rectangle texture image.";
            return DrawResult::kFail;
        }

        return DrawResult::kOk;
    }

    void onGpuTeardown() override {
        fGradImgs[0] = fGradImgs[1] = nullptr;
        fSmallImg = nullptr;
    }

    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        SkASSERT(fGradImgs[0] && fGradImgs[1] && fSmallImg);

        static constexpr SkScalar kPad = 5.f;

        const SkSamplingOptions kSamplings[] = {
            SkSamplingOptions(SkFilterMode::kNearest),
            SkSamplingOptions(SkFilterMode::kLinear),
            SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear),
            SkSamplingOptions(SkCubicResampler::Mitchell()),
        };

        constexpr SkScalar kScales[] = {1.0f, 1.2f, 0.75f};

        canvas->translate(kPad, kPad);
        for (size_t i = 0; i < kNumGradImages; ++i) {
            auto img = fGradImgs[i];
            int w = img->width();
            int h = img->height();
            for (auto scale : kScales) {
                canvas->save();
                canvas->scale(scale, scale);
                for (auto s : kSamplings) {
                    // drawImage
                    canvas->drawImage(img, 0, 0, s);
                    canvas->translate(w + kPad, 0);

                    // clamp/clamp shader
                    SkPaint clampPaint;
                    clampPaint.setShader(fGradImgs[i]->makeShader(s));
                    canvas->drawRect(SkRect::MakeWH(1.5f*w, 1.5f*h), clampPaint);
                    canvas->translate(1.5f*w + kPad, 0);

                    // repeat/mirror shader
                    SkPaint repeatPaint;
                    repeatPaint.setShader(fGradImgs[i]->makeShader(SkTileMode::kRepeat,
                                                                   SkTileMode::kMirror,
                                                                   s));
                    canvas->drawRect(SkRect::MakeWH(1.5f*w, 1.5f*h), repeatPaint);
                    canvas->translate(1.5f*w + kPad, 0);

                    // drawImageRect with kStrict
                    auto srcRect = SkRect::MakeXYWH(.25f*w, .25f*h, .50f*w, .50f*h);
                    auto dstRect = SkRect::MakeXYWH(      0,     0, .50f*w, .50f*h);
                    canvas->drawImageRect(fGradImgs[i], srcRect, dstRect, s, nullptr,
                                          SkCanvas::kStrict_SrcRectConstraint);
                    canvas->translate(.5f*w + kPad, 0);
                }
                canvas->restore();
                canvas->translate(0, kPad + 1.5f*h*scale);
            }
        }

        static constexpr SkScalar kOutset = 25.f;
        canvas->translate(kOutset, kOutset);
        auto dstRect = SkRect::Make(fSmallImg->dimensions()).makeOutset(kOutset, kOutset);

        const SkSamplingOptions gSamplings[] = {
            SkSamplingOptions(SkFilterMode::kNearest),
            SkSamplingOptions(SkFilterMode::kLinear),
            SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear),
            SkSamplingOptions(SkCubicResampler::Mitchell()),
        };

        for (const auto& sampling : gSamplings) {
            if (!sampling.useCubic && sampling.mipmap != SkMipmapMode::kNone) {
                // Medium is the same as Low for upscaling.
                continue;
            }
            canvas->save();
            for (int ty = 0; ty < kSkTileModeCount; ++ty) {
                canvas->save();
                for (int tx = 0; tx < kSkTileModeCount; ++tx) {
                    SkMatrix lm;
                    lm.setRotate(45.f, 1, 1);
                    lm.postScale(6.5f, 6.5f);
                    SkPaint paint;
                    paint.setShader(fSmallImg->makeShader(static_cast<SkTileMode>(tx),
                                                          static_cast<SkTileMode>(ty),
                                                          sampling,
                                                          lm));
                    canvas->drawRect(dstRect, paint);
                    canvas->translate(dstRect.width() + kPad, 0);
                }
                canvas->restore();
                canvas->translate(0, dstRect.height() + kPad);
            }
            canvas->restore();
            canvas->translate((dstRect.width() + kPad)*kSkTileModeCount, 0);
        }

        return DrawResult::kOk;
    }

private:
    static const int kNumGradImages = 2;

    std::array<sk_sp<SkImage>, kNumGradImages> fGradImgs;
    sk_sp<SkImage> fSmallImg;

    using INHERITED = GM;
};

DEF_GM(return new RectangleTexture;)
}  // namespace skiagm
#endif
