/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef Benchmark_DEFINED
#define Benchmark_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/private/base/SkTArray.h"
#include "tools/Registry.h"

#if defined(SK_GRAPHITE)
#include "include/gpu/graphite/Context.h"
#endif

#include <functional>

#define DEF_BENCH3(code, N) \
    static BenchRegistry gBench##N([](void*) -> Benchmark* { code; });
#define DEF_BENCH2(code, N) DEF_BENCH3(code, N)
#define DEF_BENCH(code) DEF_BENCH2(code, __COUNTER__)

/*
 *  With the above macros, you can register benches as follows (at the bottom
 *  of your .cpp)
 *
 *  DEF_BENCH(return new MyBenchmark(...))
 *  DEF_BENCH(return new MyBenchmark(...))
 *  DEF_BENCH(return new MyBenchmark(...))
 */

struct GrContextOptions;
class GrRecordingContext;
class SkCanvas;
class SkPaint;

class Benchmark : public SkRefCnt {
public:
    Benchmark();

    const char* getName();
    const char* getUniqueName();
    SkISize getSize();

    enum class Backend {
        kNonRendering,
        kRaster,
        kGanesh,
        kGraphite,
        kPDF,
        kHWUI,
    };

    // Call to determine whether the benchmark is intended for
    // the rendering mode.
    virtual bool isSuitableFor(Backend backend) {
        return backend != Backend::kNonRendering;
    }

    // Allows a benchmark to override options used to construct the GrContext.
    virtual void modifyGrContextOptions(GrContextOptions*) {}

#if defined(SK_GRAPHITE)
    virtual void modifyGraphiteContextOptions(skgpu::graphite::ContextOptions*) {}
#endif

    // Whether or not this benchmark requires multiple samples to get a meaningful result.
    virtual bool shouldLoop() const {
        return true;
    }

    // Call before draw, allows the benchmark to do setup work outside of the
    // timer. When a benchmark is repeatedly drawn, this should be called once
    // before the initial draw.
    void delayedSetup();

    // Called once before and after a series of draw calls to a single canvas.
    // The setup/break down in these calls is not timed.
    void perCanvasPreDraw(SkCanvas*);
    void perCanvasPostDraw(SkCanvas*);

    // Called just before and after each call to draw().  Not timed.
    void preDraw(SkCanvas*);
    void postDraw(SkCanvas*);

    // Bench framework can tune loops to be large enough for stable timing.
    void draw(int loops, SkCanvas*, std::function<void()> submitFrame = nullptr);

    virtual void getGpuStats(SkCanvas*,
                             skia_private::TArray<SkString>* keys,
                             skia_private::TArray<double>* values) {}

    // Replaces the GrRecordingContext's dmsaaStats() with a single frame of this benchmark.
    virtual bool getDMSAAStats(GrRecordingContext*) { return false; }

    // Count of units (pixels, whatever) being exercised, to scale timing by.
    int getUnits() const { return fUnits; }

protected:
    void setUnits(int units) { SkASSERT(units > 0); fUnits = units; }

    virtual void setupPaint(SkPaint* paint);

    virtual const char* onGetName() = 0;
    virtual const char* onGetUniqueName() { return this->onGetName(); }
    virtual void onDelayedSetup() {}
    virtual void onPerCanvasPreDraw(SkCanvas*) {}
    virtual void onPerCanvasPostDraw(SkCanvas*) {}
    virtual void onPreDraw(SkCanvas*) {}
    virtual void onPostDraw(SkCanvas*) {}
    // Each bench should do its main work in a loop like this:
    //   for (int i = 0; i < loops; i++) { <work here> }
    virtual void onDraw(int loops, SkCanvas*) = 0;
    // Similar to onDraw except after each frame the Benchmark draws it should call the endFrame
    // callback (if valid). This is useful for Benchmarks like MSKP which inherently draw multiple
    // frames within one draw call. Benchmarks that want to use this should make sure to return
    // true from hasInternalFrames.
    virtual void onDrawFrame(int loops, SkCanvas*, std::function<void()> endFrame) {}

    virtual SkISize onGetSize();

private:
    // If the Benchmark has its own internal frames (e.g. MSKPs) this function should return true.
    // If it returns true then onDrawFrame will be called intstead of onDraw.
    virtual bool submitsInternalFrames() { return false; }

    int fUnits = 1;

    using INHERITED = SkRefCnt;
};

typedef sk_tools::Registry<Benchmark*(*)(void*)> BenchRegistry;

#endif
