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