/*
 * Copyright 2018 Google LLC
 *
 * 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); )
