/*
* Copyright 2016 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 "SkRect.h"
#include "SkString.h"

class DrawLatticeBench : public Benchmark {
public:
    DrawLatticeBench(int* xDivs, int xCount, int* yDivs, int yCount, const SkISize& srcSize,
                     const SkRect& dst, const char* desc)
        : fSrcSize(srcSize)
        , fDst(dst)
    {
        fLattice.fXDivs = xDivs;
        fLattice.fXCount = xCount;
        fLattice.fYDivs = yDivs;
        fLattice.fYCount = yCount;
        fLattice.fFlags = nullptr;
        fLattice.fBounds = nullptr;

        fName = SkStringPrintf("DrawLattice_%s", desc);
    }

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

    SkIPoint onGetSize() override {
        return SkIPoint::Make(1000, 1000);
    }

    bool isSuitableFor(Backend backend) override {
        return kRaster_Backend == backend || kGPU_Backend == backend;
    }

    void onDelayedSetup() override {
        fBitmap.allocN32Pixels(fSrcSize.width(), fSrcSize.height());
        fBitmap.eraseColor(0x880000FF);
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        for (int i = 0; i < loops; i++) {
            canvas->drawBitmapLattice(fBitmap, fLattice, fDst);
        }
    }

private:
    SkISize           fSrcSize;
    SkCanvas::Lattice fLattice;
    SkRect            fDst;
    SkString          fName;
    SkBitmap          fBitmap;

    typedef Benchmark INHERITED;
};

static int gDivs9[2] = { 25, 75, };
DEF_BENCH(return new DrawLatticeBench(gDivs9, 2, gDivs9, 2, SkISize::Make(100, 100),
                                      SkRect::MakeWH(250.0f, 250.0f), "Src100_Dst250_Rects9");)
DEF_BENCH(return new DrawLatticeBench(gDivs9, 2, gDivs9, 2, SkISize::Make(100, 100),
                                      SkRect::MakeWH(500.0f, 500.0f), "Src100_Dst500_Rects9");)
DEF_BENCH(return new DrawLatticeBench(gDivs9, 2, gDivs9, 2, SkISize::Make(100, 100),
                                      SkRect::MakeWH(1000.0f, 1000.0f), "Src100_Dst1000_Rects9");)
static int gDivs15[4] = { 15, 45, 55, 85, };
DEF_BENCH(return new DrawLatticeBench(gDivs15, 4, gDivs15, 4, SkISize::Make(100, 100),
                                      SkRect::MakeWH(250.0f, 250.0f), "Src100_Dst250_Rects15");)
DEF_BENCH(return new DrawLatticeBench(gDivs15, 4, gDivs15, 4, SkISize::Make(100, 100),
                                      SkRect::MakeWH(500.0f, 500.0f), "Src100_Dst500_Rects15");)
DEF_BENCH(return new DrawLatticeBench(gDivs15, 4, gDivs15, 4, SkISize::Make(100, 100),
                                      SkRect::MakeWH(1000.0f, 1000.0f), "Src100_Dst1000_Rects15");)
