/*
* Copyright 2014 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/SkSize.h"
#include "include/private/SkTDArray.h"
#include "include/utils/SkRandom.h"

#include "src/core/SkMathPriv.h"
#include "src/gpu/GrRectanizerSkyline.h"

/**
 * This bench exercises Ganesh' GrRectanizer classes. It exercises the following
 * rectanizers:
 *      Pow2 Rectanizer
 *      Skyline Rectanizer
 * in the following cases:
 *      random rects (e.g., pull-save-layers forward use case)
 *      random power of two rects
 *      small constant sized power of 2 rects (e.g., glyph cache use case)
 */
class RectanizerBench : public Benchmark {
public:
    static const int kWidth = 1024;
    static const int kHeight = 1024;

    enum RectanizerType {
        kSkyline_RectanizerType,
    };

    enum RectType {
        kRand_RectType,
        kRandPow2_RectType,
        kSmallPow2_RectType
    };

    RectanizerBench(RectanizerType rectanizerType, RectType rectType)
        : fName("rectanizer_")
        , fRectType(rectType) {

        fName.append("skyline_");

        if (kRand_RectType == fRectType) {
            fName.append("rand");
        } else if (kRandPow2_RectType == fRectType) {
            fName.append("rand2");
        } else {
            SkASSERT(kSmallPow2_RectType == fRectType);
            fName.append("sm2");
        }
    }

protected:
    bool isSuitableFor(Backend backend) override {
        return kNonRendering_Backend == backend;
    }

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

    void onDelayedSetup() override {
        SkASSERT(nullptr == fRectanizer.get());

        fRectanizer.reset(new GrRectanizerSkyline(kWidth, kHeight));
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        SkRandom rand;
        SkIPoint16 loc;
        SkISize size;

        for (int i = 0; i < loops; ++i) {
            if (kRand_RectType == fRectType) {
                size = SkISize::Make(rand.nextRangeU(1, kWidth / 2),
                                     rand.nextRangeU(1, kHeight / 2));
            } else if (kRandPow2_RectType == fRectType) {
                size = SkISize::Make(GrNextPow2(rand.nextRangeU(1, kWidth / 2)),
                                     GrNextPow2(rand.nextRangeU(1, kHeight / 2)));
            } else {
                SkASSERT(kSmallPow2_RectType == fRectType);
                size = SkISize::Make(128, 128);
            }

            if (!fRectanizer->addRect(size.fWidth, size.fHeight, &loc)) {
                // insert failed so clear out the rectanizer and give the
                // current rect another try
                fRectanizer->reset();
                i--;
            }
        }

        fRectanizer->reset();
    }

private:
    SkString                    fName;
    RectType                    fRectType;
    std::unique_ptr<GrRectanizerSkyline> fRectanizer;

    typedef Benchmark INHERITED;
};

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

DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
                                     RectanizerBench::kRand_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
                                     RectanizerBench::kRandPow2_RectType);)
DEF_BENCH(return new RectanizerBench(RectanizerBench::kSkyline_RectanizerType,
                                     RectanizerBench::kSmallPow2_RectType);)
