/*
 * Copyright 2014 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 GPU backend.

#include "gm/gm.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/private/SkTArray.h"
#include "src/core/SkCanvasPriv.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrSamplerState.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/effects/GrTextureEffect.h"
#include "tools/Resources.h"
#include "tools/gpu/TestOps.h"

#include <memory>
#include <utility>

using MipmapMode = GrSamplerState::MipmapMode;
using Filter     = GrSamplerState::Filter;
using Wrap       = GrSamplerState::WrapMode;

namespace skiagm {
/**
 * This GM directly exercises GrTextureEffect::MakeTexelSubset.
 */
class TexelSubset : public GpuGM {
public:
    TexelSubset(Filter filter, MipmapMode mm, bool upscale)
            : fFilter(filter), fMipmapMode(mm), fUpscale(upscale) {
        this->setBGColor(0xFFFFFFFF);
    }

protected:
    SkString onShortName() override {
        SkString name("texel_subset");
        switch (fFilter) {
            case Filter::kNearest:
                name.append("_nearest");
                break;
            case Filter::kLinear:
                name.append("_linear");
                break;
        }
        switch (fMipmapMode) {
            case MipmapMode::kNone:
                break;
            case MipmapMode::kNearest:
                name.append("_mipmap_nearest");
                break;
            case MipmapMode::kLinear:
                name.append("_mipmap_linear");
                break;
        }
        name.append(fUpscale ? "_up" : "_down");
        return name;
    }

    SkISize onISize() override {
        static constexpr int kN = GrSamplerState::kWrapModeCount;
        int w = kTestPad + 2*kN*(kImageSize.width()  + 2*kDrawPad + kTestPad);
        int h = kTestPad + 2*kN*(kImageSize.height() + 2*kDrawPad + kTestPad);
        return {w, h};
    }

    void onOnceBeforeDraw() override {
        GetResourceAsBitmap("images/mandrill_128.png", &fBitmap);
        // Make the bitmap non-square to detect any width/height confusion.
        fBitmap.extractSubset(&fBitmap, SkIRect::MakeSize(fBitmap.dimensions()).makeInset(0, 20));
        SkASSERT(fBitmap.dimensions() == kImageSize);
    }

    DrawResult onDraw(GrRecordingContext* rContext, SkCanvas* canvas, SkString* errorMsg) override {
        auto sdc = SkCanvasPriv::TopDeviceSurfaceDrawContext(canvas);
        if (!sdc) {
            *errorMsg = kErrorMsg_DrawSkippedGpuOnly;
            return DrawResult::kSkip;
        }

        GrMipmapped mipmapped = (fMipmapMode != MipmapMode::kNone) ? GrMipmapped::kYes
                                                                   : GrMipmapped::kNo;
        if (mipmapped == GrMipmapped::kYes && !rContext->priv().caps()->mipmapSupport()) {
            return DrawResult::kSkip;
        }
        auto view = std::get<0>(GrMakeCachedBitmapProxyView(
                rContext, fBitmap, /*label=*/"DrawResult_Draw_BitMap", mipmapped));
        if (!view) {
            *errorMsg = "Failed to create proxy.";
            return DrawResult::kFail;
        }

        SkIRect texelSubset;
        // Use a smaller subset when upscaling so that wrap is hit on all sides of the rect we
        // will draw.
        if (fUpscale) {
            texelSubset = SkIRect::MakeXYWH(fBitmap.width()/3 - 1, 2*fBitmap.height()/5 - 1,
                                            fBitmap.width()/4 + 2,   fBitmap.height()/5 + 2);
        } else {
            texelSubset = SkIRect::MakeXYWH(  fBitmap.width()/8 - 1,   fBitmap.height()/7 - 1,
                                            3*fBitmap.width()/5 + 2, 4*fBitmap.height()/5 + 2);
        }

        SkTArray<SkMatrix> textureMatrices;

        SkRect a = SkRect::Make(texelSubset);
        SkRect b = fUpscale ? a.makeInset (.31f * a.width(), .31f * a.height())
                            : a.makeOutset(.25f * a.width(), .25f * a.height());
        textureMatrices.push_back() = SkMatrix::RectToRect(a, b);

        b = fUpscale ? a.makeInset (.25f * a.width(), .35f * a.height())
                     : a.makeOutset(.20f * a.width(), .35f * a.height());
        textureMatrices.push_back() = SkMatrix::RectToRect(a, b);
        textureMatrices.back().preRotate(45.f, a.centerX(), a.centerY());
        textureMatrices.back().postSkew(.05f, -.05f);

        SkBitmap subsetBmp;
        fBitmap.extractSubset(&subsetBmp, texelSubset);
        subsetBmp.setImmutable();
        auto subsetView = std::get<0>(GrMakeCachedBitmapProxyView(
                rContext, subsetBmp, /*label=*/"DrawResult_Draw_SubsetBitMap", mipmapped));

        SkRect localRect = SkRect::Make(fBitmap.bounds()).makeOutset(kDrawPad, kDrawPad);

        auto size = this->onISize();

        SkScalar y = kDrawPad + kTestPad;
        SkRect drawRect;
        for (int tm = 0; tm < textureMatrices.count(); ++tm) {
            for (int my = 0; my < GrSamplerState::kWrapModeCount; ++my) {
                SkScalar x = kDrawPad + kTestPad;
                auto wmy = static_cast<Wrap>(my);
                for (int mx = 0; mx < GrSamplerState::kWrapModeCount; ++mx) {
                    auto wmx = static_cast<Wrap>(mx);

                    const auto& caps = *rContext->priv().caps();

                    GrSamplerState sampler(wmx, wmy, fFilter, fMipmapMode);

                    drawRect = localRect.makeOffset(x, y);

                    std::unique_ptr<GrFragmentProcessor> fp1;
                    fp1 = GrTextureEffect::MakeSubset(view,
                                                      fBitmap.alphaType(),
                                                      textureMatrices[tm],
                                                      sampler,
                                                      SkRect::Make(texelSubset),
                                                      caps);
                    if (!fp1) {
                        continue;
                    }

                    // Throw a translate in the local matrix just to test having something other
                    // than identity. Compensate with an offset local rect.
                    static constexpr SkVector kT = {-100, 300};
                    if (auto op = sk_gpu_test::test_ops::MakeRect(rContext,
                                                                  std::move(fp1),
                                                                  drawRect,
                                                                  localRect.makeOffset(kT),
                                                                  SkMatrix::Translate(-kT))) {
                        sdc->addDrawOp(std::move(op));
                    }

                    x += localRect.width() + kTestPad;

                    // Now draw with a subsetted proxy using fixed function texture sampling
                    // rather than a texture subset as a comparison.
                    drawRect = localRect.makeOffset(x, y);
                    SkMatrix subsetTextureMatrix = SkMatrix::Concat(
                            SkMatrix::Translate(-texelSubset.topLeft()), textureMatrices[tm]);

                    auto fp2 = GrTextureEffect::Make(subsetView,
                                                     fBitmap.alphaType(),
                                                     subsetTextureMatrix,
                                                     sampler,
                                                     caps);
                    if (auto op = sk_gpu_test::test_ops::MakeRect(rContext, std::move(fp2),
                                                                  drawRect, localRect)) {
                        sdc->addDrawOp(std::move(op));
                    }

                    if (mx < GrSamplerState::kWrapModeCount - 1) {
                        SkScalar midX =
                                SkScalarFloorToScalar(drawRect.right() + kTestPad/2.f) + 0.5f;
                        canvas->drawLine({midX, -1}, {midX, (float)size.fHeight+1}, {});
                    }
                    x += localRect.width() + kTestPad;
                }
                if (my < GrSamplerState::kWrapModeCount - 1) {
                    SkScalar midY = SkScalarFloorToScalar(drawRect.bottom() + kTestPad/2.f) + 0.5f;
                    canvas->drawLine({-1, midY}, {(float)size.fWidth+1, midY}, {});
                }
                y += localRect.height() + kTestPad;
            }
            if (tm < textureMatrices.count() - 1) {
                SkPaint paint;
                paint.setColor(SK_ColorRED);
                SkScalar midY = SkScalarFloorToScalar(drawRect.bottom() + kTestPad/2.f) + 0.5f;
                canvas->drawLine({-1, midY}, {(float)size.fWidth + 1, midY}, paint);
            }
        }
        return DrawResult::kOk;
    }

private:
    inline static constexpr SkISize kImageSize = {128, 88};
    inline static constexpr SkScalar kDrawPad = 10.f;
    inline static constexpr SkScalar kTestPad = 10.f;
    SkBitmap fBitmap;
    Filter fFilter;
    MipmapMode fMipmapMode;
    bool fUpscale;

    using INHERITED = GM;
};

DEF_GM(return new TexelSubset(Filter::kNearest, MipmapMode::kNone   , false);)
DEF_GM(return new TexelSubset(Filter::kNearest, MipmapMode::kNone   , true );)
DEF_GM(return new TexelSubset(Filter::kLinear , MipmapMode::kNone   , false);)
DEF_GM(return new TexelSubset(Filter::kLinear , MipmapMode::kNone   , true );)
// It doesn't make sense to have upscaling MIP map.
DEF_GM(return new TexelSubset(Filter::kNearest, MipmapMode::kNearest, false);)
DEF_GM(return new TexelSubset(Filter::kLinear , MipmapMode::kNearest, false);)
DEF_GM(return new TexelSubset(Filter::kNearest, MipmapMode::kLinear , false);)
DEF_GM(return new TexelSubset(Filter::kLinear , MipmapMode::kLinear , false);)

}  // namespace skiagm
