/*
 * 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 "bench/Benchmark.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkString.h"
#include "tools/ToolUtils.h"

class PremulAndUnpremulAlphaOpsBench : public Benchmark {
    enum {
        W = 256,
        H = 256,
    };
    SkBitmap fBmp1, fBmp2;

public:
    PremulAndUnpremulAlphaOpsBench(SkColorType ct) {
        fColorType = ct;
        fName.printf("premul_and_unpremul_alpha_%s", ToolUtils::colortype_name(ct));
    }

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

    void onDelayedSetup() override {
        SkImageInfo info = SkImageInfo::Make(W, H, fColorType, kUnpremul_SkAlphaType);
        fBmp1.allocPixels(info);   // used in writePixels

        for (int h = 0; h < H; ++h) {
            for (int w = 0; w < W; ++w) {
                // SkColor places A in the right slot for either RGBA or BGRA
                *fBmp1.getAddr32(w, h) = SkColorSetARGB(h & 0xFF, w & 0xFF, w & 0xFF, w & 0xFF);
            }
        }

        fBmp2.allocPixels(info);    // used in readPixels()
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        canvas->clear(SK_ColorBLACK);

        for (int loop = 0; loop < loops; ++loop) {
            // Unpremul -> Premul
            canvas->writePixels(fBmp1.info(), fBmp1.getPixels(), fBmp1.rowBytes(), 0, 0);
            // Premul -> Unpremul
            canvas->readPixels(fBmp2.info(), fBmp2.getPixels(), fBmp2.rowBytes(), 0, 0);
        }
    }

private:
    SkColorType fColorType;
    SkString fName;

    typedef Benchmark INHERITED;
};


DEF_BENCH(return new PremulAndUnpremulAlphaOpsBench(kRGBA_8888_SkColorType));
DEF_BENCH(return new PremulAndUnpremulAlphaOpsBench(kBGRA_8888_SkColorType));
