102cafcc1bf6e2968c2efdf459871167970da150eegdaniel/*
202cafcc1bf6e2968c2efdf459871167970da150eegdaniel * Copyright 2014 Google Inc.
302cafcc1bf6e2968c2efdf459871167970da150eegdaniel *
402cafcc1bf6e2968c2efdf459871167970da150eegdaniel * Use of this source code is governed by a BSD-style license that can be
502cafcc1bf6e2968c2efdf459871167970da150eegdaniel * found in the LICENSE file.
602cafcc1bf6e2968c2efdf459871167970da150eegdaniel */
702cafcc1bf6e2968c2efdf459871167970da150eegdaniel
802cafcc1bf6e2968c2efdf459871167970da150eegdaniel#include "Benchmark.h"
902cafcc1bf6e2968c2efdf459871167970da150eegdaniel#include "SkCanvas.h"
1002cafcc1bf6e2968c2efdf459871167970da150eegdaniel#include "SkGradientShader.h"
1102cafcc1bf6e2968c2efdf459871167970da150eegdaniel#include "SkPaint.h"
1202cafcc1bf6e2968c2efdf459871167970da150eegdaniel#include "SkString.h"
1302cafcc1bf6e2968c2efdf459871167970da150eegdaniel
1402cafcc1bf6e2968c2efdf459871167970da150eegdanielenum ColorPattern {
1502cafcc1bf6e2968c2efdf459871167970da150eegdaniel    kWhite_ColorPattern,
1602cafcc1bf6e2968c2efdf459871167970da150eegdaniel    kBlue_ColorPattern,
1702cafcc1bf6e2968c2efdf459871167970da150eegdaniel    kOpaqueBitmap_ColorPattern,
1802cafcc1bf6e2968c2efdf459871167970da150eegdaniel    kAlphaBitmap_ColorPattern,
1902cafcc1bf6e2968c2efdf459871167970da150eegdaniel};
2002cafcc1bf6e2968c2efdf459871167970da150eegdaniel
2102cafcc1bf6e2968c2efdf459871167970da150eegdanielstatic const struct ColorPatternData{
2202cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkColor         fColor;
2302cafcc1bf6e2968c2efdf459871167970da150eegdaniel    bool            fIsBitmap;
2402cafcc1bf6e2968c2efdf459871167970da150eegdaniel    const char*     fName;
2502cafcc1bf6e2968c2efdf459871167970da150eegdaniel} gColorPatterns[] = {
2602cafcc1bf6e2968c2efdf459871167970da150eegdaniel    // Keep this in same order as ColorPattern enum
2702cafcc1bf6e2968c2efdf459871167970da150eegdaniel    { SK_ColorWHITE, false,  "white"        }, // kWhite_ColorPattern
2802cafcc1bf6e2968c2efdf459871167970da150eegdaniel    { SK_ColorBLUE,  false,  "blue"         }, // kBlue_ColorPattern
2902cafcc1bf6e2968c2efdf459871167970da150eegdaniel    { SK_ColorWHITE, true,   "obaqueBitMap" }, // kOpaqueBitmap_ColorPattern
3002cafcc1bf6e2968c2efdf459871167970da150eegdaniel    { 0x10000000,    true,   "alphaBitmap"  }, // kAlphaBitmap_ColorPattern
3102cafcc1bf6e2968c2efdf459871167970da150eegdaniel};
3202cafcc1bf6e2968c2efdf459871167970da150eegdaniel
3302cafcc1bf6e2968c2efdf459871167970da150eegdanielenum DrawType {
3402cafcc1bf6e2968c2efdf459871167970da150eegdaniel    kRect_DrawType,
3502cafcc1bf6e2968c2efdf459871167970da150eegdaniel    kPath_DrawType,
3602cafcc1bf6e2968c2efdf459871167970da150eegdaniel};
3702cafcc1bf6e2968c2efdf459871167970da150eegdaniel
3802cafcc1bf6e2968c2efdf459871167970da150eegdanielstatic void makebm(SkBitmap* bm, int w, int h) {
3902cafcc1bf6e2968c2efdf459871167970da150eegdaniel    bm->allocN32Pixels(w, h);
4002cafcc1bf6e2968c2efdf459871167970da150eegdaniel    bm->eraseColor(SK_ColorTRANSPARENT);
4102cafcc1bf6e2968c2efdf459871167970da150eegdaniel
4202cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkCanvas    canvas(*bm);
4302cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkScalar    s = SkIntToScalar(SkMin32(w, h));
4402cafcc1bf6e2968c2efdf459871167970da150eegdaniel    static const SkPoint     kPts0[] = { { 0, 0 }, { s, s } };
4502cafcc1bf6e2968c2efdf459871167970da150eegdaniel    static const SkPoint     kPts1[] = { { s/2, 0 }, { s/2, s } };
4602cafcc1bf6e2968c2efdf459871167970da150eegdaniel    static const SkScalar    kPos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
4702cafcc1bf6e2968c2efdf459871167970da150eegdaniel    static const SkColor kColors0[] = {0x80F00080, 0xF0F08000, 0x800080F0 };
4802cafcc1bf6e2968c2efdf459871167970da150eegdaniel    static const SkColor kColors1[] = {0xF08000F0, 0x8080F000, 0xF000F080 };
4902cafcc1bf6e2968c2efdf459871167970da150eegdaniel
5002cafcc1bf6e2968c2efdf459871167970da150eegdaniel
5102cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkPaint     paint;
5202cafcc1bf6e2968c2efdf459871167970da150eegdaniel
5302cafcc1bf6e2968c2efdf459871167970da150eegdaniel    paint.setShader(SkGradientShader::CreateLinear(kPts0, kColors0, kPos,
5402cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    SK_ARRAY_COUNT(kColors0), SkShader::kClamp_TileMode))->unref();
5502cafcc1bf6e2968c2efdf459871167970da150eegdaniel    canvas.drawPaint(paint);
5602cafcc1bf6e2968c2efdf459871167970da150eegdaniel    paint.setShader(SkGradientShader::CreateLinear(kPts1, kColors1, kPos,
5702cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    SK_ARRAY_COUNT(kColors1), SkShader::kClamp_TileMode))->unref();
5802cafcc1bf6e2968c2efdf459871167970da150eegdaniel    canvas.drawPaint(paint);
5902cafcc1bf6e2968c2efdf459871167970da150eegdaniel}
6002cafcc1bf6e2968c2efdf459871167970da150eegdaniel
6102cafcc1bf6e2968c2efdf459871167970da150eegdaniel/**
6202cafcc1bf6e2968c2efdf459871167970da150eegdaniel * This bench draws a grid of either rects or filled paths, with two alternating color patterns.
6302cafcc1bf6e2968c2efdf459871167970da150eegdaniel * This color patterns are passed in as enums to the class. The options are:
6402cafcc1bf6e2968c2efdf459871167970da150eegdaniel *   1) solid white color
6502cafcc1bf6e2968c2efdf459871167970da150eegdaniel *   2) solid blue color
6602cafcc1bf6e2968c2efdf459871167970da150eegdaniel *   3) opaque bitmap
6702cafcc1bf6e2968c2efdf459871167970da150eegdaniel *   4) partial alpha bitmap
6802cafcc1bf6e2968c2efdf459871167970da150eegdaniel * The same color pattern can be set for both arguments to create a uniform pattern on all draws.
6902cafcc1bf6e2968c2efdf459871167970da150eegdaniel *
7002cafcc1bf6e2968c2efdf459871167970da150eegdaniel * The bench is used to test a few things. First it can test any optimizations made for a specific
7102cafcc1bf6e2968c2efdf459871167970da150eegdaniel * color pattern (for example drawing an opaque bitmap versus one with partial alpha). Also it can
7202cafcc1bf6e2968c2efdf459871167970da150eegdaniel * be used to test the cost of program switching and/or batching when alternating between different
7302cafcc1bf6e2968c2efdf459871167970da150eegdaniel * patterns when on the gpu.
7402cafcc1bf6e2968c2efdf459871167970da150eegdaniel */
7502cafcc1bf6e2968c2efdf459871167970da150eegdanielclass AlternatingColorPatternBench : public Benchmark {
7602cafcc1bf6e2968c2efdf459871167970da150eegdanielpublic:
7702cafcc1bf6e2968c2efdf459871167970da150eegdaniel    enum {
7802cafcc1bf6e2968c2efdf459871167970da150eegdaniel        NX = 5,
7902cafcc1bf6e2968c2efdf459871167970da150eegdaniel        NY = 5,
8002cafcc1bf6e2968c2efdf459871167970da150eegdaniel        NUM_DRAWS = NX * NY,
8102cafcc1bf6e2968c2efdf459871167970da150eegdaniel    };
8202cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkShader* fBmShader;
8302cafcc1bf6e2968c2efdf459871167970da150eegdaniel
8402cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkPath  fPaths[NUM_DRAWS];
8502cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkRect  fRects[NUM_DRAWS];
8602cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkColor fColors[NUM_DRAWS];
8702cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkShader* fShaders[NUM_DRAWS];
8802cafcc1bf6e2968c2efdf459871167970da150eegdaniel
8902cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkString        fName;
9002cafcc1bf6e2968c2efdf459871167970da150eegdaniel    ColorPatternData    fPattern1;
9102cafcc1bf6e2968c2efdf459871167970da150eegdaniel    ColorPatternData    fPattern2;
9202cafcc1bf6e2968c2efdf459871167970da150eegdaniel    DrawType fDrawType;
9302cafcc1bf6e2968c2efdf459871167970da150eegdaniel    SkBitmap fBmp;
9402cafcc1bf6e2968c2efdf459871167970da150eegdaniel
9502cafcc1bf6e2968c2efdf459871167970da150eegdaniel
9602cafcc1bf6e2968c2efdf459871167970da150eegdaniel    AlternatingColorPatternBench(ColorPattern pattern1, ColorPattern pattern2, DrawType drawType)
9702cafcc1bf6e2968c2efdf459871167970da150eegdaniel        : fBmShader(NULL) {
9802cafcc1bf6e2968c2efdf459871167970da150eegdaniel        fPattern1 = gColorPatterns[pattern1];
9902cafcc1bf6e2968c2efdf459871167970da150eegdaniel        fPattern2 = gColorPatterns[pattern2];
10002cafcc1bf6e2968c2efdf459871167970da150eegdaniel        fName.printf("colorPattern_%s_%s_%s",
10102cafcc1bf6e2968c2efdf459871167970da150eegdaniel                     fPattern1.fName, fPattern2.fName,
10202cafcc1bf6e2968c2efdf459871167970da150eegdaniel                     kRect_DrawType == drawType ? "rect" : "path");
10302cafcc1bf6e2968c2efdf459871167970da150eegdaniel        fDrawType = drawType;
10402cafcc1bf6e2968c2efdf459871167970da150eegdaniel    }
10502cafcc1bf6e2968c2efdf459871167970da150eegdaniel
10602cafcc1bf6e2968c2efdf459871167970da150eegdaniel    virtual ~AlternatingColorPatternBench() {
10702cafcc1bf6e2968c2efdf459871167970da150eegdaniel        SkSafeUnref(fBmShader);
10802cafcc1bf6e2968c2efdf459871167970da150eegdaniel    }
10902cafcc1bf6e2968c2efdf459871167970da150eegdaniel
11002cafcc1bf6e2968c2efdf459871167970da150eegdanielprotected:
11102cafcc1bf6e2968c2efdf459871167970da150eegdaniel    virtual const char* onGetName() SK_OVERRIDE {
11202cafcc1bf6e2968c2efdf459871167970da150eegdaniel        return fName.c_str();
11302cafcc1bf6e2968c2efdf459871167970da150eegdaniel    }
11402cafcc1bf6e2968c2efdf459871167970da150eegdaniel
11502cafcc1bf6e2968c2efdf459871167970da150eegdaniel    virtual void onPreDraw() {
11602cafcc1bf6e2968c2efdf459871167970da150eegdaniel        int w = 40;
11702cafcc1bf6e2968c2efdf459871167970da150eegdaniel        int h = 40;
11802cafcc1bf6e2968c2efdf459871167970da150eegdaniel        makebm(&fBmp, w, h);
11902cafcc1bf6e2968c2efdf459871167970da150eegdaniel        fBmShader = SkShader::CreateBitmapShader(fBmp,
12002cafcc1bf6e2968c2efdf459871167970da150eegdaniel                                                 SkShader::kRepeat_TileMode,
12102cafcc1bf6e2968c2efdf459871167970da150eegdaniel                                                 SkShader::kRepeat_TileMode);
12202cafcc1bf6e2968c2efdf459871167970da150eegdaniel        int offset = 2;
12302cafcc1bf6e2968c2efdf459871167970da150eegdaniel        int count = 0;
12402cafcc1bf6e2968c2efdf459871167970da150eegdaniel        for (int j = 0; j < NY; ++j) {
12502cafcc1bf6e2968c2efdf459871167970da150eegdaniel            for (int i = 0; i < NX; ++i) {
12602cafcc1bf6e2968c2efdf459871167970da150eegdaniel                int x = (w + offset) * i;
12702cafcc1bf6e2968c2efdf459871167970da150eegdaniel                int y = (h * offset) * j;
12802cafcc1bf6e2968c2efdf459871167970da150eegdaniel                if (kRect_DrawType == fDrawType) {
12902cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    fRects[count].set(SkIntToScalar(x), SkIntToScalar(y),
13002cafcc1bf6e2968c2efdf459871167970da150eegdaniel                                      SkIntToScalar(x + w), SkIntToScalar(y + h));
13102cafcc1bf6e2968c2efdf459871167970da150eegdaniel                } else {
13202cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    fPaths[count].moveTo(SkIntToScalar(x), SkIntToScalar(y));
13302cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    fPaths[count].rLineTo(SkIntToScalar(w), 0);
13402cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    fPaths[count].rLineTo(0, SkIntToScalar(h));
13502cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    fPaths[count].rLineTo(SkIntToScalar(-w + 1), 0);
13602cafcc1bf6e2968c2efdf459871167970da150eegdaniel                }
13702cafcc1bf6e2968c2efdf459871167970da150eegdaniel                if (0 == count % 2) {
13802cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    fColors[count]  = fPattern1.fColor;
13902cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    fShaders[count] = fPattern1.fIsBitmap ? fBmShader : NULL;
14002cafcc1bf6e2968c2efdf459871167970da150eegdaniel                } else {
14102cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    fColors[count]  = fPattern2.fColor;
14202cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    fShaders[count] = fPattern2.fIsBitmap ? fBmShader : NULL;
14302cafcc1bf6e2968c2efdf459871167970da150eegdaniel                }
14402cafcc1bf6e2968c2efdf459871167970da150eegdaniel                ++count;
14502cafcc1bf6e2968c2efdf459871167970da150eegdaniel            }
14602cafcc1bf6e2968c2efdf459871167970da150eegdaniel        }
14702cafcc1bf6e2968c2efdf459871167970da150eegdaniel    }
14802cafcc1bf6e2968c2efdf459871167970da150eegdaniel
14902cafcc1bf6e2968c2efdf459871167970da150eegdaniel    virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
15002cafcc1bf6e2968c2efdf459871167970da150eegdaniel        SkPaint paint;
15102cafcc1bf6e2968c2efdf459871167970da150eegdaniel        paint.setAntiAlias(false);
15202cafcc1bf6e2968c2efdf459871167970da150eegdaniel        paint.setFilterLevel(SkPaint::kLow_FilterLevel);
15302cafcc1bf6e2968c2efdf459871167970da150eegdaniel
15402cafcc1bf6e2968c2efdf459871167970da150eegdaniel        for (int i = 0; i < loops; ++i) {
15502cafcc1bf6e2968c2efdf459871167970da150eegdaniel            for (int j = 0; j < NUM_DRAWS; ++j) {
15602cafcc1bf6e2968c2efdf459871167970da150eegdaniel                paint.setColor(fColors[j]);
15702cafcc1bf6e2968c2efdf459871167970da150eegdaniel                paint.setShader(fShaders[j]);
15802cafcc1bf6e2968c2efdf459871167970da150eegdaniel                if (kRect_DrawType == fDrawType) {
15902cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    canvas->drawRect(fRects[j], paint);
16002cafcc1bf6e2968c2efdf459871167970da150eegdaniel                } else {
16102cafcc1bf6e2968c2efdf459871167970da150eegdaniel                    canvas->drawPath(fPaths[j], paint);
16202cafcc1bf6e2968c2efdf459871167970da150eegdaniel                }
16302cafcc1bf6e2968c2efdf459871167970da150eegdaniel            }
16402cafcc1bf6e2968c2efdf459871167970da150eegdaniel        }
16502cafcc1bf6e2968c2efdf459871167970da150eegdaniel    }
16602cafcc1bf6e2968c2efdf459871167970da150eegdaniel
16702cafcc1bf6e2968c2efdf459871167970da150eegdanielprivate:
16802cafcc1bf6e2968c2efdf459871167970da150eegdaniel    typedef Benchmark INHERITED;
16902cafcc1bf6e2968c2efdf459871167970da150eegdaniel};
17002cafcc1bf6e2968c2efdf459871167970da150eegdaniel
17102cafcc1bf6e2968c2efdf459871167970da150eegdanielDEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
17202cafcc1bf6e2968c2efdf459871167970da150eegdaniel                             (kWhite_ColorPattern, kWhite_ColorPattern,
17302cafcc1bf6e2968c2efdf459871167970da150eegdaniel                              kPath_DrawType)); )
17402cafcc1bf6e2968c2efdf459871167970da150eegdanielDEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
17502cafcc1bf6e2968c2efdf459871167970da150eegdaniel                             (kBlue_ColorPattern, kBlue_ColorPattern,
17602cafcc1bf6e2968c2efdf459871167970da150eegdaniel                              kPath_DrawType)); )
17702cafcc1bf6e2968c2efdf459871167970da150eegdanielDEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
17802cafcc1bf6e2968c2efdf459871167970da150eegdaniel                             (kWhite_ColorPattern, kBlue_ColorPattern,
17902cafcc1bf6e2968c2efdf459871167970da150eegdaniel                              kPath_DrawType)); )
18002cafcc1bf6e2968c2efdf459871167970da150eegdaniel
18102cafcc1bf6e2968c2efdf459871167970da150eegdanielDEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
18202cafcc1bf6e2968c2efdf459871167970da150eegdaniel                             (kOpaqueBitmap_ColorPattern, kOpaqueBitmap_ColorPattern,
18302cafcc1bf6e2968c2efdf459871167970da150eegdaniel                              kPath_DrawType)); )
18402cafcc1bf6e2968c2efdf459871167970da150eegdanielDEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
18502cafcc1bf6e2968c2efdf459871167970da150eegdaniel                             (kAlphaBitmap_ColorPattern, kAlphaBitmap_ColorPattern,
18602cafcc1bf6e2968c2efdf459871167970da150eegdaniel                              kPath_DrawType)); )
18702cafcc1bf6e2968c2efdf459871167970da150eegdanielDEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
18802cafcc1bf6e2968c2efdf459871167970da150eegdaniel                             (kOpaqueBitmap_ColorPattern, kAlphaBitmap_ColorPattern,
18902cafcc1bf6e2968c2efdf459871167970da150eegdaniel                              kPath_DrawType)); )
19002cafcc1bf6e2968c2efdf459871167970da150eegdaniel
19102cafcc1bf6e2968c2efdf459871167970da150eegdanielDEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
19202cafcc1bf6e2968c2efdf459871167970da150eegdaniel                             (kOpaqueBitmap_ColorPattern, kOpaqueBitmap_ColorPattern,
19302cafcc1bf6e2968c2efdf459871167970da150eegdaniel                              kRect_DrawType)); )
19402cafcc1bf6e2968c2efdf459871167970da150eegdanielDEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
19502cafcc1bf6e2968c2efdf459871167970da150eegdaniel                             (kAlphaBitmap_ColorPattern, kAlphaBitmap_ColorPattern,
19602cafcc1bf6e2968c2efdf459871167970da150eegdaniel                              kRect_DrawType)); )
19702cafcc1bf6e2968c2efdf459871167970da150eegdanielDEF_BENCH( return SkNEW_ARGS(AlternatingColorPatternBench,
19802cafcc1bf6e2968c2efdf459871167970da150eegdaniel                             (kOpaqueBitmap_ColorPattern, kAlphaBitmap_ColorPattern,
19902cafcc1bf6e2968c2efdf459871167970da150eegdaniel                              kRect_DrawType)); )
20002cafcc1bf6e2968c2efdf459871167970da150eegdaniel
201