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 class AARectBench : public Benchmark {
    174 public:
    175     enum {
    176         W = 640,
    177         H = 480,
    178     };
    179 
    180     AARectBench(bool rotate) : fRotate(rotate) {}
    181 
    182 protected:
    183 
    184     virtual const char* onGetName() {
    185         if (fRotate) {
    186             return "aarects_rotated";
    187         }
    188         return "aarects";
    189     }
    190 
    191     virtual void onDraw(const int loops, SkCanvas* canvas) {
    192         static const SkScalar kHalfRectSize = 0.75f;
    193 
    194         SkPaint paint;
    195         this->setupPaint(&paint);
    196         paint.setAntiAlias(true);
    197         paint.setColor(SK_ColorBLACK);
    198         SkRect r = { -kHalfRectSize, -kHalfRectSize, kHalfRectSize, kHalfRectSize };
    199         int rot = 0;
    200 
    201         for (int i = 0; i < loops; i++) {
    202             // Draw small aa rects in a grid across the screen
    203             for (SkScalar y = kHalfRectSize+SK_Scalar1; y < H; y += 2*kHalfRectSize+2) {
    204                 for (SkScalar x = kHalfRectSize+SK_Scalar1; x < W; x += 2*kHalfRectSize+2) {
    205                     canvas->save();
    206                     canvas->translate(x, y);
    207 
    208                     if (fRotate) {
    209                         SkMatrix rotate;
    210                         rotate.setRotate(SkIntToScalar(rot));
    211                         canvas->concat(rotate);
    212                         rot += 10;
    213                     }
    214 
    215                     canvas->drawRect(r, paint);
    216                     canvas->restore();
    217                 }
    218             }
    219         }
    220 
    221     }
    222 private:
    223     bool fRotate;
    224     typedef Benchmark INHERITED;
    225 };
    226 
    227 /*******************************************************************************
    228  * to bench BlitMask [Opaque, Black, color, shader]
    229  *******************************************************************************/
    230 
    231 class BlitMaskBench : public RectBench {
    232 public:
    233     enum kMaskType {
    234         kMaskOpaque = 0,
    235         kMaskBlack,
    236         kMaskColor,
    237         KMaskShader
    238     };
    239     SkCanvas::PointMode fMode;
    240     const char* fName;
    241 
    242     BlitMaskBench(SkCanvas::PointMode mode,
    243                   BlitMaskBench::kMaskType type, const char* name) :
    244         RectBench(2), fMode(mode), _type(type) {
    245         fName = name;
    246     }
    247 
    248 protected:
    249     virtual void onDraw(const int loops, SkCanvas* canvas) {
    250         SkScalar gSizes[] = {
    251             SkIntToScalar(13), SkIntToScalar(24)
    252         };
    253         size_t sizes = SK_ARRAY_COUNT(gSizes);
    254 
    255         if (FLAGS_strokeWidth >= 0) {
    256             gSizes[0] = (SkScalar)FLAGS_strokeWidth;
    257             sizes = 1;
    258         }
    259         SkRandom rand;
    260         SkColor color = 0xFF000000;
    261         U8CPU alpha = 0xFF;
    262         SkPaint paint;
    263         paint.setStrokeCap(SkPaint::kRound_Cap);
    264         if (_type == KMaskShader) {
    265             SkBitmap srcBM;
    266             srcBM.allocN32Pixels(10, 1);
    267             srcBM.eraseColor(0xFF00FF00);
    268 
    269             SkShader* s;
    270             s  = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode,
    271                                               SkShader::kClamp_TileMode);
    272             paint.setShader(s)->unref();
    273         }
    274         for (int loop = 0; loop < loops; loop++) {
    275             for (size_t i = 0; i < sizes; i++) {
    276                 switch (_type) {
    277                     case kMaskOpaque:
    278                         color = fColors[i];
    279                         alpha = 0xFF;
    280                         break;
    281                     case kMaskBlack:
    282                         alpha = 0xFF;
    283                         color = 0xFF000000;
    284                         break;
    285                     case kMaskColor:
    286                         color = fColors[i];
    287                         alpha = rand.nextU() & 255;
    288                         break;
    289                     case KMaskShader:
    290                         break;
    291                 }
    292                 paint.setStrokeWidth(gSizes[i]);
    293                 this->setupPaint(&paint);
    294                 paint.setColor(color);
    295                 paint.setAlpha(alpha);
    296                 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
    297            }
    298         }
    299     }
    300     virtual const char* onGetName() { return fName; }
    301 private:
    302     typedef RectBench INHERITED;
    303     kMaskType _type;
    304 };
    305 
    306 
    307 DEF_BENCH( return SkNEW_ARGS(RectBench, (1)); )
    308 DEF_BENCH( return SkNEW_ARGS(RectBench, (1, 4)); )
    309 DEF_BENCH( return SkNEW_ARGS(RectBench, (3)); )
    310 DEF_BENCH( return SkNEW_ARGS(RectBench, (3, 4)); )
    311 DEF_BENCH( return SkNEW_ARGS(OvalBench, (1)); )
    312 DEF_BENCH( return SkNEW_ARGS(OvalBench, (3)); )
    313 DEF_BENCH( return SkNEW_ARGS(OvalBench, (1, 4)); )
    314 DEF_BENCH( return SkNEW_ARGS(OvalBench, (3, 4)); )
    315 DEF_BENCH( return SkNEW_ARGS(RRectBench, (1)); )
    316 DEF_BENCH( return SkNEW_ARGS(RRectBench, (1, 4)); )
    317 DEF_BENCH( return SkNEW_ARGS(RRectBench, (3)); )
    318 DEF_BENCH( return SkNEW_ARGS(RRectBench, (3, 4)); )
    319 DEF_BENCH( return SkNEW_ARGS(PointsBench, (SkCanvas::kPoints_PointMode, "points")); )
    320 DEF_BENCH( return SkNEW_ARGS(PointsBench, (SkCanvas::kLines_PointMode, "lines")); )
    321 DEF_BENCH( return SkNEW_ARGS(PointsBench, (SkCanvas::kPolygon_PointMode, "polygon")); )
    322 
    323 DEF_BENCH( return SkNEW_ARGS(SrcModeRectBench, ()); )
    324 
    325 DEF_BENCH( return SkNEW_ARGS(AARectBench, (false)); )
    326 DEF_BENCH( return SkNEW_ARGS(AARectBench, (true)); )
    327 
    328 /* init the blitmask bench
    329  */
    330 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
    331                       (SkCanvas::kPoints_PointMode,
    332                       BlitMaskBench::kMaskOpaque, "maskopaque")
    333                       ); )
    334 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
    335                       (SkCanvas::kPoints_PointMode,
    336                       BlitMaskBench::kMaskBlack, "maskblack")
    337                       ); )
    338 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
    339                       (SkCanvas::kPoints_PointMode,
    340                       BlitMaskBench::kMaskColor, "maskcolor")
    341                       ); )
    342 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
    343                      (SkCanvas::kPoints_PointMode,
    344                      BlitMaskBench::KMaskShader, "maskshader")
    345                      ); )
    346