/*
 * Copyright 2021 Google LLC
 *
 * 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/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "src/base/SkRectMemcpy.h"
#include "src/core/SkCanvasPriv.h"
#include "src/core/SkConvertPixels.h"
#include "src/gpu/ganesh/GrCanvas.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/effects/GrTextureEffect.h"
#include "tools/gpu/ProxyUtils.h"

static GrSurfaceProxyView create_view(GrDirectContext* dContext,
                                      const SkBitmap& src,
                                      GrSurfaceOrigin origin) {
    SkASSERT(src.colorType() == kRGBA_8888_SkColorType);

#define USE_LAZY_PROXIES 1 // Toggle this to generate the reference images

    if (USE_LAZY_PROXIES) {
        auto format = dContext->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
                                                                       GrRenderable::kNo);
        if (!format.isValid()) {
            return {};
        }

        sk_sp<GrTextureProxy> proxy = GrProxyProvider::MakeFullyLazyProxy(
                [src](GrResourceProvider* rp, const GrSurfaceProxy::LazySurfaceDesc& desc)
                        -> GrSurfaceProxy::LazyCallbackResult {
                    SkASSERT(desc.fMipmapped == skgpu::Mipmapped::kNo);
                    GrMipLevel mipLevel = {src.getPixels(), src.rowBytes(), nullptr};
                    auto colorType = SkColorTypeToGrColorType(src.colorType());

                    return rp->createTexture(src.dimensions(),
                                             desc.fFormat,
                                             desc.fTextureType,
                                             colorType,
                                             desc.fRenderable,
                                             desc.fSampleCnt,
                                             desc.fBudgeted,
                                             desc.fFit,
                                             desc.fProtected,
                                             mipLevel,
                                             desc.fLabel);
                },
                format,
                GrRenderable::kNo,
                1,
                GrProtected::kNo,
                *dContext->priv().caps(),
                GrSurfaceProxy::UseAllocator::kYes);

        if (!proxy) {
            return {};
        }

        auto swizzle = dContext->priv().caps()->getReadSwizzle(proxy->backendFormat(),
                                                               GrColorType::kRGBA_8888);
        return GrSurfaceProxyView(std::move(proxy), origin, swizzle);
    }

    return sk_gpu_test::MakeTextureProxyViewFromData(dContext,
                                                     GrRenderable::kNo,
                                                     origin,
                                                     src.pixmap());
}

// Create an over large texture which is initialized to opaque black outside of the content
// rect. The inside of the content rect consists of a grey coordinate frame lacking the -Y axis.
// The -X and +X axes have a red and green dot at their ends (respectively). Finally, the content
// rect has a 1-pixel wide blue border.
static SkBitmap create_bitmap(SkIRect contentRect, SkISize fullSize, GrSurfaceOrigin origin) {

    const int kContentSize = contentRect.width();
    SkBitmap contentBM;

    {
        SkImageInfo contentInfo = SkImageInfo::Make(kContentSize, kContentSize,
                                                    kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
        contentBM.allocPixels(contentInfo);

        contentBM.eraseColor(SK_ColorWHITE);

        const int halfM1 = kContentSize/2 - 1;

        // The coordinate frame
        contentBM.eraseArea(SkIRect::MakeXYWH(halfM1, 2,2, halfM1), SK_ColorGRAY);
        contentBM.eraseArea(SkIRect::MakeXYWH(2, halfM1, kContentSize-4, 2), SK_ColorGRAY);

        contentBM.eraseArea(SkIRect::MakeXYWH(2, halfM1, 2, 2), SK_ColorRED);
        contentBM.eraseArea(SkIRect::MakeXYWH(kContentSize-4, halfM1, 2, 2), SK_ColorGREEN);

        // The 1-pixel wide rim around the content rect
        contentBM.eraseArea(SkIRect::MakeXYWH(0, 0, kContentSize, 1), SK_ColorBLUE);
        contentBM.eraseArea(SkIRect::MakeXYWH(0, 0, 1, kContentSize), SK_ColorBLUE);
        contentBM.eraseArea(SkIRect::MakeXYWH(kContentSize-1, 0, 1, kContentSize), SK_ColorBLUE);
        contentBM.eraseArea(SkIRect::MakeXYWH(0, kContentSize-1, kContentSize, 1), SK_ColorBLUE);
    }

    SkBitmap bigBM;

    {
        const int kLeft = contentRect.fLeft;
        const int kTop  = contentRect.fTop;

        SkImageInfo bigInfo = SkImageInfo::Make(fullSize.fWidth, fullSize.fHeight,
                                                kRGBA_8888_SkColorType, kOpaque_SkAlphaType);

        bigBM.allocPixels(bigInfo);

        bigBM.eraseColor(SK_ColorBLACK);

        const char* src = static_cast<const char*>(contentBM.getPixels());
        size_t srcRB = contentBM.rowBytes();
        size_t dstRB = bigBM.rowBytes();

        if (USE_LAZY_PROXIES && origin == kBottomLeft_GrSurfaceOrigin) {
            char* dst = static_cast<char*>(bigBM.getAddr(kLeft, fullSize.height() - kTop - 1));
            for (int y = 0; y < contentBM.height(); ++y) {
                memcpy(dst, src, srcRB);
                src = src + srcRB;
                dst = dst - dstRB;
            }
        } else {
            char* dst = static_cast<char*>(bigBM.getAddr(kLeft, kTop));
            SkRectMemcpy(dst, dstRB, src, srcRB,
                         contentBM.rowBytes(), contentBM.height());
        }

        bigBM.setAlphaType(kOpaque_SkAlphaType);
        bigBM.setImmutable();
    }

    return bigBM;
}

static void draw_texture(const GrCaps* caps,
                         skgpu::ganesh::SurfaceDrawContext* sdc,
                         const GrSurfaceProxyView& src,
                         const SkIRect& srcRect,
                         const SkIRect& drawRect,
                         const SkMatrix& mat,
                         GrSamplerState::WrapMode xTileMode,
                         GrSamplerState::WrapMode yTileMode) {
    GrSamplerState sampler(xTileMode, yTileMode, SkFilterMode::kNearest);

    auto fp = GrTextureEffect::MakeSubset(src, kOpaque_SkAlphaType, mat,
                                          sampler, SkRect::Make(srcRect), *caps);
    GrPaint paint;
    paint.setColorFragmentProcessor(std::move(fp));

    sdc->drawRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(), SkRect::Make(drawRect));
}

namespace skiagm {

// This GM exercises all the different tile modes for a texture that cannot be normalized
// early (i.e., rectangle or fully-lazy).
// TODO: should we also test w/ mipmapping?
class LazyTilingGM : public GpuGM {
public:
    LazyTilingGM(GrSurfaceOrigin origin)
            : fOrigin(origin)
            , fContentRect(SkIRect::MakeXYWH(kLeftContentOffset, kTopContentOffset,
                                             kContentSize, kContentSize)) {
        this->setBGColor(0xFFCCCCCC);
    }

protected:
    SkString getName() const override {
        return SkStringPrintf("lazytiling_%s", fOrigin == kTopLeft_GrSurfaceOrigin ? "tl" : "bl");
    }

    SkISize getISize() override { return SkISize::Make(kTotalWidth, kTotalHeight); }

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

        auto bm = create_bitmap(fContentRect,
                                { kLeftContentOffset + kContentSize + kRightContentPadding,
                                  kTopContentOffset  + kContentSize + kBottomContentPadding },
                                fOrigin);

        fView = create_view(dContext, bm, fOrigin);
        if (!fView.proxy()) {
            *errorMsg = "Failed to create proxy";
            return DrawResult::kFail;
        }

        return DrawResult::kOk;
    }

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

        int y = kPad;
        for (auto yMode : { SkTileMode::kClamp, SkTileMode::kRepeat,
                            SkTileMode::kMirror, SkTileMode::kDecal }) {
            int x = kPad;
            for (auto xMode : { SkTileMode::kClamp, SkTileMode::kRepeat,
                                SkTileMode::kMirror, SkTileMode::kDecal }) {
                SkIRect cellRect = SkIRect::MakeXYWH(x, y, 2*kContentSize, 2*kContentSize);
                SkRect contentRect = SkRect::MakeXYWH(x+kContentSize/2, y+kContentSize/2,
                                                      kContentSize, kContentSize);

                SkMatrix texMatrix = SkMatrix::RectToRect(contentRect, SkRect::Make(fContentRect));

                draw_texture(rContext->priv().caps(),
                             sdc,
                             fView,
                             fContentRect,
                             cellRect,
                             texMatrix,
                             SkTileModeToWrapMode(xMode),
                             SkTileModeToWrapMode(yMode));

                x += 2*kContentSize+kPad;
            }

            y += 2*kContentSize+kPad;
        }

        return DrawResult::kOk;
    }

private:
    inline static constexpr int kLeftContentOffset = 8;
    inline static constexpr int kTopContentOffset = 16;
    inline static constexpr int kRightContentPadding = 24;
    inline static constexpr int kBottomContentPadding = 80;

    inline static constexpr int kPad = 4; // on-screen padding between cells

    inline static constexpr int kContentSize = 32;

    // Each cell in this GM's grid is a square - 2*kContentSize on a side
    inline static constexpr int kTotalWidth = (2*kContentSize+kPad) * kSkTileModeCount + kPad;
    inline static constexpr int kTotalHeight = (2*kContentSize+kPad) * kSkTileModeCount + kPad;

    GrSurfaceOrigin    fOrigin;
    SkIRect            fContentRect;
    GrSurfaceProxyView fView;

    using INHERITED = GM;
};

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

DEF_GM(return new LazyTilingGM(kTopLeft_GrSurfaceOrigin);)
DEF_GM(return new LazyTilingGM(kBottomLeft_GrSurfaceOrigin);)

}  // namespace skiagm
