/*
 * 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/SkFilterQuality.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/SkGradientShader.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrTypes.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrGpu.h"
#include "src/gpu/gl/GrGLCaps.h"
#include "src/gpu/gl/GrGLDefines.h"

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

class GrRenderTargetContext;

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

private:
    enum class ImageType {
        kGradientCircle,
        k2x2
    };

    SkString onShortName() override {
        return SkString("rectangle_texture");
    }

    SkISize onISize() 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)}};
                SkColor colors0[] = {0xFF1060B0, 0xFF102030};
                paint.setShader(
                        SkGradientShader::MakeLinear(pts, colors0, nullptr, 2, SkTileMode::kClamp));
                canvas.drawPaint(paint);
                SkColor colors1[] = {0xFFA07010, 0xFFA02080};
                paint.setAntiAlias(true);
                paint.setShader(
                        SkGradientShader::MakeLinear(pts, colors1, nullptr, 2, 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 = GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_RECTANGLE);
        auto bet = dContext->createBackendTexture(content.width(), content.height(), format,
                                                 GrMipmapped::kNo, GrRenderable::kNo);
        if (!bet.isValid()) {
            return nullptr;
        }
        const SkPixmap* pm = &content.pixmap();
        SkAutoPixmapStorage tempPM;
        if (origin == kBottomLeft_GrSurfaceOrigin) {
            tempPM.alloc(pm->info());
            const uint32_t* src = pm->addr32();
            uint32_t* dst = tempPM.writable_addr32(0, content.height() - 1);
            for (int y = 0; y < content.height(); ++y,
                                                  src += pm->rowBytesAsPixels(),
                                                  dst -= tempPM.rowBytesAsPixels()) {
                std::copy_n(src, content.width(), dst);
            }
            pm = &tempPM;
        }
        if (!dContext->updateBackendTexture(bet, pm, 1, nullptr, nullptr)) {
            dContext->deleteBackendTexture(bet);
        }
        return SkImage::MakeFromAdoptedTexture(dContext, bet, origin, kRGBA_8888_SkColorType);
    }

    DrawResult onGpuSetup(GrDirectContext* context, SkString* errorMsg) override {
        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(GrRecordingContext*, GrRenderTargetContext*, SkCanvas* canvas,
                      SkString*) override {
        SkASSERT(fGradImgs[0] && fGradImgs[1] && fSmallImg);

        static constexpr SkScalar kPad = 5.f;

        constexpr SkFilterQuality kQualities[] = {
                kNone_SkFilterQuality,
                kLow_SkFilterQuality,
                kMedium_SkFilterQuality,
                kHigh_SkFilterQuality,
        };

        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 s : kScales) {
                canvas->save();
                canvas->scale(s, s);
                for (auto q : kQualities) {
                    // drawImage
                    SkPaint plainPaint;
                    plainPaint.setFilterQuality(q);
                    canvas->drawImage(img, 0, 0, &plainPaint);
                    canvas->translate(w + kPad, 0);

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

                    // repeat/mirror shader
                    SkPaint repeatPaint;
                    repeatPaint.setFilterQuality(q);
                    repeatPaint.setShader(fGradImgs[i]->makeShader(SkTileMode::kRepeat,
                                                                   SkTileMode::kMirror));
                    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, &plainPaint,
                                          SkCanvas::kStrict_SrcRectConstraint);
                    canvas->translate(.5f*w + kPad, 0);
                }
                canvas->restore();
                canvas->translate(0, kPad + 1.5f*h*s);
            }
        }

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

        for (int fq = kNone_SkFilterQuality; fq <= kLast_SkFilterQuality; ++fq) {
            if (fq == kMedium_SkFilterQuality) {
                // 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);
                    auto shader = fSmallImg->makeShader(static_cast<SkTileMode>(tx),
                                                        static_cast<SkTileMode>(ty), &lm);
                    SkPaint paint;
                    paint.setShader(std::move(shader));
                    paint.setFilterQuality(static_cast<SkFilterQuality>(fq));
                    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;

    sk_sp<SkImage> fGradImgs[kNumGradImages];
    sk_sp<SkImage> fSmallImg;

    typedef GM INHERITED;
};

DEF_GM(return new RectangleTexture;)
}
#endif
