/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkBenchmark.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"

class PictureRecordBench : public SkBenchmark {
public:
    PictureRecordBench(const char name[])  {
        fName.printf("picture_record_%s", name);
    }

    virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
        return backend == kNonRendering_Backend;
    }

    enum {
        PICTURE_WIDTH = 1000,
        PICTURE_HEIGHT = 4000,
    };
protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }
private:
    SkString fName;
    typedef SkBenchmark INHERITED;
};


static const int kMaxLoopsPerCanvas = 10000;

/*
 *  An SkPicture has internal dictionaries to store bitmaps, matrices, paints,
 *  and regions.  This bench populates those dictionaries to test the speed of
 *  reading and writing to those particular dictionary data structures.
 */
class DictionaryRecordBench : public PictureRecordBench {
public:
    DictionaryRecordBench() : INHERITED("dictionaries") {}

protected:
    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
        SkPictureRecorder recorder;
        SkCanvas* canvas = NULL;

        const SkPoint translateDelta = getTranslateDelta(loops);

        for (int i = 0; i < loops; i++) {
            if (0 == i % kMaxLoopsPerCanvas) {
                SkAutoTUnref<SkPicture> picture(recorder.endRecording());
                canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
            }

            SkColor color = SK_ColorYELLOW + (i % 255);
            SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT);

            canvas->save();

            // set the clip to the given region
            SkRegion region;
            region.setRect(rect);
            canvas->clipRegion(region);

            // fill the clip with a color
            SkPaint paint;
            paint.setColor(color);
            canvas->drawPaint(paint);

            // set a matrix on the canvas
            SkMatrix matrix;
            matrix.setRotate(SkIntToScalar(i % 360));
            canvas->setMatrix(matrix);

            // create a simple bitmap
            SkBitmap bitmap;
            bitmap.setConfig(SkBitmap::kRGB_565_Config, 10, 10);
            bitmap.allocPixels();

            // draw a single color into the bitmap
            SkCanvas bitmapCanvas(bitmap);
            bitmapCanvas.drawColor(SkColorSetA(color, i % 255));

            // draw the bitmap onto the canvas
            canvas->drawBitmapMatrix(bitmap, matrix);

            canvas->restore();
            canvas->translate(translateDelta.fX, translateDelta.fY);
        }
    }

    SkPoint getTranslateDelta(int M) {
        SkIPoint canvasSize = onGetSize();
        return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/M),
                             SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/M));
    }
private:
    typedef PictureRecordBench INHERITED;
};

/*
 *  Populates the SkPaint dictionary with a large number of unique paint
 *  objects that differ only by color
 */
class UniquePaintDictionaryRecordBench : public PictureRecordBench {
public:
    UniquePaintDictionaryRecordBench() : INHERITED("unique_paint_dictionary") { }

protected:
    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
        SkRandom rand;
        SkPaint paint;
        SkPictureRecorder recorder;
        SkCanvas* canvas = NULL;
        for (int i = 0; i < loops; i++) {
            if (0 == i % kMaxLoopsPerCanvas) {
                SkAutoTUnref<SkPicture> picture(recorder.endRecording());
                canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
            }
            paint.setColor(rand.nextU());
            canvas->drawPaint(paint);
        }
    }

private:
    typedef PictureRecordBench INHERITED;
};

/*
 *  Populates the SkPaint dictionary with a number of unique paint
 *  objects that get reused repeatedly.
 *
 *  Re-creating the paint objects in the inner loop slows the benchmark down 10%.
 *  Using setColor(i % objCount) instead of a random color creates a very high rate
 *  of hash conflicts, slowing us down 12%.
 */
class RecurringPaintDictionaryRecordBench : public PictureRecordBench {
public:
    RecurringPaintDictionaryRecordBench() : INHERITED("recurring_paint_dictionary") {
        SkRandom rand;
        for (int i = 0; i < ObjCount; i++) {
            fPaint[i].setColor(rand.nextU());
        }
    }

    enum {
        ObjCount = 100,  // number of unique paint objects
    };
protected:
    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
        SkPictureRecorder recorder;
        SkCanvas* canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
        for (int i = 0; i < loops; i++) {
            canvas->drawPaint(fPaint[i % ObjCount]);
        }
    }

private:
    SkPaint fPaint [ObjCount];
    typedef PictureRecordBench INHERITED;
};

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

DEF_BENCH( return new DictionaryRecordBench(); )
DEF_BENCH( return new UniquePaintDictionaryRecordBench(); )
DEF_BENCH( return new RecurringPaintDictionaryRecordBench(); )
