/*
 * Copyright 2013 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 "SkPaint.h"
#include "SkRandom.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkBlurMask.h"

class BitmapScaleBench: public SkBenchmark {
    int         fLoopCount;
    int         fInputSize;
    int         fOutputSize;
    SkString    fName;

public:
    BitmapScaleBench(void *param, int is, int os) : INHERITED(param) {
        fInputSize = is;
        fOutputSize = os;

        fLoopCount = 100;
    }

protected:

    SkBitmap fInputBitmap, fOutputBitmap;
    SkMatrix fMatrix;

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

    int inputSize() const {
        return fInputSize;
    }

    int outputSize() const {
        return fOutputSize;
    }

    float scale() const {
        return float(outputSize())/inputSize();
    }

    SkIPoint onGetSize() SK_OVERRIDE {
        return SkIPoint::Make( fOutputSize, fOutputSize );
    }

    void setName(const char * name) {
        fName.printf( "bitmap_scale_%s_%d_%d", name, fInputSize, fOutputSize );
    }

    virtual void onPreDraw() {
        fInputBitmap.setConfig(SkBitmap::kARGB_8888_Config, fInputSize, fInputSize);
        fInputBitmap.allocPixels();
        fInputBitmap.eraseColor(SK_ColorWHITE);
        fInputBitmap.setIsOpaque(true);

        fOutputBitmap.setConfig(SkBitmap::kARGB_8888_Config, fOutputSize, fOutputSize);
        fOutputBitmap.allocPixels();
        fOutputBitmap.setIsOpaque(true);

        fMatrix.setScale( scale(), scale() );
    }

    virtual void onDraw(SkCanvas*) {
        SkPaint paint;
        this->setupPaint(&paint);

        preBenchSetup();

        for (int i = 0; i < SkBENCHLOOP(fLoopCount); i++) {
            doScaleImage();
        }
    }

    virtual void doScaleImage() = 0;
    virtual void preBenchSetup() {}
private:
    typedef SkBenchmark INHERITED;
};

class BitmapFilterScaleBench: public BitmapScaleBench {
 public:
    BitmapFilterScaleBench(void *param, int is, int os) : INHERITED(param, is, os) {
        setName( "filter" );
    }
protected:
    virtual void doScaleImage() SK_OVERRIDE {
        SkCanvas canvas( fOutputBitmap );
        SkPaint paint;

        paint.setFlags( SkPaint::kHighQualityFilterBitmap_Flag | SkPaint::kFilterBitmap_Flag );

        canvas.drawBitmapMatrix( fInputBitmap, fMatrix, &paint );
    }
private:
    typedef BitmapScaleBench INHERITED;
};

class BitmapDirectScaleBench: public BitmapScaleBench {
 public:
    BitmapDirectScaleBench(void *param, int is, int os) : INHERITED(param, is, os) {
        setName( "direct" );
    }
protected:
    virtual void doScaleImage() SK_OVERRIDE {
        fInputBitmap.scale( &fOutputBitmap );
    }
private:
    typedef BitmapScaleBench INHERITED;
};


DEF_BENCH(return new BitmapFilterScaleBench(p, 10, 90);)
DEF_BENCH(return new BitmapFilterScaleBench(p, 30, 90);)
DEF_BENCH(return new BitmapFilterScaleBench(p, 80, 90);)
// DEF_BENCH(return new BitmapFilterScaleBench(p, 90, 90);)
// DEF_BENCH(return new BitmapFilterScaleBench(p, 90, 80);)
// DEF_BENCH(return new BitmapFilterScaleBench(p, 90, 30);)
// DEF_BENCH(return new BitmapFilterScaleBench(p, 90, 10);)

DEF_BENCH(return new BitmapDirectScaleBench(p, 10, 90);)
DEF_BENCH(return new BitmapDirectScaleBench(p, 30, 90);)
DEF_BENCH(return new BitmapDirectScaleBench(p, 80, 90);)
// DEF_BENCH(return new BitmapDirectScaleBench(p, 90, 90);)
// DEF_BENCH(return new BitmapDirectScaleBench(p, 90, 80);)
// DEF_BENCH(return new BitmapDirectScaleBench(p, 90, 30);)
// DEF_BENCH(return new BitmapDirectScaleBench(p, 90, 10);)
