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

#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "tools/timer/TimeUtils.h"
#include "tools/viewer/Slide.h"

using namespace skia_private;

/**
 * This sample exercises heavy texture updates and uploads.
 */
class TextureUploadSlide : public Slide {
public:
    TextureUploadSlide() { fName = "TextureUpload"; }

    bool onChar(SkUnichar uni) override {
        if ('m' == uni) {
            fDrawTexturesToScreen = !fDrawTexturesToScreen;
            return true;
        } else if ('>' == uni) {
            fTileSize = std::min(kMaxTileSize, 2*fTileSize);
            fTileRows = kMaxTileSize/fTileSize;
            fTileCols = kMaxTileSize/fTileSize;
            fCachedContext = nullptr;
        } else if ('<' == uni) {
            fTileSize = std::max(kMinTileSize, fTileSize/2);
            fTileRows = kMaxTileSize/fTileSize;
            fTileCols = kMaxTileSize/fTileSize;
            fCachedContext = nullptr;
        }
        return false;
    }

    SkISize getDimensions() const override { return {1024, 1024}; }

    void draw(SkCanvas* canvas) override {
        canvas->clear(0xFFFFFFFF);
#if defined(SK_GANESH)
        auto direct = GrAsDirectContext(canvas->recordingContext());
        if (direct) {
            // One-time context-specific setup.
            if (direct != fCachedContext) {
                fCachedContext = direct;
                this->initializeTextures(direct);
            }

            // Upload new texture data for all textures, simulating a full page of tiles
            // needing refresh.
            int textureCount = fTileRows * fTileCols;
            for (int i = 0; i < textureCount; i++) {
                fTextures[i]->uploadRasterSurface(i == fActiveTileIndex ? fBlueSurface
                                                                        : fGraySurface);
            }

            // Scale grid.
            canvas->scale(kGridScale, kGridScale);

            if (fDrawTexturesToScreen) {
                for (int y = 0; y < fTileRows; y++) {
                    for (int x = 0; x < fTileCols; x++) {
                        int currentIndex = y * fTileCols + x;
                        canvas->drawImage(fTextures[currentIndex]->getImage(),
                                          x * fTileSize, y * fTileSize);
                    }
                }
            }
        }
#endif
    }

    bool animate(double nanos) override {
        constexpr SkScalar kDesiredDurationSecs = 16.0f;
        float numTiles = fTileRows*fTileCols;
        fActiveTileIndex = floorf(TimeUtils::Scaled(1e-9 * nanos,
                                                    numTiles/kDesiredDurationSecs, numTiles));
        return true;
    }

private:
    class RenderTargetTexture : public SkRefCnt {
    public:
        RenderTargetTexture(GrDirectContext* direct, int size) {
            SkSurfaceProps surfaceProps(0, kRGB_H_SkPixelGeometry);
            SkImageInfo imageInfo = SkImageInfo::Make(size, size, kRGBA_8888_SkColorType,
                                                      kPremul_SkAlphaType);
            fSurface = SkSurfaces::RenderTarget(
                    direct, skgpu::Budgeted::kNo, imageInfo, 0, &surfaceProps);
        }

        sk_sp<SkImage> getImage() {
            return fSurface->makeImageSnapshot();
        }

        void uploadRasterSurface(sk_sp<SkSurface> rasterSurface) {
            SkPixmap pixmap;
            rasterSurface->peekPixels(&pixmap);
            fSurface->writePixels(pixmap, 0, 0);
        }

    private:
        sk_sp<SkSurface> fSurface;
        sk_sp<SkImage> fCachedImage;
    };

    inline static constexpr int kMinTileSize = 128;
    inline static constexpr int kMaxTileSize = 2048;
    inline static constexpr float kGridScale = 0.25f;

    bool fDrawTexturesToScreen = true;
    int fTileSize = 256;
    int fTileRows = 8;
    int fTileCols = 8;

    sk_sp<SkSurface> fBlueSurface;
    sk_sp<SkSurface> fGraySurface;

    TArray<sk_sp<RenderTargetTexture>> fTextures;

    GrDirectContext* fCachedContext = nullptr;

    SkScalar fActiveTileIndex = 0;

    sk_sp<SkSurface> getFilledRasterSurface(SkColor color, int size) {
        sk_sp<SkSurface> surface(SkSurfaces::Raster(SkImageInfo::MakeN32Premul(size, size)));
        SkCanvas* canvas = surface->getCanvas();
        canvas->clear(color);
        return surface;
    }
    void initializeTextures(GrDirectContext* direct) {
        fTextures.clear();
        int textureCount = fTileRows * fTileCols;
        for (int i = 0; i < textureCount; i++) {
            fTextures.emplace_back(new RenderTargetTexture(direct, fTileSize));
        }

        // Construct two simple rasters of differing colors to serve
        // as cpu rasterized data to refresh textures with.
        fBlueSurface = this->getFilledRasterSurface(SK_ColorBLUE, fTileSize);
        fGraySurface = this->getFilledRasterSurface(SK_ColorGRAY, fTileSize);
    }
};


DEF_SLIDE( return new TextureUploadSlide(); )

