/*
 * 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 "src/base/SkRandom.h"
#include "src/core/SkBlendModePriv.h"
#include "tools/Resources.h"

namespace {
enum Type {
    kText,
    kRect,
    kSprite,
};
}

const char* gTypeNames[] = {
    "mask", "rect", "sprite",
};

// Benchmark that draws non-AA rects or AA text with an SkBlendMode.
class XfermodeBench : public Benchmark {
public:
    XfermodeBench(SkBlendMode mode, Type t) : fBlendMode(mode) {
        fType = t;
        fName.printf("blendmicro_%s_%s", gTypeNames[t], SkBlendMode_Name(mode));
    }

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

    void onDelayedSetup() override {
        if (fType == kSprite) {
            fImage = GetResourceAsImage("images/color_wheel.png");
        }
    }

    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());
            switch (fType) {
                case kText: {
                    // 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;
                } break;
                case kRect: {
                    // 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;
                } break;
                case kSprite:
                    paint.setAlphaf(1.0f);
                    for (int i = 0; i < 10; ++i) {
                        canvas->drawImage(fImage, 0, 0, SkSamplingOptions(), &paint);
                    }
                    loops -= 1;
                    break;
            }
        }
    }

private:
    SkBlendMode fBlendMode;
    SkString    fName;
    sk_sp<SkImage> fImage;
    Type        fType;

    using INHERITED = Benchmark;
};

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

#define BENCH(mode)                                      \
    DEF_BENCH( return new XfermodeBench(mode, kText); )  \
    DEF_BENCH( return new XfermodeBench(mode, kRect); )  \
    DEF_BENCH( return new XfermodeBench(mode, kSprite); )

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)
