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

#include "Benchmark.h"
#include "SkCanvas.h"
#include "SkCommandLineFlags.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkRRect.h"
#include "SkString.h"
#include <stdio.h>
#include <stdlib.h>
#include <functional>

#define ENABLE_COMMAND_LINE_SHAPES_BENCH 0

#if ENABLE_COMMAND_LINE_SHAPES_BENCH
DEFINE_string(shapesType, "mixed", "Type of shape to use in ShapesBench. Must be one of: "
                                   "rect, oval, rrect, mixed.");
DEFINE_string(innerShapesType, "none", "Type of inner shape to use in ShapesBench. Must be one of: "
                                       "none, rect, oval, rrect, mixed.");
DEFINE_int32(numShapes, 10000, "Number of shapes to draw in ShapesBench.");
DEFINE_string(shapesSize, "32x32", "Size of shapes to draw in ShapesBench.");
DEFINE_bool(shapesPersp, false, "Use slight perspective tilt in ShapesBench?");
#endif

/*
 * This class is used for several benchmarks that draw different primitive Skia shapes at various
 * sizes. It is used to test both CPU-bound and GPU-bound rendering situations. It draws large
 * amounts of shapes internally (rather than relying on nanobench selecting lots of loops) in order
 * to take advantage of instanced rendering approaches.
 */
class ShapesBench : public Benchmark {
public:
    enum ShapesType {
        kNone_ShapesType,
        kRect_ShapesType,
        kOval_ShapesType,
        kRRect_ShapesType,
        kMixed_ShapesType
    };

    ShapesBench(ShapesType shapesType, ShapesType innerShapesType,
                int numShapes, const SkISize& shapesSize, bool perspective)
        : fShapesType(shapesType)
        , fInnerShapesType(innerShapesType)
        , fNumShapes(numShapes)
        , fShapesSize(shapesSize)
        , fPerspective(perspective) {
        clampShapeSize();
    }

#if ENABLE_COMMAND_LINE_SHAPES_BENCH
    ShapesBench() {
        if (!strcmp(FLAGS_shapesType[0], "rect")) {
            fShapesType = kRect_ShapesType;
        } else if (!strcmp(FLAGS_shapesType[0], "oval")) {
            fShapesType = kOval_ShapesType;
        } else if (!strcmp(FLAGS_shapesType[0], "rrect")) {
            fShapesType = kRRect_ShapesType;
        } else if (!strcmp(FLAGS_shapesType[0], "mixed")) {
            fShapesType = kMixed_ShapesType;
        } else {
            SkDebugf("Invalid shapesType \"%s\". Must be one of: rect, oval, rrect, mixed.",
                     FLAGS_shapesType[0]);
            exit(-1);
        }
        if (!strcmp(FLAGS_innerShapesType[0], "none")) {
            fInnerShapesType = kNone_ShapesType;
        } else if (!strcmp(FLAGS_innerShapesType[0], "rect")) {
            fInnerShapesType = kRect_ShapesType;
        } else if (!strcmp(FLAGS_innerShapesType[0], "oval")) {
            fInnerShapesType = kOval_ShapesType;
        } else if (!strcmp(FLAGS_innerShapesType[0], "rrect")) {
            fInnerShapesType = kRRect_ShapesType;
        } else if (!strcmp(FLAGS_innerShapesType[0], "mixed")) {
            fInnerShapesType = kMixed_ShapesType;
        } else {
            SkDebugf("Invalid innerShapesType \"%s\". Must be one of: "
                     "none, rect, oval, rrect, mixed.", FLAGS_innerShapesType[0]);
            exit(-1);
        }
        if (2 != sscanf(FLAGS_shapesSize[0], "%ix%i", &fShapesSize.fWidth, &fShapesSize.fHeight)) {
            SkDebugf("Could not parse shapesSize from \"%s\". Expected \"%%ix%%i\"\n",
                     FLAGS_shapesSize[0]);
            exit(-1);
        }

        fNumShapes = FLAGS_numShapes;
        fPerspective = FLAGS_shapesPersp;

        clampShapeSize();
    }
#endif

    bool isVisual() override { return true; }

private:
    void clampShapeSize() {
        float maxDiagonal = static_cast<float>(SkTMin(kBenchWidth, kBenchHeight));
        float diagonal = sqrtf(static_cast<float>(fShapesSize.width() * fShapesSize.width()) +
                               static_cast<float>(fShapesSize.height() * fShapesSize.height()));
        if (diagonal > maxDiagonal) {
            fShapesSize.fWidth = static_cast<int>(fShapesSize.width() * maxDiagonal / diagonal);
            fShapesSize.fHeight = static_cast<int>(fShapesSize.height() * maxDiagonal / diagonal);
        }
    }

    const char* onGetName() override {
        const char* shapeTypeNames[] = {
            "none", "rect", "oval", "rrect", "mixed"
        };

        fName.printf("shapes_%s", shapeTypeNames[fShapesType]);

        if (kNone_ShapesType != fInnerShapesType) {
            fName.appendf("_inner_%s", shapeTypeNames[fInnerShapesType]);
        }

        fName.appendf("_%i_%ix%i", fNumShapes, fShapesSize.width(), fShapesSize.height());

        if (fPerspective) {
            fName.append("_persp");
        }

        return fName.c_str();
    }
    SkIPoint onGetSize() override { return SkIPoint::Make(kBenchWidth, kBenchHeight); }

    void onDelayedSetup() override {
        SkScalar w = SkIntToScalar(fShapesSize.width());
        SkScalar h = SkIntToScalar(fShapesSize.height());

        fRect.setRect(SkRect::MakeXYWH(-w / 2, -h / 2, w, h));
        fOval.setOval(fRect.rect());
        fRRect.setNinePatch(fRect.rect(), w / 8, h / 13, w / 11, h / 7);

        if (kNone_ShapesType != fInnerShapesType) {
            fRect.inset(w / 7, h / 11, &fInnerRect);
            fInnerRect.offset(w / 28, h / 44);
            fInnerOval.setOval(fInnerRect.rect());
            fInnerRRect.setRectXY(fInnerRect.rect(), w / 13, w / 7);
        }

        SkRandom rand;
        fShapes.push_back_n(fNumShapes);
        for (int i = 0; i < fNumShapes; i++) {
            float pad = sqrtf(static_cast<float>(fShapesSize.width() * fShapesSize.width()) +
                              static_cast<float>(fShapesSize.height() * fShapesSize.height()));
            fShapes[i].fMatrix.setTranslate(0.5f * pad + rand.nextF() * (kBenchWidth - pad),
                                            0.5f * pad + rand.nextF() * (kBenchHeight - pad));
            fShapes[i].fMatrix.preRotate(rand.nextF() * 360.0f);
            if (fPerspective) {
                fShapes[i].fMatrix.setPerspX(0.00015f);
                fShapes[i].fMatrix.setPerspY(-0.00015f);
            }
            fShapes[i].fColor = rand.nextU() | 0xff808080;
        }
        for (int i = 0; i < fNumShapes; i++) {
            // Do this in a separate loop so mixed shapes get the same random numbers during
            // placement as non-mixed do.
            int shapeType = fShapesType;
            if (kMixed_ShapesType == shapeType) {
                shapeType = rand.nextRangeU(kRect_ShapesType, kRRect_ShapesType);
            }
            int innerShapeType = fInnerShapesType;
            if (kMixed_ShapesType == innerShapeType) {
                innerShapeType = rand.nextRangeU(kRect_ShapesType, kRRect_ShapesType);
            }
            if (kNone_ShapesType == innerShapeType) {
                switch (shapeType) {
                    using namespace std;
                    using namespace std::placeholders;
                    case kRect_ShapesType:
                        fShapes[i].fDraw = bind(&SkCanvas::drawRect, _1, cref(fRect.rect()), _2);
                        break;
                    case kOval_ShapesType:
                        fShapes[i].fDraw = bind(&SkCanvas::drawOval, _1, cref(fOval.rect()), _2);
                        break;
                    case kRRect_ShapesType:
                        fShapes[i].fDraw = bind(&SkCanvas::drawRRect, _1, cref(fRRect), _2);
                        break;
                }
            } else {
                const SkRRect* outer;
                switch (shapeType) {
                    case kRect_ShapesType: outer = &fRect; break;
                    case kOval_ShapesType: outer = &fOval; break;
                    case kRRect_ShapesType: outer = &fRRect; break;
                }
                const SkRRect* inner;
                switch (innerShapeType) {
                    case kRect_ShapesType: inner = &fInnerRect; break;
                    case kOval_ShapesType: inner = &fInnerOval; break;
                    case kRRect_ShapesType: inner = &fInnerRRect; break;
                }
                fShapes[i].fDraw = std::bind(&SkCanvas::drawDRRect, std::placeholders::_1,
                                             std::cref(*outer), std::cref(*inner),
                                             std::placeholders::_2);
            }
        }
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        SkPaint paint;
        this->setupPaint(&paint);
        for (int j = 0; j < loops; j++) {
            for (int i = 0; i < fNumShapes; i++) {
                canvas->save();
                canvas->setMatrix(fShapes[i].fMatrix);
                paint.setColor(fShapes[i].fColor);
                fShapes[i].fDraw(canvas, paint);
                canvas->restore();
            }
        }
    }

    enum {
        kBenchWidth = 1000,
        kBenchHeight = 1000
    };

    struct ShapeInfo {
        SkMatrix   fMatrix;
        SkColor    fColor;
        std::function<void(SkCanvas*, const SkPaint&)> fDraw;
    };

    ShapesType            fShapesType;
    ShapesType            fInnerShapesType;
    int                   fNumShapes;
    SkISize               fShapesSize;
    bool                  fPerspective;
    SkString              fName;
    SkRRect               fRect;
    SkRRect               fOval;
    SkRRect               fRRect;
    SkRRect               fInnerRect;
    SkRRect               fInnerOval;
    SkRRect               fInnerRRect;
    SkTArray<ShapeInfo>   fShapes;


    typedef Benchmark INHERITED;
};

#if ENABLE_COMMAND_LINE_SHAPES_BENCH
DEF_BENCH(return new ShapesBench;)
#else
// Small primitives (CPU bound, in theory):
DEF_BENCH(return new ShapesBench(ShapesBench::kRect_ShapesType, ShapesBench::kNone_ShapesType,
                                 10000, SkISize::Make(32, 32), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType,
                                 10000, SkISize::Make(32, 32), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType,
                                 10000, SkISize::Make(32, 33), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kRRect_ShapesType, ShapesBench::kNone_ShapesType,
                                 10000, SkISize::Make(32, 32), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kMixed_ShapesType, ShapesBench::kNone_ShapesType,
                                 10000, SkISize::Make(32, 33), false);)

// Large primitives (GPU bound, in theory):
DEF_BENCH(return new ShapesBench(ShapesBench::kRect_ShapesType, ShapesBench::kNone_ShapesType,
                                 100, SkISize::Make(500, 500), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType,
                                 100, SkISize::Make(500, 500), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType,
                                 100, SkISize::Make(500, 501), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kRRect_ShapesType, ShapesBench::kNone_ShapesType,
                                 100, SkISize::Make(500, 500), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kMixed_ShapesType, ShapesBench::kNone_ShapesType,
                                 100, SkISize::Make(500, 501), false);)

// Donuts (small and large). These fall-back to path rendering due to non-orthogonal rotation
// making them quite slow. Thus, reduce the counts substantially:
DEF_BENCH(return new ShapesBench(ShapesBench::kRect_ShapesType, ShapesBench::kRect_ShapesType,
                                 500, SkISize::Make(32, 32), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kRRect_ShapesType, ShapesBench::kRRect_ShapesType,
                                 500, SkISize::Make(32, 32), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kRect_ShapesType, ShapesBench::kRect_ShapesType,
                                 50, SkISize::Make(500, 500), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kRRect_ShapesType, ShapesBench::kRRect_ShapesType,
                                 50, SkISize::Make(500, 500), false);)
#endif
