/*
 * 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 "SkDeferredCanvas.h"
#include "SkDevice.h"
#include "SkString.h"

class DeferredCanvasBench : public SkBenchmark {
public:
    DeferredCanvasBench(void* param, const char name[]) : INHERITED(param) {
        fName.printf("deferred_canvas_%s", name);
    }

    enum {
        N = SkBENCHLOOP(25), // number of times to create the picture
        CANVAS_WIDTH = 200,
        CANVAS_HEIGHT = 200,
    };
protected:
    virtual const char* onGetName() {
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) {
        SkDevice *device = canvas->getDevice()->createCompatibleDevice(
            SkBitmap::kARGB_8888_Config, CANVAS_WIDTH, CANVAS_HEIGHT, false);

        SkDeferredCanvas deferredCanvas(device);

        device->unref();

        initDeferredCanvas(deferredCanvas);

        for (int i = 0; i < N; i++) {
            drawInDeferredCanvas(deferredCanvas);
        }

        finalizeDeferredCanvas(deferredCanvas);
        deferredCanvas.flush();
    }

    virtual void initDeferredCanvas(SkDeferredCanvas& canvas) = 0;
    virtual void drawInDeferredCanvas(SkDeferredCanvas& canvas) = 0;
    virtual void finalizeDeferredCanvas(SkDeferredCanvas& canvas) = 0;

    SkString fName;

private:
    typedef SkBenchmark INHERITED;
};

class SimpleNotificationClient : public SkDeferredCanvas::NotificationClient {
public:
    SimpleNotificationClient() : fDummy(false) {}

    //bogus virtual implementations that just do something small
    virtual void prepareForDraw() SK_OVERRIDE {fDummy = true;}
    virtual void storageAllocatedForRecordingChanged(size_t) SK_OVERRIDE {fDummy = false;}
    virtual void flushedDrawCommands() SK_OVERRIDE {fDummy = !fDummy;}
private:
    bool fDummy;
};

// Test that records very simple draw operations.
// This benchmark aims to capture performance fluctuations in the recording
// overhead of SkDeferredCanvas
class DeferredRecordBench : public DeferredCanvasBench {
public:
    DeferredRecordBench(void* param)
        : INHERITED(param, "record") {
    }

    enum {
        M = SkBENCHLOOP(700),   // number of individual draws in each loop
    };
protected:

    virtual void initDeferredCanvas(SkDeferredCanvas& canvas) SK_OVERRIDE {
        canvas.setNotificationClient(&fNotificationClient);
    }

    virtual void drawInDeferredCanvas(SkDeferredCanvas& canvas) SK_OVERRIDE {
        SkRect rect;
        rect.setXYWH(0, 0, 10, 10);
        SkPaint paint;
        for (int i = 0; i < M; i++) {
            canvas.save(SkCanvas::kMatrixClip_SaveFlag);
            canvas.translate(SkIntToScalar(i * 27 % CANVAS_WIDTH), SkIntToScalar(i * 13 % CANVAS_HEIGHT));
            canvas.drawRect(rect, paint);
            canvas.restore();
        }
    }

    virtual void finalizeDeferredCanvas(SkDeferredCanvas& canvas) SK_OVERRIDE {
        canvas.clear(0x0);
        canvas.setNotificationClient(NULL);
    }

private:
    typedef DeferredCanvasBench INHERITED;
    SimpleNotificationClient fNotificationClient;
};


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

static SkBenchmark* Fact0(void* p) { return new DeferredRecordBench(p); }

static BenchRegistry gReg0(Fact0);
