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