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