/*
 * Copyright 2015 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/SkPaint.h"
#include "include/core/SkPath.h"
#include "include/core/SkPathBuilder.h"
#include "include/core/SkPathUtils.h"
#include "include/core/SkString.h"
#include "src/base/SkRandom.h"

class StrokeBench : public Benchmark {
public:
    StrokeBench(const SkPath& path, const SkPaint& paint, const char pathType[], SkScalar res)
        : fPath(path), fPaint(paint), fRes(res)
    {
        fName.printf("build_stroke_%s_%g_%d_%d",
                     pathType, paint.getStrokeWidth(), paint.getStrokeJoin(), paint.getStrokeCap());
    }

protected:
    bool isSuitableFor(Backend backend) override {
        return backend == Backend::kNonRendering;
    }

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

    void onDraw(int loops, SkCanvas* canvas) override {
        SkPaint paint(fPaint);
        this->setupPaint(&paint);

        const SkMatrix mx = SkMatrix::Scale(fRes, fRes);
        for (int outer = 0; outer < 10; ++outer) {
            for (int i = 0; i < loops; ++i) {
                SkPathBuilder result;
                skpathutils::FillPathWithPaint(fPath, paint, &result, nullptr, mx);
            }
        }
    }

private:
    SkPath      fPath;
    SkPaint     fPaint;
    SkString    fName;
    SkScalar    fRes;
    using INHERITED = Benchmark;
};

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

static const int N = 100;
static const SkScalar X = 100;
static const SkScalar Y = 100;

static SkPoint rand_pt(SkRandom& rand) {
    return SkPoint::Make(rand.nextSScalar1() * X, rand.nextSScalar1() * Y);
}

static SkPath line_path_maker() {
    SkPathBuilder builder;
    SkRandom rand;
    builder.moveTo(rand_pt(rand));
    for (int i = 0; i < N; ++i) {
        builder.lineTo(rand_pt(rand));
    }
    return builder.detach();
}
static SkPath quad_path_maker() {
    SkPathBuilder builder;
    SkRandom rand;
    builder.moveTo(rand_pt(rand));
    for (int i = 0; i < N; ++i) {
        builder.quadTo(rand_pt(rand), rand_pt(rand));
    }
    return builder.detach();
}
static SkPath conic_path_maker() {
    SkPathBuilder builder;
    SkRandom rand;
    builder.moveTo(rand_pt(rand));
    for (int i = 0; i < N; ++i) {
        builder.conicTo(rand_pt(rand), rand_pt(rand), rand.nextUScalar1());
    }
    return builder.detach();
}
static SkPath cubic_path_maker() {
    SkPathBuilder builder;
    SkRandom rand;
    builder.moveTo(rand_pt(rand));
    for (int i = 0; i < N; ++i) {
        builder.cubicTo(rand_pt(rand), rand_pt(rand), rand_pt(rand));
    }
    return builder.detach();
}

static SkPaint paint_maker() {
    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(X / 10);
    paint.setStrokeJoin(SkPaint::kMiter_Join);
    paint.setStrokeCap(SkPaint::kSquare_Cap);
    return paint;
}

DEF_BENCH(return new StrokeBench(line_path_maker(), paint_maker(), "line_1", 1);)
DEF_BENCH(return new StrokeBench(quad_path_maker(), paint_maker(), "quad_1", 1);)
DEF_BENCH(return new StrokeBench(conic_path_maker(), paint_maker(), "conic_1", 1);)
DEF_BENCH(return new StrokeBench(cubic_path_maker(), paint_maker(), "cubic_1", 1);)

DEF_BENCH(return new StrokeBench(line_path_maker(), paint_maker(), "line_4", 4);)
DEF_BENCH(return new StrokeBench(quad_path_maker(), paint_maker(), "quad_4", 4);)
DEF_BENCH(return new StrokeBench(conic_path_maker(), paint_maker(), "conic_4", 4);)
DEF_BENCH(return new StrokeBench(cubic_path_maker(), paint_maker(), "cubic_4", 4);)

DEF_BENCH(return new StrokeBench(line_path_maker(), paint_maker(), "line_.25", .25f);)
DEF_BENCH(return new StrokeBench(quad_path_maker(), paint_maker(), "quad_.25", .25f);)
DEF_BENCH(return new StrokeBench(conic_path_maker(), paint_maker(), "conic_.25", .25f);)
DEF_BENCH(return new StrokeBench(cubic_path_maker(), paint_maker(), "cubic_.25", .25f);)
