/*
 * 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 "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 == 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);)
