/*
 * 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 "Benchmark.h"
#include "SkCanvas.h"
#include "SkChunkAlloc.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkString.h"

class ChunkAllocBench : public Benchmark {
    SkString    fName;
    size_t      fMinSize;
public:
    ChunkAllocBench(size_t minSize)  {
        fMinSize = minSize;
        fName.printf("chunkalloc_" SK_SIZE_T_SPECIFIER, minSize);
    }

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

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
        size_t inc = fMinSize >> 4;
        SkASSERT(inc > 0);
        size_t total = fMinSize * 64;

        SkChunkAlloc alloc(fMinSize);

        for (int i = 0; i < loops; ++i) {
            size_t size = 0;
            int calls = 0;
            while (size < total) {
                alloc.allocThrow(inc);
                size += inc;
                calls += 1;
            }
            alloc.reset();
        }
    }

private:
    typedef Benchmark INHERITED;
};

DEF_BENCH( return new ChunkAllocBench(64); )
DEF_BENCH( return new ChunkAllocBench(8*1024); )

static int* calloc(size_t num) {
    return (int*)sk_calloc_throw(num*sizeof(int));
}

static int* malloc_bzero(size_t num) {
    const size_t bytes = num*sizeof(int);
    int* ints = (int*)sk_malloc_throw(bytes);
    sk_bzero(ints, bytes);
    return ints;
}

class ZerosBench : public Benchmark {
    size_t   fNum;
    bool     fRead;
    bool     fWrite;
    bool     fUseCalloc;
    SkString fName;
public:
    ZerosBench(size_t num, bool read, bool write, bool useCalloc)
        : fNum(num)
        , fRead(read)
        , fWrite(write)
        , fUseCalloc(useCalloc) {
        fName.printf("memory_%s", useCalloc ? "calloc" : "malloc_bzero");
        if (read && write) {
            fName.appendf("_rw");
        } else if (read) {
            fName.appendf("_r");
        } else if (write) {
            fName.appendf("_w");
        }
        fName.appendf("_"SK_SIZE_T_SPECIFIER, num);
    }

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

protected:
    virtual const char* onGetName() SK_OVERRIDE {
        return fName.c_str();
    }

    virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
        for (int i = 0; i < loops; i++) {
            int* zeros = fUseCalloc ? calloc(fNum) : malloc_bzero(fNum);
            if (fRead) {
                volatile int x = 15;
                for (size_t j = 0; j < fNum; j++) {
                    x ^= zeros[j];
                }
            }
            if (fWrite) {
                for (size_t j = 0; j < fNum; j++) {
                    zeros[j] = 15;
                }
            }
            sk_free(zeros);
        }
    }
};

//                             zero count  r  w  useCalloc?
DEF_BENCH(return new ZerosBench(1024*1024, 0, 0, 0))
DEF_BENCH(return new ZerosBench(1024*1024, 0, 0, 1))
DEF_BENCH(return new ZerosBench(1024*1024, 0, 1, 0))
DEF_BENCH(return new ZerosBench(1024*1024, 0, 1, 1))
DEF_BENCH(return new ZerosBench(1024*1024, 1, 0, 0))
DEF_BENCH(return new ZerosBench(1024*1024, 1, 0, 1))
DEF_BENCH(return new ZerosBench(1024*1024, 1, 1, 0))
DEF_BENCH(return new ZerosBench(1024*1024, 1, 1, 1))

DEF_BENCH(return new ZerosBench(256*1024, 0, 0, 0))
DEF_BENCH(return new ZerosBench(256*1024, 0, 0, 1))
DEF_BENCH(return new ZerosBench(256*1024, 0, 1, 0))
DEF_BENCH(return new ZerosBench(256*1024, 0, 1, 1))
DEF_BENCH(return new ZerosBench(256*1024, 1, 0, 0))
DEF_BENCH(return new ZerosBench(256*1024, 1, 0, 1))
DEF_BENCH(return new ZerosBench(256*1024, 1, 1, 0))
DEF_BENCH(return new ZerosBench(256*1024, 1, 1, 1))

DEF_BENCH(return new ZerosBench(4*1024, 0, 0, 0))
DEF_BENCH(return new ZerosBench(4*1024, 0, 0, 1))
DEF_BENCH(return new ZerosBench(4*1024, 0, 1, 0))
DEF_BENCH(return new ZerosBench(4*1024, 0, 1, 1))
DEF_BENCH(return new ZerosBench(4*1024, 1, 0, 0))
DEF_BENCH(return new ZerosBench(4*1024, 1, 0, 1))
DEF_BENCH(return new ZerosBench(4*1024, 1, 1, 0))
DEF_BENCH(return new ZerosBench(4*1024, 1, 1, 1))

DEF_BENCH(return new ZerosBench(300, 0, 0, 0))
DEF_BENCH(return new ZerosBench(300, 0, 0, 1))
DEF_BENCH(return new ZerosBench(300, 0, 1, 0))
DEF_BENCH(return new ZerosBench(300, 0, 1, 1))
DEF_BENCH(return new ZerosBench(300, 1, 0, 0))
DEF_BENCH(return new ZerosBench(300, 1, 0, 1))
DEF_BENCH(return new ZerosBench(300, 1, 1, 0))
DEF_BENCH(return new ZerosBench(300, 1, 1, 1))

DEF_BENCH(return new ZerosBench(4, 0, 0, 0))
DEF_BENCH(return new ZerosBench(4, 0, 0, 1))
DEF_BENCH(return new ZerosBench(4, 0, 1, 0))
DEF_BENCH(return new ZerosBench(4, 0, 1, 1))
DEF_BENCH(return new ZerosBench(4, 1, 0, 0))
DEF_BENCH(return new ZerosBench(4, 1, 0, 1))
DEF_BENCH(return new ZerosBench(4, 1, 1, 0))
DEF_BENCH(return new ZerosBench(4, 1, 1, 1))
