/*
 * Copyright 2013 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/SkFont.h"
#include "include/core/SkPaint.h"
#include "include/core/SkString.h"
#include "include/core/SkTextBlob.h"
#include "include/utils/SkRandom.h"
#include "src/core/SkBlendModePriv.h"

// Benchmark that draws non-AA rects or AA text with an SkXfermode::Mode.
class XfermodeBench : public Benchmark {
public:
    XfermodeBench(SkBlendMode mode, bool aa) : fBlendMode(mode) {
        fAA = aa;
        fName.printf("blendmicro_%s_%s", aa ? "mask" : "rect", SkBlendMode_Name(mode));
    }

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

    void onDraw(int loops, SkCanvas* canvas) override {
        const char* text = "Hamburgefons";
        size_t len = strlen(text);
        SkISize size = canvas->getBaseLayerSize();
        SkRandom random;
        while (loops > 0) {
            SkPaint paint;
            paint.setBlendMode(fBlendMode);
            paint.setColor(random.nextU());
            if (fAA) {
                // Draw text to exercise AA code paths.
                SkFont font;
                font.setSize(random.nextRangeScalar(12, 96));
                SkScalar x = random.nextRangeScalar(0, (SkScalar)size.fWidth),
                         y = random.nextRangeScalar(0, (SkScalar)size.fHeight);
                auto blob = SkTextBlob::MakeFromText(text, len, font, SkTextEncoding::kUTF8);
                int iterations = std::min(1000, loops);
                for (int j = 0; j < iterations; ++j) {
                    canvas->drawTextBlob(blob, x, y, paint);
                }
                loops -= iterations;
            } else {
                // Draw rects to exercise non-AA code paths.
                SkScalar w = random.nextRangeScalar(50, 100);
                SkScalar h = random.nextRangeScalar(50, 100);
                SkRect rect = SkRect::MakeXYWH(
                    random.nextUScalar1() * (size.fWidth - w),
                    random.nextUScalar1() * (size.fHeight - h),
                    w,
                    h
                );
                int iterations = std::min(1000, loops);
                for (int j = 0; j < iterations; ++j) {
                    canvas->drawRect(rect, paint);
                }
                loops -= iterations;
            }
        }
    }

private:
    SkBlendMode fBlendMode;
    SkString    fName;
    bool        fAA;

    using INHERITED = Benchmark;
};

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

#define BENCH(...)                                             \
    DEF_BENCH( return new XfermodeBench(__VA_ARGS__, true); )  \
    DEF_BENCH( return new XfermodeBench(__VA_ARGS__, false); )

BENCH(SkBlendMode::kClear)
BENCH(SkBlendMode::kSrc)
BENCH(SkBlendMode::kDst)
BENCH(SkBlendMode::kSrcOver)
BENCH(SkBlendMode::kDstOver)
BENCH(SkBlendMode::kSrcIn)
BENCH(SkBlendMode::kDstIn)
BENCH(SkBlendMode::kSrcOut)
BENCH(SkBlendMode::kDstOut)
BENCH(SkBlendMode::kSrcATop)
BENCH(SkBlendMode::kDstATop)
BENCH(SkBlendMode::kXor)

BENCH(SkBlendMode::kPlus)
BENCH(SkBlendMode::kModulate)
BENCH(SkBlendMode::kScreen)

BENCH(SkBlendMode::kOverlay)
BENCH(SkBlendMode::kDarken)
BENCH(SkBlendMode::kLighten)
BENCH(SkBlendMode::kColorDodge)
BENCH(SkBlendMode::kColorBurn)
BENCH(SkBlendMode::kHardLight)
BENCH(SkBlendMode::kSoftLight)
BENCH(SkBlendMode::kDifference)
BENCH(SkBlendMode::kExclusion)
BENCH(SkBlendMode::kMultiply)

BENCH(SkBlendMode::kHue)
BENCH(SkBlendMode::kSaturation)
BENCH(SkBlendMode::kColor)
BENCH(SkBlendMode::kLuminosity)
