Home | History | Annotate | Download | only in bench
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "Benchmark.h"
      9 #include "SkCanvas.h"
     10 #include "SkGradientShader.h"
     11 #include "SkPaint.h"
     12 #include "SkPath.h"
     13 #include "SkString.h"
     14 
     15 enum ColorPattern {
     16     kWhite_ColorPattern,
     17     kBlue_ColorPattern,
     18     kOpaqueBitmap_ColorPattern,
     19     kAlphaBitmap_ColorPattern,
     20 };
     21 
     22 static const struct ColorPatternData{
     23     SkColor         fColor;
     24     bool            fIsBitmap;
     25     const char*     fName;
     26 } gColorPatterns[] = {
     27     // Keep this in same order as ColorPattern enum
     28     { SK_ColorWHITE, false,  "white"        }, // kWhite_ColorPattern
     29     { SK_ColorBLUE,  false,  "blue"         }, // kBlue_ColorPattern
     30     { SK_ColorWHITE, true,   "obaqueBitMap" }, // kOpaqueBitmap_ColorPattern
     31     { 0x10000000,    true,   "alphaBitmap"  }, // kAlphaBitmap_ColorPattern
     32 };
     33 
     34 enum DrawType {
     35     kRect_DrawType,
     36     kPath_DrawType,
     37 };
     38 
     39 static void makebm(SkBitmap* bm, int w, int h) {
     40     bm->allocN32Pixels(w, h);
     41     bm->eraseColor(SK_ColorTRANSPARENT);
     42 
     43     SkCanvas    canvas(*bm);
     44     SkScalar    s = SkIntToScalar(SkMin32(w, h));
     45     static const SkPoint     kPts0[] = { { 0, 0 }, { s, s } };
     46     static const SkPoint     kPts1[] = { { s/2, 0 }, { s/2, s } };
     47     static const SkScalar    kPos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
     48     static const SkColor kColors0[] = {0x80F00080, 0xF0F08000, 0x800080F0 };
     49     static const SkColor kColors1[] = {0xF08000F0, 0x8080F000, 0xF000F080 };
     50 
     51 
     52     SkPaint     paint;
     53 
     54     paint.setShader(SkGradientShader::CreateLinear(kPts0, kColors0, kPos,
     55                     SK_ARRAY_COUNT(kColors0), SkShader::kClamp_TileMode))->unref();
     56     canvas.drawPaint(paint);
     57     paint.setShader(SkGradientShader::CreateLinear(kPts1, kColors1, kPos,
     58                     SK_ARRAY_COUNT(kColors1), SkShader::kClamp_TileMode))->unref();
     59     canvas.drawPaint(paint);
     60 }
     61 
     62 /**
     63  * This bench draws a grid of either rects or filled paths, with two alternating color patterns.
     64  * This color patterns are passed in as enums to the class. The options are:
     65  *   1) solid white color
     66  *   2) solid blue color
     67  *   3) opaque bitmap
     68  *   4) partial alpha bitmap
     69  * The same color pattern can be set for both arguments to create a uniform pattern on all draws.
     70  *
     71  * The bench is used to test a few things. First it can test any optimizations made for a specific
     72  * color pattern (for example drawing an opaque bitmap versus one with partial alpha). Also it can
     73  * be used to test the cost of program switching and/or batching when alternating between different
     74  * patterns when on the gpu.
     75  */
     76 class AlternatingColorPatternBench : public Benchmark {
     77 public:
     78     enum {
     79         NX = 5,
     80         NY = 5,
     81         NUM_DRAWS = NX * NY,
     82     };
     83     SkShader* fBmShader;
     84 
     85     SkPath  fPaths[NUM_DRAWS];
     86     SkRect  fRects[NUM_DRAWS];
     87     SkColor fColors[NUM_DRAWS];
     88     SkShader* fShaders[NUM_DRAWS];
     89 
     90     SkString        fName;
     91     ColorPatternData    fPattern1;
     92     ColorPatternData    fPattern2;
     93     DrawType fDrawType;
     94     SkBitmap fBmp;
     95 
     96 
     97     AlternatingColorPatternBench(ColorPattern pattern1, ColorPattern pattern2, DrawType drawType)
     98         : fBmShader(nullptr) {
     99         fPattern1 = gColorPatterns[pattern1];
    100         fPattern2 = gColorPatterns[pattern2];
    101         fName.printf("colorPattern_%s_%s_%s",
    102                      fPattern1.fName, fPattern2.fName,
    103                      kRect_DrawType == drawType ? "rect" : "path");
    104         fDrawType = drawType;
    105     }
    106 
    107     virtual ~AlternatingColorPatternBench() {
    108         SkSafeUnref(fBmShader);
    109     }
    110 
    111 protected:
    112     const char* onGetName() override {
    113         return fName.c_str();
    114     }
    115 
    116     void onDelayedSetup() override {
    117         int w = 40;
    118         int h = 40;
    119         makebm(&fBmp, w, h);
    120         fBmShader = SkShader::CreateBitmapShader(fBmp,
    121                                                  SkShader::kRepeat_TileMode,
    122                                                  SkShader::kRepeat_TileMode);
    123         int offset = 2;
    124         int count = 0;
    125         for (int j = 0; j < NY; ++j) {
    126             for (int i = 0; i < NX; ++i) {
    127                 int x = (w + offset) * i;
    128                 int y = (h * offset) * j;
    129                 if (kRect_DrawType == fDrawType) {
    130                     fRects[count].set(SkIntToScalar(x), SkIntToScalar(y),
    131                                       SkIntToScalar(x + w), SkIntToScalar(y + h));
    132                 } else {
    133                     fPaths[count].moveTo(SkIntToScalar(x), SkIntToScalar(y));
    134                     fPaths[count].rLineTo(SkIntToScalar(w), 0);
    135                     fPaths[count].rLineTo(0, SkIntToScalar(h));
    136                     fPaths[count].rLineTo(SkIntToScalar(-w + 1), 0);
    137                 }
    138                 if (0 == count % 2) {
    139                     fColors[count]  = fPattern1.fColor;
    140                     fShaders[count] = fPattern1.fIsBitmap ? fBmShader : nullptr;
    141                 } else {
    142                     fColors[count]  = fPattern2.fColor;
    143                     fShaders[count] = fPattern2.fIsBitmap ? fBmShader : nullptr;
    144                 }
    145                 ++count;
    146             }
    147         }
    148     }
    149 
    150     void onDraw(int loops, SkCanvas* canvas) override {
    151         SkPaint paint;
    152         paint.setAntiAlias(false);
    153         paint.setFilterQuality(kLow_SkFilterQuality);
    154 
    155         for (int i = 0; i < loops; ++i) {
    156             for (int j = 0; j < NUM_DRAWS; ++j) {
    157                 paint.setColor(fColors[j]);
    158                 paint.setShader(fShaders[j]);
    159                 if (kRect_DrawType == fDrawType) {
    160                     canvas->drawRect(fRects[j], paint);
    161                 } else {
    162                     canvas->drawPath(fPaths[j], paint);
    163                 }
    164             }
    165         }
    166     }
    167 
    168 private:
    169     typedef Benchmark INHERITED;
    170 };
    171 
    172 DEF_BENCH(return new AlternatingColorPatternBench(kWhite_ColorPattern,
    173                                                   kWhite_ColorPattern,
    174                                                   kPath_DrawType);)
    175 DEF_BENCH(return new AlternatingColorPatternBench(kBlue_ColorPattern,
    176                                                   kBlue_ColorPattern,
    177                                                   kPath_DrawType);)
    178 DEF_BENCH(return new AlternatingColorPatternBench(kWhite_ColorPattern,
    179                                                   kBlue_ColorPattern,
    180                                                   kPath_DrawType);)
    181 
    182 DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern,
    183                                                   kOpaqueBitmap_ColorPattern,
    184                                                   kPath_DrawType);)
    185 DEF_BENCH(return new AlternatingColorPatternBench(kAlphaBitmap_ColorPattern,
    186                                                   kAlphaBitmap_ColorPattern,
    187                                                   kPath_DrawType);)
    188 DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern,
    189                                                   kAlphaBitmap_ColorPattern,
    190                                                   kPath_DrawType);)
    191 
    192 DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern,
    193                                                   kOpaqueBitmap_ColorPattern,
    194                                                   kRect_DrawType);)
    195 DEF_BENCH(return new AlternatingColorPatternBench(kAlphaBitmap_ColorPattern,
    196                                                   kAlphaBitmap_ColorPattern,
    197                                                   kRect_DrawType);)
    198 DEF_BENCH(return new AlternatingColorPatternBench(kOpaqueBitmap_ColorPattern,
    199                                                   kAlphaBitmap_ColorPattern,
    200                                                   kRect_DrawType);)
    201