/*
 * Copyright 2011 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/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkShader.h"
#include "include/core/SkString.h"
#include "include/effects/SkGradientShader.h"
#include "include/utils/SkRandom.h"
#include "tools/flags/CommandLineFlags.h"

static DEFINE_double(strokeWidth, -1.0, "If set, use this stroke width in RectBench.");

class RectBench : public Benchmark {
public:
    int fShift, fStroke;
    enum {
        W = 640,
        H = 480,
        N = 300,
    };
    SkRect  fRects[N];
    SkColor fColors[N];
    bool    fAA;
    bool    fPerspective;

    RectBench(int shift, int stroke = 0, bool aa = true, bool perspective = false)
        : fShift(shift)
        , fStroke(stroke)
        , fAA(aa)
        , fPerspective(perspective) {}

    const char* computeName(const char root[]) {
        fBaseName.printf("%s_%d", root, fShift);
        if (fStroke > 0) {
            fBaseName.appendf("_stroke_%d", fStroke);
        }
        if (fAA) {
            fBaseName.appendf("_aa");
        } else {
            fBaseName.appendf("_bw");
        }
        if (fPerspective) {
            fBaseName.appendf("_persp");
        }
        return fBaseName.c_str();
    }

protected:

    virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
        c->drawRect(r, p);
    }

    const char* onGetName() override { return computeName("rects"); }

    void onDelayedSetup() override {
        SkRandom rand;
        const SkScalar offset = SK_Scalar1/3;
        for (int i = 0; i < N; i++) {
            int x = rand.nextU() % W;
            int y = rand.nextU() % H;
            int w = rand.nextU() % W;
            int h = rand.nextU() % H;
            w >>= fShift;
            h >>= fShift;
            x -= w/2;
            y -= h/2;
            fRects[i].setXYWH(SkIntToScalar(x), SkIntToScalar(y),
                              SkIntToScalar(w), SkIntToScalar(h));
            fRects[i].offset(offset, offset);
            fColors[i] = rand.nextU() | 0xFF808080;
        }
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        SkPaint paint;
        if (fStroke > 0) {
            paint.setStyle(SkPaint::kStroke_Style);
            paint.setStrokeWidth(SkIntToScalar(fStroke));
        }
        if (fPerspective) {
            // Apply some fixed perspective to change how ops may draw the rects
            SkMatrix perspective;
            perspective.setIdentity();
            perspective.setPerspX(1e-4f);
            perspective.setPerspY(1e-3f);
            perspective.setSkewX(0.1f);
            canvas->concat(perspective);
        }
        for (int i = 0; i < loops; i++) {
            paint.setColor(fColors[i % N]);
            this->setupPaint(&paint);
            this->drawThisRect(canvas, fRects[i % N], paint);
        }
    }

    void setupPaint(SkPaint* paint) override {
        this->INHERITED::setupPaint(paint);
        paint->setAntiAlias(fAA);
    }

private:
    SkString fBaseName;
    using INHERITED = Benchmark;
};

class SrcModeRectBench : public RectBench {
public:
    SrcModeRectBench() : INHERITED(1, 0) {
        fMode = SkBlendMode::kSrc;
    }

protected:
    void setupPaint(SkPaint* paint) override {
        this->INHERITED::setupPaint(paint);
        // srcmode is most interesting when we're not opaque
        paint->setAlpha(0x80);
        paint->setBlendMode(fMode);
    }

    const char* onGetName() override {
        fName.set(this->INHERITED::onGetName());
        fName.prepend("srcmode_");
        return fName.c_str();
    }

private:
    SkBlendMode fMode;
    SkString fName;

    using INHERITED = RectBench;
};

class TransparentRectBench : public RectBench {
public:
    TransparentRectBench() : INHERITED(1, 0) {}

protected:
    void setupPaint(SkPaint* paint) override {
        this->INHERITED::setupPaint(paint);
        // draw non opaque rect
        paint->setAlpha(0x80);
    }

    const char* onGetName() override {
        fName.set(this->INHERITED::onGetName());
        fName.prepend("transparent_");
        return fName.c_str();
    }

private:
    SkString fName;
    using INHERITED = RectBench;
};

// Adds a shader to the paint that requires local coordinates to be used
class LocalCoordsRectBench : public RectBench {
public:
    LocalCoordsRectBench(bool aa, bool perspective = false) : INHERITED(1, 0, aa, perspective) { }

protected:
    void onDelayedSetup() override {
        this->INHERITED::onDelayedSetup();
        // Create the shader once, so that isn't included in the timing
        SkPoint pts[2] = { {0.f, 0.f}, {50.f, 50.f} };
        SkColor colors[] = { SK_ColorWHITE, SK_ColorBLUE };
        fShader = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
    }

    void setupPaint(SkPaint* paint) override {
        this->INHERITED::setupPaint(paint);
        paint->setShader(fShader);
    }

    const char* onGetName() override {
        fName.set(this->INHERITED::onGetName());
        fName.append("_localcoords");
        return fName.c_str();
    }

private:
    SkString fName;
    sk_sp<SkShader> fShader;

    using INHERITED = RectBench;
};


class OvalBench : public RectBench {
public:
    OvalBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
protected:
    void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
        c->drawOval(r, p);
    }
    const char* onGetName() override { return computeName("ovals"); }
};

class RRectBench : public RectBench {
public:
    RRectBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
protected:
    void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
        c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
    }
    const char* onGetName() override { return computeName("rrects"); }
};

class PointsBench : public RectBench {
public:
    SkCanvas::PointMode fMode;

    PointsBench(SkCanvas::PointMode mode, const char* name)
        : RectBench(2)
        , fMode(mode) {
        fName = name;
    }

protected:
    void onDraw(int loops, SkCanvas* canvas) override {
        SkScalar gSizes[] = {
            SkIntToScalar(7), 0
        };
        size_t sizes = std::size(gSizes);

        if (FLAGS_strokeWidth >= 0) {
            gSizes[0] = (SkScalar)FLAGS_strokeWidth;
            sizes = 1;
        }

        SkPaint paint;
        paint.setStrokeCap(SkPaint::kRound_Cap);

        for (int loop = 0; loop < loops; loop++) {
            for (size_t i = 0; i < sizes; i++) {
                paint.setStrokeWidth(gSizes[i]);
                this->setupPaint(&paint);
                canvas->drawPoints(fMode, N * 2, reinterpret_cast<SkPoint*>(fRects), paint);
                paint.setColor(fColors[i % N]);
            }
        }
    }
    const char* onGetName() override { return fName.c_str(); }

private:
    SkString fName;

};

/*******************************************************************************
 * to bench BlitMask [Opaque, Black, color, shader]
 *******************************************************************************/

class BlitMaskBench : public RectBench {
public:
    enum kMaskType {
        kMaskOpaque = 0,
        kMaskBlack,
        kMaskColor,
        KMaskShader
    };
    SkCanvas::PointMode fMode;

    BlitMaskBench(SkCanvas::PointMode mode,
                  BlitMaskBench::kMaskType type, const char* name) :
        RectBench(2), fMode(mode), _type(type) {
        fName = name;
    }

protected:
    void onDraw(int loops, SkCanvas* canvas) override {
        SkScalar gSizes[] = {
            SkIntToScalar(13), SkIntToScalar(24)
        };
        size_t sizes = std::size(gSizes);

        if (FLAGS_strokeWidth >= 0) {
            gSizes[0] = (SkScalar)FLAGS_strokeWidth;
            sizes = 1;
        }
        SkRandom rand;
        SkColor color = 0xFF000000;
        U8CPU alpha = 0xFF;
        SkPaint paint;
        paint.setStrokeCap(SkPaint::kRound_Cap);
        if (_type == KMaskShader) {
            SkBitmap srcBM;
            srcBM.allocN32Pixels(10, 1);
            srcBM.eraseColor(0xFF00FF00);

            paint.setShader(srcBM.makeShader(SkSamplingOptions()));
        }
        for (int loop = 0; loop < loops; loop++) {
            for (size_t i = 0; i < sizes; i++) {
                switch (_type) {
                    case kMaskOpaque:
                        color = fColors[i];
                        alpha = 0xFF;
                        break;
                    case kMaskBlack:
                        alpha = 0xFF;
                        color = 0xFF000000;
                        break;
                    case kMaskColor:
                        color = fColors[i];
                        alpha = rand.nextU() & 255;
                        break;
                    case KMaskShader:
                        break;
                }
                paint.setStrokeWidth(gSizes[i]);
                this->setupPaint(&paint);
                paint.setColor(color);
                paint.setAlpha(alpha);
                canvas->drawPoints(fMode, N * 2, reinterpret_cast<SkPoint*>(fRects), paint);
           }
        }
    }
    const char* onGetName() override { return fName.c_str(); }

private:
    using INHERITED = RectBench;
    kMaskType _type;
    SkString fName;
};

// AA rects
DEF_BENCH(return new RectBench(1, 0, true);)
DEF_BENCH(return new RectBench(1, 4, true);)
DEF_BENCH(return new RectBench(3, 0, true);)
DEF_BENCH(return new RectBench(3, 4, true);)
// Non-AA rects
DEF_BENCH(return new RectBench(1, 0, false);)
DEF_BENCH(return new RectBench(1, 4, false);)
DEF_BENCH(return new RectBench(3, 0, false);)
DEF_BENCH(return new RectBench(3, 4, false);)

DEF_BENCH(return new OvalBench(1);)
DEF_BENCH(return new OvalBench(3);)
DEF_BENCH(return new OvalBench(1, 4);)
DEF_BENCH(return new OvalBench(3, 4);)
DEF_BENCH(return new RRectBench(1);)
DEF_BENCH(return new RRectBench(1, 4);)
DEF_BENCH(return new RRectBench(3);)
DEF_BENCH(return new RRectBench(3, 4);)
DEF_BENCH(return new PointsBench(SkCanvas::kPoints_PointMode, "points");)
DEF_BENCH(return new PointsBench(SkCanvas::kLines_PointMode, "lines");)
DEF_BENCH(return new PointsBench(SkCanvas::kPolygon_PointMode, "polygon");)

DEF_BENCH(return new SrcModeRectBench();)

DEF_BENCH(return new TransparentRectBench();)

DEF_BENCH(return new LocalCoordsRectBench(true);)
DEF_BENCH(return new LocalCoordsRectBench(false);)

// Perspective rects
DEF_BENCH(return new RectBench(1, 0, true, true);)
DEF_BENCH(return new RectBench(1, 0, false, true);)
DEF_BENCH(return new LocalCoordsRectBench(true, true);)
DEF_BENCH(return new LocalCoordsRectBench(false, true);)

/* init the blitmask bench
 */
DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
                                   BlitMaskBench::kMaskOpaque,
                                   "maskopaque");)
DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
                                   BlitMaskBench::kMaskBlack,
                                   "maskblack");)
DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
                                   BlitMaskBench::kMaskColor,
                                   "maskcolor");)
DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
                                   BlitMaskBench::KMaskShader,
                                   "maskshader");)
