/*
 * Copyright 2018 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/SkBBHFactory.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTileMode.h"
#include "include/effects/SkShaderMaskFilter.h"
#include "src/shaders/SkPictureShader.h"

static sk_sp<SkShader> make_bitmap_shader() {
    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setAntiAlias(true);

    auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(100, 100));
    surface->getCanvas()->drawCircle(50, 50, 50, p);

    return surface->makeImageSnapshot()->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                                    SkSamplingOptions());
}

static sk_sp<SkShader> make_picture_shader() {
    SkPaint p;
    p.setColor(SK_ColorBLACK);
    p.setAntiAlias(true);

    SkPictureRecorder recorder;
    recorder.beginRecording(100, 100)->drawCircle(50, 50, 50, p);

    return recorder.finishRecordingAsPicture()->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat,
                                                           SkFilterMode::kNearest);
}

class ShaderMFBench final : public Benchmark {

public:
    using ShaderMaker = sk_sp<SkShader>(*)();

    ShaderMFBench(const char* nm, bool opaque, ShaderMaker maker)
            : fMaker{maker}, fColor{opaque ? 0xff00ff00 : 0x8000ff00} {
        fName = SkStringPrintf("shadermaskfilter_%s_%x", nm, SkColorGetA(fColor));
    }

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

    void onDelayedSetup() override {
        fMaskFilter = SkShaderMaskFilter::Make(fMaker());
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        SkPaint maskPaint;
        maskPaint.setMaskFilter(fMaskFilter);

        for (int i = 0; i < loops; ++i) {
            SkAutoCanvasRestore arc(canvas, false);
            canvas->saveLayer(nullptr, &maskPaint);
            canvas->drawColor(fColor);
        }
    }

private:
    const ShaderMaker fMaker;
    const SkColor fColor;
    SkString fName;
    sk_sp<SkMaskFilter> fMaskFilter;

    using INHERITED = Benchmark;
};

DEF_BENCH( return new ShaderMFBench("bitmap" , true , make_bitmap_shader ); )
DEF_BENCH( return new ShaderMFBench("bitmap" , false, make_bitmap_shader ); )
DEF_BENCH( return new ShaderMFBench("picture", true , make_picture_shader); )
DEF_BENCH( return new ShaderMFBench("picture", false, make_picture_shader); )
