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

#include "bench/Benchmark.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkShader.h"
#include "include/core/SkString.h"
#include "include/core/SkVertices.h"
#include "include/utils/SkRandom.h"
#include "tools/Resources.h"

// Just want to trigger perspective handling, not dramatically change size
static void tiny_persp_effect(SkCanvas* canvas) {
    SkMatrix m;
    m.reset();
    m[7] = 0.000001f;
    canvas->concat(m);
}

enum VertFlags {
    kColors_VertFlag  = 1 << 0,
    kTexture_VertFlag = 1 << 1,
    kPersp_VertFlag   = 1 << 2,
};

class VertBench : public Benchmark {
    SkString fName;
    enum {
        W = 64*2,
        H = 48*2,
        ROW = 20,
        COL = 20,
        PTS = (ROW + 1) * (COL + 1),
        IDX = ROW * COL * 6,
    };

    sk_sp<SkShader> fShader;
    SkPoint fPts[PTS];
    SkColor fColors[PTS];
    uint16_t fIdx[IDX];
    unsigned fFlags;

    static void load_2_tris(uint16_t idx[], int x, int y, int rb) {
        int n = y * rb + x;
        idx[0] = n; idx[1] = n + 1; idx[2] = rb + n + 1;
        idx[3] = n; idx[4] = rb + n + 1; idx[5] = n + rb;
    }

    void onDelayedSetup() override {
        auto img = GetResourceAsImage("images/mandrill_256.png");
        if (img) {
            fShader = img->makeShader();
        }
    }

public:
    VertBench(unsigned flags) : fFlags(flags) {
        const SkScalar dx = SkIntToScalar(W) / COL;
        const SkScalar dy = SkIntToScalar(H) / COL;

        SkPoint* pts = fPts;
        uint16_t* idx = fIdx;

        SkScalar yy = 0;
        for (int y = 0; y <= ROW; y++) {
            SkScalar xx = 0;
            for (int x = 0; x <= COL; ++x) {
                pts->set(xx, yy);
                pts += 1;
                xx += dx;

                if (x < COL && y < ROW) {
                    load_2_tris(idx, x, y, COL + 1);
                    for (int i = 0; i < 6; i++) {
                        SkASSERT(idx[i] < PTS);
                    }
                    idx += 6;
                }
            }
            yy += dy;
        }
        SkASSERT(PTS == pts - fPts);
        SkASSERT(IDX == idx - fIdx);

        SkRandom rand;
        for (int i = 0; i < PTS; ++i) {
            fColors[i] = rand.nextU() | (0xFF << 24);
        }

        fName.set("verts");
        if (fFlags & kTexture_VertFlag) {
            fName.append("_textures");
        }
        if (fFlags & kColors_VertFlag) {
            fName.append("_colors");
        }
        if (fFlags & kPersp_VertFlag) {
            fName.append("_persp");
        }
    }

protected:
    const char* onGetName() override { return fName.c_str(); }
    void onDraw(int loops, SkCanvas* canvas) override {
        SkPaint paint;
        this->setupPaint(&paint);
        paint.setShader(fShader);

        if (fFlags & kPersp_VertFlag) {
            tiny_persp_effect(canvas);
        }

        const SkPoint* texs = (fFlags & kTexture_VertFlag) ? fPts    : nullptr;
        const SkColor* cols = (fFlags & kColors_VertFlag)  ? fColors : nullptr;
        auto verts = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, PTS,
                                          fPts, texs, cols, IDX, fIdx);
        for (int i = 0; i < loops; i++) {
            canvas->drawVertices(verts, SkBlendMode::kModulate, paint);
        }
    }
private:
    typedef Benchmark INHERITED;
};
DEF_BENCH(return new VertBench(kTexture_VertFlag | kPersp_VertFlag);)
DEF_BENCH(return new VertBench(kColors_VertFlag  | kPersp_VertFlag);)
DEF_BENCH(return new VertBench(kTexture_VertFlag);)
DEF_BENCH(return new VertBench(kColors_VertFlag);)
DEF_BENCH(return new VertBench(kColors_VertFlag | kTexture_VertFlag);)

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

#include "include/core/SkRSXform.h"
#include "include/utils/SkRandom.h"
#include "tools/Resources.h"

enum AtlasFlags {
    kColors_Flag = 1 << 0,
    kRotate_Flag = 1 << 1,
    kPersp_Flag  = 1 << 2,
};

class AtlasBench : public Benchmark {
    unsigned fFlags;
    SkString fName;
    enum {
        W = 640,
        H = 480,
        N = 10*1000,
    };

    sk_sp<SkImage>  fAtlas;
    SkRSXform       fXforms[N];
    SkRect          fRects[N];
    SkColor         fColors[N];

public:
    AtlasBench(unsigned flags) : fFlags(flags) {
        fName.printf("drawAtlas");
        if (flags & kColors_Flag) {
            fName.append("_colors");
        }
        if (flags & kRotate_Flag) {
            fName.append("_rotated");
        }
        if (flags & kPersp_Flag) {
            fName.append("_persp");
        }
    }
    ~AtlasBench() override {}

protected:
    const char* onGetName() override { return fName.c_str(); }
    void onDelayedSetup() override {
        fAtlas = GetResourceAsImage("images/mandrill_256.png");
        if (fAtlas) {
            fAtlas = fAtlas->makeRasterImage();
        }

        const SkScalar imageW = fAtlas->width();
        const SkScalar imageH = fAtlas->height();
        SkScalar scos = 1;
        SkScalar ssin = 0;
        if (fFlags & kRotate_Flag) {
            scos = 0.866025403784439f;  // sqrt(3)/2
            ssin = 0.5f;
        }

        SkRandom rand;
        for (int i = 0; i < N; ++i) {
            fRects[i] = SkRect::MakeXYWH(rand.nextF() * (imageW - 8),
                                         rand.nextF() * (imageH - 8), 8, 8);
            fColors[i] = rand.nextU() | 0xFF000000;
            fXforms[i] = SkRSXform::Make(scos, ssin, rand.nextF() * W, rand.nextF() * H);
        }
    }
    void onDraw(int loops, SkCanvas* canvas) override {
        const SkRect* cullRect = nullptr;
        const SkPaint* paintPtr = nullptr;
        const SkColor* colors = nullptr;
        if (fFlags & kColors_Flag) {
            colors = fColors;
        }
        if (fFlags & kPersp_Flag) {
            tiny_persp_effect(canvas);
        }
        for (int i = 0; i < loops; i++) {
            canvas->drawAtlas(fAtlas, fXforms, fRects, colors, N, SkBlendMode::kModulate,
                              cullRect, paintPtr);
        }
    }
private:
    typedef Benchmark INHERITED;
};
//DEF_BENCH(return new AtlasBench(0);)
//DEF_BENCH(return new AtlasBench(kColors_Flag);)
DEF_BENCH(return new AtlasBench(0);)
DEF_BENCH(return new AtlasBench(kRotate_Flag);)
DEF_BENCH(return new AtlasBench(kPersp_Flag);)
DEF_BENCH(return new AtlasBench(kColors_Flag);)
DEF_BENCH(return new AtlasBench(kColors_Flag | kRotate_Flag);)

