/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "Benchmark.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
#include "SkPoint.h"
#include "SkRandom.h"
#include "SkRect.h"
#include "SkString.h"

// This is designed to emulate about 4 screens of textual content

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

// Chrome draws into small tiles with impl-side painting.
// This benchmark measures the relative performance of our bounding-box hierarchies,
// both when querying tiles perfectly and when not.
enum BBH  { kNone, kRTree };
enum Mode { kTiled, kRandom };
class TiledPlaybackBench : public Benchmark {
public:
    TiledPlaybackBench(BBH bbh, Mode mode) : fBBH(bbh), fMode(mode), fName("tiled_playback") {
        switch (fBBH) {
            case kNone:     fName.append("_none"    ); break;
            case kRTree:    fName.append("_rtree"   ); break;
        }
        switch (fMode) {
            case kTiled:  fName.append("_tiled" ); break;
            case kRandom: fName.append("_random"); break;
        }
    }

    const char* onGetName() override { return fName.c_str(); }
    SkIPoint onGetSize() override { return SkIPoint::Make(1024,1024); }

    void onDelayedSetup() override {
        std::unique_ptr<SkBBHFactory> factory;
        switch (fBBH) {
            case kNone:                                                 break;
            case kRTree:    factory.reset(new SkRTreeFactory);          break;
        }

        SkPictureRecorder recorder;
        SkCanvas* canvas = recorder.beginRecording(1024, 1024, factory.get());
            SkRandom rand;
            for (int i = 0; i < 10000; i++) {
                SkScalar x = rand.nextRangeScalar(0, 1024),
                         y = rand.nextRangeScalar(0, 1024),
                         w = rand.nextRangeScalar(0, 128),
                         h = rand.nextRangeScalar(0, 128);
                SkPaint paint;
                paint.setColor(rand.nextU());
                paint.setAlpha(0xFF);
                canvas->drawRect(SkRect::MakeXYWH(x,y,w,h), paint);
            }
        fPic = recorder.finishRecordingAsPicture();
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        for (int i = 0; i < loops; i++) {
            // This inner loop guarantees we make the same choices for all bench variants.
            SkRandom rand;
            for (int j = 0; j < 10; j++) {
                SkScalar x = 0, y = 0;
                switch (fMode) {
                    case kTiled:  x = SkScalar(256 * rand.nextULessThan(4));
                                  y = SkScalar(256 * rand.nextULessThan(4));
                                  break;
                    case kRandom: x = rand.nextRangeScalar(0, 768);
                                  y = rand.nextRangeScalar(0, 768);
                                  break;
                }
                SkAutoCanvasRestore ar(canvas, true/*save now*/);
                canvas->clipRect(SkRect::MakeXYWH(x,y,256,256));
                fPic->playback(canvas);
            }
        }
    }

private:
    BBH                 fBBH;
    Mode                fMode;
    SkString            fName;
    sk_sp<SkPicture>    fPic;
};

DEF_BENCH( return new TiledPlaybackBench(kNone,     kRandom); )
DEF_BENCH( return new TiledPlaybackBench(kNone,     kTiled ); )
DEF_BENCH( return new TiledPlaybackBench(kRTree,    kRandom); )
DEF_BENCH( return new TiledPlaybackBench(kRTree,    kTiled ); )
