Home | History | Annotate | Download | only in bench
      1 /*
      2  * Copyright 2011 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 "SkBitmap.h"
     10 #include "SkCanvas.h"
     11 #include "SkCommandLineFlags.h"
     12 #include "SkPaint.h"
     13 #include "SkRandom.h"
     14 #include "SkShader.h"
     15 #include "SkString.h"
     16 
     17 DEFINE_double(strokeWidth, -1.0, "If set, use this stroke width in RectBench.");
     18 
     19 class RectBench : public Benchmark {
     20 public:
     21     int fShift, fStroke;
     22     enum {
     23         W = 640,
     24         H = 480,
     25         N = 300,
     26     };
     27     SkRect  fRects[N];
     28     SkColor fColors[N];
     29 
     30     RectBench(int shift, int stroke = 0)
     31         : fShift(shift)
     32         , fStroke(stroke) {}
     33 
     34     const char* computeName(const char root[]) {
     35         fBaseName.printf("%s_%d", root, fShift);
     36         if (fStroke > 0) {
     37             fBaseName.appendf("_stroke_%d", fStroke);
     38         }
     39         return fBaseName.c_str();
     40     }
     41 
     42     bool isVisual() override { return true; }
     43 
     44 protected:
     45 
     46     virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
     47         c->drawRect(r, p);
     48     }
     49 
     50     const char* onGetName() override { return computeName("rects"); }
     51 
     52     void onDelayedSetup() override {
     53         SkRandom rand;
     54         const SkScalar offset = SK_Scalar1/3;
     55         for (int i = 0; i < N; i++) {
     56             int x = rand.nextU() % W;
     57             int y = rand.nextU() % H;
     58             int w = rand.nextU() % W;
     59             int h = rand.nextU() % H;
     60             w >>= fShift;
     61             h >>= fShift;
     62             x -= w/2;
     63             y -= h/2;
     64             fRects[i].set(SkIntToScalar(x), SkIntToScalar(y),
     65                           SkIntToScalar(x+w), SkIntToScalar(y+h));
     66             fRects[i].offset(offset, offset);
     67             fColors[i] = rand.nextU() | 0xFF808080;
     68         }
     69     }
     70 
     71     void onDraw(int loops, SkCanvas* canvas) override {
     72         SkPaint paint;
     73         if (fStroke > 0) {
     74             paint.setStyle(SkPaint::kStroke_Style);
     75             paint.setStrokeWidth(SkIntToScalar(fStroke));
     76         }
     77         for (int i = 0; i < loops; i++) {
     78             paint.setColor(fColors[i % N]);
     79             this->setupPaint(&paint);
     80             this->drawThisRect(canvas, fRects[i % N], paint);
     81         }
     82     }
     83 
     84 private:
     85     SkString fBaseName;
     86     typedef Benchmark INHERITED;
     87 };
     88 
     89 class SrcModeRectBench : public RectBench {
     90 public:
     91     SrcModeRectBench() : INHERITED(1, 0) {
     92         fMode = SkBlendMode::kSrc;
     93     }
     94 
     95 protected:
     96     void setupPaint(SkPaint* paint) override {
     97         this->INHERITED::setupPaint(paint);
     98         // srcmode is most interesting when we're not opaque
     99         paint->setAlpha(0x80);
    100         paint->setBlendMode(fMode);
    101     }
    102 
    103     const char* onGetName() override {
    104         fName.set(this->INHERITED::onGetName());
    105         fName.prepend("srcmode_");
    106         return fName.c_str();
    107     }
    108 
    109 private:
    110     SkBlendMode fMode;
    111     SkString fName;
    112 
    113     typedef RectBench INHERITED;
    114 };
    115 
    116 class TransparentRectBench : public RectBench {
    117 public:
    118     TransparentRectBench() : INHERITED(1, 0) {}
    119 
    120 protected:
    121     void setupPaint(SkPaint* paint) override {
    122         this->INHERITED::setupPaint(paint);
    123         // draw non opaque rect
    124         paint->setAlpha(0x80);
    125     }
    126 
    127     const char* onGetName() override {
    128         fName.set(this->INHERITED::onGetName());
    129         fName.prepend("transparent_");
    130         return fName.c_str();
    131     }
    132 
    133 private:
    134     SkString fName;
    135     typedef RectBench INHERITED;
    136 };
    137 
    138 
    139 class OvalBench : public RectBench {
    140 public:
    141     OvalBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
    142 protected:
    143     void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
    144         c->drawOval(r, p);
    145     }
    146     const char* onGetName() override { return computeName("ovals"); }
    147 };
    148 
    149 class RRectBench : public RectBench {
    150 public:
    151     RRectBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
    152 protected:
    153     void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
    154         c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
    155     }
    156     const char* onGetName() override { return computeName("rrects"); }
    157 };
    158 
    159 class PointsBench : public RectBench {
    160 public:
    161     SkCanvas::PointMode fMode;
    162 
    163     PointsBench(SkCanvas::PointMode mode, const char* name)
    164         : RectBench(2)
    165         , fMode(mode) {
    166         fName = name;
    167     }
    168 
    169 protected:
    170     void onDraw(int loops, SkCanvas* canvas) override {
    171         SkScalar gSizes[] = {
    172             SkIntToScalar(7), 0
    173         };
    174         size_t sizes = SK_ARRAY_COUNT(gSizes);
    175 
    176         if (FLAGS_strokeWidth >= 0) {
    177             gSizes[0] = (SkScalar)FLAGS_strokeWidth;
    178             sizes = 1;
    179         }
    180 
    181         SkPaint paint;
    182         paint.setStrokeCap(SkPaint::kRound_Cap);
    183 
    184         for (int loop = 0; loop < loops; loop++) {
    185             for (size_t i = 0; i < sizes; i++) {
    186                 paint.setStrokeWidth(gSizes[i]);
    187                 this->setupPaint(&paint);
    188                 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
    189                 paint.setColor(fColors[i % N]);
    190             }
    191         }
    192     }
    193     const char* onGetName() override { return fName.c_str(); }
    194 
    195 private:
    196     SkString fName;
    197 
    198 };
    199 
    200 /*******************************************************************************
    201  * to bench BlitMask [Opaque, Black, color, shader]
    202  *******************************************************************************/
    203 
    204 class BlitMaskBench : public RectBench {
    205 public:
    206     enum kMaskType {
    207         kMaskOpaque = 0,
    208         kMaskBlack,
    209         kMaskColor,
    210         KMaskShader
    211     };
    212     SkCanvas::PointMode fMode;
    213 
    214     BlitMaskBench(SkCanvas::PointMode mode,
    215                   BlitMaskBench::kMaskType type, const char* name) :
    216         RectBench(2), fMode(mode), _type(type) {
    217         fName = name;
    218     }
    219 
    220 protected:
    221     void onDraw(int loops, SkCanvas* canvas) override {
    222         SkScalar gSizes[] = {
    223             SkIntToScalar(13), SkIntToScalar(24)
    224         };
    225         size_t sizes = SK_ARRAY_COUNT(gSizes);
    226 
    227         if (FLAGS_strokeWidth >= 0) {
    228             gSizes[0] = (SkScalar)FLAGS_strokeWidth;
    229             sizes = 1;
    230         }
    231         SkRandom rand;
    232         SkColor color = 0xFF000000;
    233         U8CPU alpha = 0xFF;
    234         SkPaint paint;
    235         paint.setStrokeCap(SkPaint::kRound_Cap);
    236         if (_type == KMaskShader) {
    237             SkBitmap srcBM;
    238             srcBM.allocN32Pixels(10, 1);
    239             srcBM.eraseColor(0xFF00FF00);
    240 
    241             paint.setShader(SkShader::MakeBitmapShader(srcBM, SkShader::kClamp_TileMode,
    242                                                        SkShader::kClamp_TileMode));
    243         }
    244         for (int loop = 0; loop < loops; loop++) {
    245             for (size_t i = 0; i < sizes; i++) {
    246                 switch (_type) {
    247                     case kMaskOpaque:
    248                         color = fColors[i];
    249                         alpha = 0xFF;
    250                         break;
    251                     case kMaskBlack:
    252                         alpha = 0xFF;
    253                         color = 0xFF000000;
    254                         break;
    255                     case kMaskColor:
    256                         color = fColors[i];
    257                         alpha = rand.nextU() & 255;
    258                         break;
    259                     case KMaskShader:
    260                         break;
    261                 }
    262                 paint.setStrokeWidth(gSizes[i]);
    263                 this->setupPaint(&paint);
    264                 paint.setColor(color);
    265                 paint.setAlpha(alpha);
    266                 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
    267            }
    268         }
    269     }
    270     const char* onGetName() override { return fName.c_str(); }
    271 
    272 private:
    273     typedef RectBench INHERITED;
    274     kMaskType _type;
    275     SkString fName;
    276 };
    277 
    278 DEF_BENCH(return new RectBench(1);)
    279 DEF_BENCH(return new RectBench(1, 4);)
    280 DEF_BENCH(return new RectBench(3);)
    281 DEF_BENCH(return new RectBench(3, 4);)
    282 DEF_BENCH(return new OvalBench(1);)
    283 DEF_BENCH(return new OvalBench(3);)
    284 DEF_BENCH(return new OvalBench(1, 4);)
    285 DEF_BENCH(return new OvalBench(3, 4);)
    286 DEF_BENCH(return new RRectBench(1);)
    287 DEF_BENCH(return new RRectBench(1, 4);)
    288 DEF_BENCH(return new RRectBench(3);)
    289 DEF_BENCH(return new RRectBench(3, 4);)
    290 DEF_BENCH(return new PointsBench(SkCanvas::kPoints_PointMode, "points");)
    291 DEF_BENCH(return new PointsBench(SkCanvas::kLines_PointMode, "lines");)
    292 DEF_BENCH(return new PointsBench(SkCanvas::kPolygon_PointMode, "polygon");)
    293 
    294 DEF_BENCH(return new SrcModeRectBench();)
    295 
    296 DEF_BENCH(return new TransparentRectBench();)
    297 
    298 /* init the blitmask bench
    299  */
    300 DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
    301                                    BlitMaskBench::kMaskOpaque,
    302                                    "maskopaque");)
    303 DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
    304                                    BlitMaskBench::kMaskBlack,
    305                                    "maskblack");)
    306 DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
    307                                    BlitMaskBench::kMaskColor,
    308                                    "maskcolor");)
    309 DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
    310                                    BlitMaskBench::KMaskShader,
    311                                    "maskshader");)
    312