
/*
 * 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;
};

// 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,
                                 1000, SkISize::Make(500, 500), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType,
                                 1000, SkISize::Make(500, 500), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kOval_ShapesType, ShapesBench::kNone_ShapesType,
                                 1000, SkISize::Make(500, 501), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kRRect_ShapesType, ShapesBench::kNone_ShapesType,
                                 1000, SkISize::Make(500, 500), false);)
DEF_BENCH(return new ShapesBench(ShapesBench::kMixed_ShapesType, ShapesBench::kNone_ShapesType,
                                 1000, 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);)

#if ENABLE_COMMAND_LINE_SHAPES_BENCH
DEF_BENCH(return new ShapesBench;)
#endif
