/*
 * 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/SkPathUtils.h"
#include "include/core/SkString.h"
#include "include/utils/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 == kNonRendering_Backend;
    }

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

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

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

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() {
    SkPath path;
    SkRandom rand;
    path.moveTo(rand_pt(rand));
    for (int i = 0; i < N; ++i) {
        path.lineTo(rand_pt(rand));
    }
    return path;
}
static SkPath quad_path_maker() {
    SkPath path;
    SkRandom rand;
    path.moveTo(rand_pt(rand));
    for (int i = 0; i < N; ++i) {
        path.quadTo(rand_pt(rand), rand_pt(rand));
    }
    return path;
}
static SkPath conic_path_maker() {
    SkPath path;
    SkRandom rand;
    path.moveTo(rand_pt(rand));
    for (int i = 0; i < N; ++i) {
        path.conicTo(rand_pt(rand), rand_pt(rand), rand.nextUScalar1());
    }
    return path;
}
static SkPath cubic_path_maker() {
    SkPath path;
    SkRandom rand;
    path.moveTo(rand_pt(rand));
    for (int i = 0; i < N; ++i) {
        path.cubicTo(rand_pt(rand), rand_pt(rand), rand_pt(rand));
    }
    return path;
}

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