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) : RectBench(param, shift) {}
    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) : RectBench(param, shift) {}
    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) : INHERITED(param) {}
    173 
    174 protected:
    175 
    176     virtual const char* onGetName() { return "aarects"; }
    177 
    178     virtual void onDraw(SkCanvas* canvas) {
    179         SkPaint paint;
    180         this->setupPaint(&paint);
    181         paint.setAntiAlias(true);
    182         paint.setColor(SK_ColorBLACK);
    183         SkRect r;
    184 
    185         // Draw small aa rects in a grid across the screen
    186         for (SkScalar y = SK_ScalarHalf; y < H; y += SkIntToScalar(2)) {
    187             for (SkScalar x = SK_ScalarHalf; x < W; x += SkIntToScalar(2)) {
    188                 r.set(x, y,
    189                       x+SkFloatToScalar(1.5f), y+SkFloatToScalar(1.5f));
    190                 canvas->drawRect(r, paint);
    191             }
    192         }
    193 
    194     }
    195 private:
    196     typedef SkBenchmark INHERITED;
    197 };
    198 
    199 /*******************************************************************************
    200  * to bench BlitMask [Opaque, Black, color, shader]
    201  *******************************************************************************/
    202 
    203 class BlitMaskBench : public RectBench {
    204 public:
    205     enum kMaskType {
    206         kMaskOpaque = 0,
    207         kMaskBlack,
    208         kMaskColor,
    209         KMaskShader
    210     };
    211     SkCanvas::PointMode fMode;
    212     const char* fName;
    213 
    214     BlitMaskBench(void* param, SkCanvas::PointMode mode,
    215                   BlitMaskBench::kMaskType type, const char* name) :
    216                   RectBench(param, 2), fMode(mode), _type(type) {
    217         fName = name;
    218     }
    219 
    220 protected:
    221     virtual void onDraw(SkCanvas* canvas) {
    222         SkScalar gSizes[] = {
    223             SkIntToScalar(13), SkIntToScalar(24)
    224         };
    225         size_t sizes = SK_ARRAY_COUNT(gSizes);
    226 
    227         if (this->hasStrokeWidth()) {
    228             gSizes[0] = this->getStrokeWidth();
    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.setConfig(SkBitmap::kARGB_8888_Config, 10, 1);
    239             srcBM.allocPixels();
    240             srcBM.eraseColor(0xFF00FF00);
    241 
    242             SkShader* s;
    243             s  = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode,
    244                                               SkShader::kClamp_TileMode);
    245             paint.setShader(s)->unref();
    246         }
    247         for (size_t i = 0; i < sizes; i++) {
    248             switch (_type) {
    249                 case kMaskOpaque:
    250                     color = fColors[i];
    251                     alpha = 0xFF;
    252                     break;
    253                 case kMaskBlack:
    254                     alpha = 0xFF;
    255                     color = 0xFF000000;
    256                     break;
    257                 case kMaskColor:
    258                     color = fColors[i];
    259                     alpha = rand.nextU() & 255;
    260                     break;
    261                 case KMaskShader:
    262                     break;
    263             }
    264             paint.setStrokeWidth(gSizes[i]);
    265             this->setupPaint(&paint);
    266             paint.setColor(color);
    267             paint.setAlpha(alpha);
    268             canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
    269        }
    270     }
    271     virtual const char* onGetName() { return fName; }
    272 private:
    273     typedef RectBench INHERITED;
    274     kMaskType _type;
    275 };
    276 
    277 
    278 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1)); )
    279 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 1, 4)); )
    280 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3)); )
    281 DEF_BENCH( return SkNEW_ARGS(RectBench, (p, 3, 4)); )
    282 DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 1)); )
    283 DEF_BENCH( return SkNEW_ARGS(OvalBench, (p, 3)); )
    284 DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 1)); )
    285 DEF_BENCH( return SkNEW_ARGS(RRectBench, (p, 3)); )
    286 DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPoints_PointMode, "points")); )
    287 DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kLines_PointMode, "lines")); )
    288 DEF_BENCH( return SkNEW_ARGS(PointsBench, (p, SkCanvas::kPolygon_PointMode, "polygon")); )
    289 
    290 DEF_BENCH( return SkNEW_ARGS(SrcModeRectBench, (p)); )
    291 DEF_BENCH( return SkNEW_ARGS(AARectBench, (p)); )
    292 
    293 /* init the blitmask bench
    294  */
    295 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
    296                       (p, SkCanvas::kPoints_PointMode,
    297                       BlitMaskBench::kMaskOpaque, "maskopaque")
    298                       ); )
    299 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
    300                       (p, SkCanvas::kPoints_PointMode,
    301                       BlitMaskBench::kMaskBlack, "maskblack")
    302                       ); )
    303 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
    304                       (p, SkCanvas::kPoints_PointMode,
    305                       BlitMaskBench::kMaskColor, "maskcolor")
    306                       ); )
    307 DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
    308                      (p, SkCanvas::kPoints_PointMode,
    309                      BlitMaskBench::KMaskShader, "maskshader")
    310                      ); )
    311