/*
 * Copyright 2017 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/SkCanvas.h"
#include "include/core/SkPath.h"
#include "include/pathops/SkPathOps.h"

class ClipStrategyBench : public Benchmark {
public:
    enum class Mode {
        kClipPath,
        kMask,
    };

    ClipStrategyBench(Mode mode, size_t count)
        : fMode(mode)
        , fCount(count)
        , fName("clip_strategy_"){

        if (fMode == Mode::kClipPath) {
            fName.append("path_");
            this->forEachClipCircle([&](float x, float y, float r) {
                fClipPath.addCircle(x, y, r);
            });
        } else {
            fName.append("mask_");
        }
        fName.appendf("%zu", count);
    }

    ~ClipStrategyBench() override = default;

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

    void onDraw(int loops, SkCanvas* canvas) override {
        SkPaint p, srcIn;
        p.setAntiAlias(true);
        srcIn.setBlendMode(SkBlendMode::kSrcIn);

        for (int i = 0; i < loops; ++i) {
            SkAutoCanvasRestore acr(canvas, false);

            if (fMode == Mode::kClipPath) {
                canvas->save();
                canvas->clipPath(fClipPath, true);
            } else {
                canvas->saveLayer(nullptr, nullptr);
                this->forEachClipCircle([&](float x, float y, float r) {
                    canvas->drawCircle(x, y, r, p);
                });
                canvas->saveLayer(nullptr, &srcIn);
            }
            canvas->drawColor(SK_ColorGREEN);
        }
    }

private:
    template <typename Func>
    void forEachClipCircle(Func&& func) {
        auto q = static_cast<float>(this->getSize().x()) / (fCount + 1);
        for (size_t i = 1; i <= fCount; ++i) {
            auto x = q * i;
            func(x, x, q / 2);
        }
    }

    Mode     fMode;
    size_t   fCount;
    SkString fName;
    SkPath   fClipPath;

    typedef Benchmark INHERITED;
};

DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kClipPath, 1  );)
DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kClipPath, 5  );)
DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kClipPath, 10 );)
DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kClipPath, 100);)

DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kMask, 1  );)
DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kMask, 5  );)
DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kMask, 10 );)
DEF_BENCH( return new ClipStrategyBench(ClipStrategyBench::Mode::kMask, 100);)
