/*
 * 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/GrContext.h"
#include "samplecode/Sample.h"
#include "tools/timer/TimeUtils.h"

/**
 * This sample exercises heavy texture updates and uploads.
 */
class TextureUploadSample : public Sample {
    static constexpr int kMinTileSize = 128;
    static constexpr int kMaxTileSize = 2048;
    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;

    class RenderTargetTexture : public SkRefCnt {
    public:
        RenderTargetTexture(GrContext* context, int size) {
            SkSurfaceProps surfaceProps(SkSurfaceProps::kLegacyFontHost_InitType);
            SkImageInfo imageInfo = SkImageInfo::Make(size, size, kRGBA_8888_SkColorType,
                                                      kPremul_SkAlphaType);
            fSurface = SkSurface::MakeRenderTarget(context, SkBudgeted::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;
    };

    SkTArray<sk_sp<RenderTargetTexture>> fTextures;
    GrContext* fCachedContext = nullptr;
    SkScalar fActiveTileIndex = 0;

    SkString name() override {
        return SkString("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;
    }

    sk_sp<SkSurface> getFilledRasterSurface(SkColor color, int size) {
        sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(size, size));
        SkCanvas* canvas = surface->getCanvas();
        canvas->clear(color);
        return surface;
    }

    void onOnceBeforeDraw() override {
        this->setBGColor(0xFFFFFFFF);
        this->setSize(1024, 1024);
    }

    void initializeTextures(GrContext* context) {
        fTextures.reset();
        int textureCount = fTileRows * fTileCols;
        for (int i = 0; i < textureCount; i++) {
            fTextures.emplace_back(new RenderTargetTexture(context, 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);
    }

    void onDrawContent(SkCanvas* canvas) override {
#if SK_SUPPORT_GPU
        SkPaint paint;

        GrContext* context = canvas->getGrContext();
        if (context) {
            // One-time context-specific setup.
            if (context != fCachedContext) {
                fCachedContext = context;
                this->initializeTextures(context);
            }

            // 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, &paint);
                    }
                }
            }
        }
#endif
    }

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

const int TextureUploadSample::kMinTileSize;
const int TextureUploadSample::kMaxTileSize;

DEF_SAMPLE( return new TextureUploadSample(); )

