/*
 * Copyright 2012 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/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkImage.h"
#include "include/core/SkM44.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"

// This bench simulates the calls Skia sees from various HTML5 canvas
// game bench marks
class GameBench : public Benchmark {
public:
    enum Type {
        kScale_Type,
        kTranslate_Type,
        kRotate_Type
    };

    enum Clear {
        kFull_Clear,
        kPartial_Clear
    };

    GameBench(Type type, Clear clear,
              bool aligned = false, bool useAtlas = false,
              bool useDrawVertices = false)
        : fType(type)
        , fClear(clear)
        , fAligned(aligned)
        , fUseAtlas(useAtlas)
        , fUseDrawVertices(useDrawVertices)
        , fName("game")
        , fNumSaved(0)
        , fInitialized(false) {

        switch (fType) {
        case kScale_Type:
            fName.append("_scale");
            break;
        case kTranslate_Type:
            fName.append("_trans");
            break;
        case kRotate_Type:
            fName.append("_rot");
            break;
        }

        if (aligned) {
            fName.append("_aligned");
        }

        if (kPartial_Clear == clear) {
            fName.append("_partial");
        } else {
            fName.append("_full");
        }

        if (useAtlas) {
            fName.append("_atlas");
        }

        if (useDrawVertices) {
            fName.append("_drawVerts");
        }

        // It's HTML 5 canvas, so always AA
        fName.append("_aa");
    }

protected:
    const char* onGetName() override {
        return fName.c_str();
    }

    void onDelayedSetup() override {
        if (!fInitialized) {
            this->makeCheckerboard();
            this->makeAtlas();
            fInitialized = true;
        }
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        SkRandom scaleRand;
        SkRandom transRand;
        SkRandom rotRand;

        int width, height;
        if (fUseAtlas) {
            width = kAtlasCellWidth;
            height = kAtlasCellHeight;
        } else {
            width = kCheckerboardWidth;
            height = kCheckerboardHeight;
        }

        SkPaint clearPaint;
        clearPaint.setColor(0xFF000000);
        clearPaint.setAntiAlias(true);

        SkISize size = canvas->getBaseLayerSize();

        SkScalar maxTransX, maxTransY;

        if (kScale_Type == fType) {
            maxTransX = size.fWidth  - (1.5f * width);
            maxTransY = size.fHeight - (1.5f * height);
        } else if (kTranslate_Type == fType) {
            maxTransX = SkIntToScalar(size.fWidth  - width);
            maxTransY = SkIntToScalar(size.fHeight - height);
        } else {
            SkASSERT(kRotate_Type == fType);
            // Yes, some rotations will be off the top and left sides
            maxTransX = size.fWidth  - SK_ScalarSqrt2 * height;
            maxTransY = size.fHeight - SK_ScalarSqrt2 * height;
        }

        SkMatrix mat;
        SkRect dst = { 0, 0, SkIntToScalar(width), SkIntToScalar(height) };
        SkRect clearRect = { -1.0f, -1.0f, width+1.0f, height+1.0f };
        SkPoint verts[4] = { // for drawVertices path
            { 0, 0 },
            { 0, SkIntToScalar(height) },
            { SkIntToScalar(width), SkIntToScalar(height) },
            { SkIntToScalar(width), 0 }
        };
        uint16_t indices[6] = { 0, 1, 2, 0, 2, 3 };

        SkPaint p;
        p.setColor(0xFF000000);

        SkPaint p2;         // for drawVertices path
        p2.setColor(0xFF000000);
        p2.setShader(fAtlas->makeShader(SkSamplingOptions(SkFilterMode::kLinear)));

        for (int i = 0; i < loops; ++i, ++fNumSaved) {
            if (0 == i % kNumBeforeClear) {
                if (kPartial_Clear == fClear) {
                    for (int j = 0; j < fNumSaved; ++j) {
                        canvas->setMatrix(SkMatrix::I());
                        mat.setTranslate(fSaved[j][0], fSaved[j][1]);

                        if (kScale_Type == fType) {
                            mat.preScale(fSaved[j][2], fSaved[j][2]);
                        } else if (kRotate_Type == fType) {
                            mat.preRotate(fSaved[j][2]);
                        }

                        canvas->concat(mat);
                        canvas->drawRect(clearRect, clearPaint);
                    }
                } else {
                    canvas->clear(0xFF000000);
                }

                fNumSaved = 0;
            }

            SkASSERT(fNumSaved < kNumBeforeClear);

            canvas->setMatrix(SkMatrix::I());

            fSaved[fNumSaved][0] = transRand.nextRangeScalar(0.0f, maxTransX);
            fSaved[fNumSaved][1] = transRand.nextRangeScalar(0.0f, maxTransY);
            if (fAligned) {
                // make the translations integer aligned
                fSaved[fNumSaved][0] = SkScalarFloorToScalar(fSaved[fNumSaved][0]);
                fSaved[fNumSaved][1] = SkScalarFloorToScalar(fSaved[fNumSaved][1]);
            }

            mat.setTranslate(fSaved[fNumSaved][0], fSaved[fNumSaved][1]);

            if (kScale_Type == fType) {
                fSaved[fNumSaved][2] = scaleRand.nextRangeScalar(0.5f, 1.5f);
                mat.preScale(fSaved[fNumSaved][2], fSaved[fNumSaved][2]);
            } else if (kRotate_Type == fType) {
                fSaved[fNumSaved][2] = rotRand.nextRangeScalar(0.0f, 360.0f);
                mat.preRotate(fSaved[fNumSaved][2]);
            }

            canvas->concat(mat);
            if (fUseAtlas) {
                const int curCell = i % (kNumAtlasedX * kNumAtlasedY);
                SkRect src = SkRect::Make(
                              fAtlasRects[curCell % (kNumAtlasedX)][curCell / (kNumAtlasedX)]);

                if (fUseDrawVertices) {
                    SkPoint uvs[4] = {
                        { SkIntToScalar(src.fLeft),  SkIntToScalar(src.fBottom) },
                        { SkIntToScalar(src.fLeft),  SkIntToScalar(src.fTop) },
                        { SkIntToScalar(src.fRight), SkIntToScalar(src.fTop) },
                        { SkIntToScalar(src.fRight), SkIntToScalar(src.fBottom) },
                    };
                    canvas->drawVertices(SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode,
                                                              4, verts, uvs, nullptr, 6, indices),
                                         SkBlendMode::kModulate, p2);
                } else {
                    canvas->drawImageRect(fAtlas, src, dst, SkSamplingOptions(), &p,
                                           SkCanvas::kFast_SrcRectConstraint);
                }
            } else {
                canvas->drawImageRect(fCheckerboard, dst, SkSamplingOptions(), &p);
            }
        }
    }

private:
    static const int kCheckerboardWidth = 64;
    static const int kCheckerboardHeight = 128;

    static const int kAtlasCellWidth = 48;
    static const int kAtlasCellHeight = 36;
    static const int kNumAtlasedX = 5;
    static const int kNumAtlasedY = 5;
    static const int kAtlasSpacer = 2;
    static const int kTotAtlasWidth  = kNumAtlasedX * kAtlasCellWidth +
                                       (kNumAtlasedX+1) * kAtlasSpacer;
    static const int kTotAtlasHeight = kNumAtlasedY * kAtlasCellHeight +
                                       (kNumAtlasedY+1) * kAtlasSpacer;
    static const int kNumBeforeClear = 100;

    Type     fType;
    Clear    fClear;
    bool     fAligned;
    bool     fUseAtlas;
    bool     fUseDrawVertices;
    SkString fName;
    int      fNumSaved; // num draws stored in 'fSaved'
    bool     fInitialized;

    // 0 & 1 are always x & y translate. 2 is either scale or rotate.
    SkScalar fSaved[kNumBeforeClear][3];

    sk_sp<SkImage> fCheckerboard, fAtlas;
    SkIRect  fAtlasRects[kNumAtlasedX][kNumAtlasedY];

    // Note: the resulting checker board has transparency
    void makeCheckerboard() {
        static int kCheckSize = 16;

        SkBitmap bm;
        bm.allocN32Pixels(kCheckerboardWidth, kCheckerboardHeight);
        for (int y = 0; y < kCheckerboardHeight; ++y) {
            int even = (y / kCheckSize) % 2;

            SkPMColor* scanline = bm.getAddr32(0, y);

            for (int x = 0; x < kCheckerboardWidth; ++x) {
                if (even == (x / kCheckSize) % 2) {
                    *scanline++ = 0xFFFF0000;
                } else {
                    *scanline++ = 0x00000000;
                }
            }
        }
        fCheckerboard = bm.asImage();
    }

    // Note: the resulting atlas has transparency
    void makeAtlas() {
        SkRandom rand;

        SkColor colors[kNumAtlasedX][kNumAtlasedY];

        for (int y = 0; y < kNumAtlasedY; ++y) {
            for (int x = 0; x < kNumAtlasedX; ++x) {
                colors[x][y] = rand.nextU() | 0xff000000;
                fAtlasRects[x][y] = SkIRect::MakeXYWH(kAtlasSpacer + x * (kAtlasCellWidth + kAtlasSpacer),
                                                      kAtlasSpacer + y * (kAtlasCellHeight + kAtlasSpacer),
                                                      kAtlasCellWidth,
                                                      kAtlasCellHeight);
            }
        }

        SkBitmap bm;
        bm.allocN32Pixels(kTotAtlasWidth, kTotAtlasHeight);

        for (int y = 0; y < kTotAtlasHeight; ++y) {
            int colorY = y / (kAtlasCellHeight + kAtlasSpacer);
            bool inColorY = (y % (kAtlasCellHeight + kAtlasSpacer)) >= kAtlasSpacer;

            SkPMColor* scanline = bm.getAddr32(0, y);

            for (int x = 0; x < kTotAtlasWidth; ++x, ++scanline) {
                int colorX = x / (kAtlasCellWidth + kAtlasSpacer);
                bool inColorX = (x % (kAtlasCellWidth + kAtlasSpacer)) >= kAtlasSpacer;

                if (inColorX && inColorY) {
                    SkASSERT(colorX < kNumAtlasedX && colorY < kNumAtlasedY);
                    *scanline = colors[colorX][colorY];
                } else {
                    *scanline = 0x00000000;
                }
            }
        }
        fAtlas = bm.asImage();
    }

    using INHERITED = Benchmark;
};

// Partial clear
DEF_BENCH(return new GameBench(GameBench::kScale_Type, GameBench::kPartial_Clear);)
DEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kPartial_Clear);)
DEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kPartial_Clear, true);)
DEF_BENCH(return new GameBench(GameBench::kRotate_Type, GameBench::kPartial_Clear);)

// Full clear
DEF_BENCH(return new GameBench(GameBench::kScale_Type, GameBench::kFull_Clear);)
DEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kFull_Clear);)
DEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kFull_Clear, true);)
DEF_BENCH(return new GameBench(GameBench::kRotate_Type, GameBench::kFull_Clear);)

// Atlased
DEF_BENCH(return new GameBench(GameBench::kTranslate_Type, GameBench::kFull_Clear, false, true);)
DEF_BENCH(return new GameBench(
                         GameBench::kTranslate_Type, GameBench::kFull_Clear, false, true, true);)


class CanvasMatrixBench : public Benchmark {
    SkString fName;
public:
    enum Type {
        kTranslate_Type,
        kScale_Type,
        k2x3_Type,
        k3x3_Type,
        k4x4_Type,
    };
    Type fType;

    CanvasMatrixBench(Type t) : fType(t) {
        fName.set("canvas_matrix");
        switch (fType) {
            case kTranslate_Type: fName.append("_trans"); break;
            case kScale_Type:     fName.append("_scale"); break;
            case k2x3_Type:       fName.append("_2x3"); break;
            case k3x3_Type:       fName.append("_3x3"); break;
            case k4x4_Type:       fName.append("_4x4"); break;
        }
    }

protected:
    const char* onGetName() override {
        return fName.c_str();
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        SkMatrix m;
        m.setRotate(1);
        if (fType == k3x3_Type) {
            m[7] = 0.0001f;
        }
        SkM44 m4(m);

        for (int i = 0; i < loops; ++i) {
            canvas->save();
            for (int j = 0; j < 10000; ++j) {
                switch (fType) {
                    case kTranslate_Type: canvas->translate(0.0001f, 0.0001f); break;
                    case kScale_Type:     canvas->scale(1.0001f, 0.9999f); break;
                    case k2x3_Type:       canvas->concat(m); break;
                    case k3x3_Type:       canvas->concat(m); break;
                    case k4x4_Type:       canvas->concat(m4); break;
                }
            }
            canvas->restore();
        }
    }

private:
    using INHERITED = Benchmark;
};

DEF_BENCH(return new CanvasMatrixBench(CanvasMatrixBench::kTranslate_Type));
DEF_BENCH(return new CanvasMatrixBench(CanvasMatrixBench::kScale_Type));
DEF_BENCH(return new CanvasMatrixBench(CanvasMatrixBench::k2x3_Type));
DEF_BENCH(return new CanvasMatrixBench(CanvasMatrixBench::k3x3_Type));
DEF_BENCH(return new CanvasMatrixBench(CanvasMatrixBench::k4x4_Type));
