/*
 * 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,
    kBilerp_VertFlag  = 1 << 3,
};

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], fTex[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 {
        if (fFlags & kTexture_VertFlag) {
            auto img = GetResourceAsImage("images/mandrill_256.png");
            if (img) {
                SkFilterMode fm = (fFlags & kBilerp_VertFlag) ? SkFilterMode::kLinear
                                                              : SkFilterMode::kNearest;
                fShader = img->makeShader(SkSamplingOptions(fm));
            }
        }
    }

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);

        // We want to store texs in a separate array, so the blitters don't "cheat" and
        // skip the (normal) step of computing the new local-matrix. This is the common case
        // we think in the wild (where the texture coordinates are different from the positions.
        memcpy(fTex, fPts, sizeof(fPts));

        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");
        }
        if (fFlags & kBilerp_VertFlag) {
            fName.append("_bilerp");
        }
    }

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) ? fTex    : 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:
    using INHERITED = Benchmark;
};
DEF_BENCH(return new VertBench(kTexture_VertFlag | kPersp_VertFlag);)
DEF_BENCH(return new VertBench(kTexture_VertFlag | kPersp_VertFlag | kBilerp_VertFlag);)
DEF_BENCH(return new VertBench(kColors_VertFlag  | kPersp_VertFlag);)
DEF_BENCH(return new VertBench(kTexture_VertFlag);)
DEF_BENCH(return new VertBench(kTexture_VertFlag | kBilerp_VertFlag);)
DEF_BENCH(return new VertBench(kColors_VertFlag);)
DEF_BENCH(return new VertBench(kColors_VertFlag | kTexture_VertFlag);)
DEF_BENCH(return new VertBench(kColors_VertFlag | kTexture_VertFlag | kBilerp_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.get(), fXforms, fRects, colors, N, SkBlendMode::kModulate,
                              SkSamplingOptions(), cullRect, paintPtr);
        }
    }
private:
    using INHERITED = Benchmark;
};
//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);)

