Home | History | Annotate | Download | only in bench
      1 /*
      2  * Copyright 2013 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 
      8 #include "Benchmark.h"
      9 #include "SkCanvas.h"
     10 #include "SkPaint.h"
     11 #include "SkRandom.h"
     12 #include "SkShader.h"
     13 #include "SkString.h"
     14 
     15 #if SK_SUPPORT_GPU
     16 #include "GrDrawTargetCaps.h"
     17 #include "GrTest.h"
     18 #endif
     19 
     20 enum Flags {
     21     kBig_Flag = 1 << 0,
     22     kAA_Flag = 1 << 1
     23 };
     24 
     25 #define FLAGS00 Flags(0)
     26 #define FLAGS01 Flags(kBig_Flag)
     27 #define FLAGS10 Flags(kAA_Flag)
     28 #define FLAGS11 Flags(kBig_Flag | kAA_Flag)
     29 
     30 static const int points[] = {
     31     10, 10, 15, 5, 20, 20,
     32     30, 5, 25, 20, 15, 12,
     33     21, 21, 30, 30, 12, 4,
     34     32, 28, 20, 18, 12, 10
     35 };
     36 
     37 static const int kMaxPathSize = 10;
     38 
     39 class HairlinePathBench : public Benchmark {
     40 public:
     41     HairlinePathBench(Flags flags) : fFlags(flags) {
     42         fPaint.setStyle(SkPaint::kStroke_Style);
     43         fPaint.setStrokeWidth(SkIntToScalar(0));
     44     }
     45 
     46     virtual void appendName(SkString*) = 0;
     47     virtual void makePath(SkPath*) = 0;
     48 
     49 protected:
     50     virtual const char* onGetName() SK_OVERRIDE {
     51         fName.printf("path_hairline_%s_%s_",
     52                      fFlags & kBig_Flag ? "big" : "small",
     53                      fFlags & kAA_Flag ? "AA" : "noAA");
     54         this->appendName(&fName);
     55         return fName.c_str();
     56     }
     57 
     58     virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
     59         SkPaint paint(fPaint);
     60         this->setupPaint(&paint);
     61 
     62         paint.setAntiAlias(fFlags & kAA_Flag ? true : false);
     63 
     64         SkPath path;
     65         this->makePath(&path);
     66         if (fFlags & kBig_Flag) {
     67             SkMatrix m;
     68             m.setScale(SkIntToScalar(3), SkIntToScalar(3));
     69             path.transform(m);
     70         }
     71 
     72         for (int i = 0; i < loops; i++) {
     73             canvas->drawPath(path, paint);
     74         }
     75     }
     76 
     77 private:
     78     SkPaint     fPaint;
     79     SkString    fName;
     80     Flags       fFlags;
     81     typedef Benchmark INHERITED;
     82 };
     83 
     84 class LinePathBench : public HairlinePathBench {
     85 public:
     86     LinePathBench(Flags flags) : INHERITED(flags) {}
     87 
     88     virtual void appendName(SkString* name) SK_OVERRIDE {
     89         name->append("line");
     90     }
     91     virtual void makePath(SkPath* path) SK_OVERRIDE {
     92         SkRandom rand;
     93         int size = SK_ARRAY_COUNT(points);
     94         int hSize = size / 2;
     95         for (int i = 0; i < kMaxPathSize; ++i) {
     96             int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
     97             int yTrans = 0;
     98             if (i > kMaxPathSize/2 - 1) {
     99                 yTrans = 40;
    100             }
    101             int base1 = 2 * rand.nextULessThan(hSize);
    102             int base2 = 2 * rand.nextULessThan(hSize);
    103             int base3 = 2 * rand.nextULessThan(hSize);
    104             path->moveTo(SkIntToScalar(points[base1] + xTrans),
    105                          SkIntToScalar(points[base1+1] + yTrans));
    106             path->lineTo(SkIntToScalar(points[base2] + xTrans),
    107                          SkIntToScalar(points[base2+1] + yTrans));
    108             path->lineTo(SkIntToScalar(points[base3] + xTrans),
    109                          SkIntToScalar(points[base3+1] + yTrans));
    110         }
    111     }
    112 private:
    113     typedef HairlinePathBench INHERITED;
    114 };
    115 
    116 class QuadPathBench : public HairlinePathBench {
    117 public:
    118     QuadPathBench(Flags flags) : INHERITED(flags) {}
    119 
    120     virtual void appendName(SkString* name) SK_OVERRIDE {
    121         name->append("quad");
    122     }
    123     virtual void makePath(SkPath* path) SK_OVERRIDE {
    124         SkRandom rand;
    125         int size = SK_ARRAY_COUNT(points);
    126         int hSize = size / 2;
    127         for (int i = 0; i < kMaxPathSize; ++i) {
    128             int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
    129             int yTrans = 0;
    130             if (i > kMaxPathSize/2 - 1) {
    131                 yTrans = 40;
    132             }
    133             int base1 = 2 * rand.nextULessThan(hSize);
    134             int base2 = 2 * rand.nextULessThan(hSize);
    135             int base3 = 2 * rand.nextULessThan(hSize);
    136             path->moveTo(SkIntToScalar(points[base1] + xTrans),
    137                          SkIntToScalar(points[base1+1] + yTrans));
    138             path->quadTo(SkIntToScalar(points[base2] + xTrans),
    139                          SkIntToScalar(points[base2+1] + yTrans),
    140                          SkIntToScalar(points[base3] + xTrans),
    141                          SkIntToScalar(points[base3+1] + yTrans));
    142         }
    143     }
    144 private:
    145     typedef HairlinePathBench INHERITED;
    146 };
    147 
    148 class ConicPathBench : public HairlinePathBench {
    149 public:
    150     ConicPathBench(Flags flags) : INHERITED(flags) {}
    151 
    152     virtual void appendName(SkString* name) SK_OVERRIDE {
    153         name->append("conic");
    154     }
    155     virtual void makePath(SkPath* path) SK_OVERRIDE {
    156         SkRandom rand;
    157         SkRandom randWeight;
    158         int size = SK_ARRAY_COUNT(points);
    159         int hSize = size / 2;
    160         for (int i = 0; i < kMaxPathSize; ++i) {
    161             int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
    162             int yTrans = 0;
    163             if (i > kMaxPathSize/2 - 1) {
    164                 yTrans = 40;
    165             }
    166             int base1 = 2 * rand.nextULessThan(hSize);
    167             int base2 = 2 * rand.nextULessThan(hSize);
    168             int base3 = 2 * rand.nextULessThan(hSize);
    169             float weight = randWeight.nextRangeF(0.0f, 2.0f);
    170             path->moveTo(SkIntToScalar(points[base1] + xTrans),
    171                          SkIntToScalar(points[base1+1] + yTrans));
    172             path->conicTo(SkIntToScalar(points[base2] + xTrans),
    173                           SkIntToScalar(points[base2+1] + yTrans),
    174                          SkIntToScalar(points[base3] + xTrans),
    175                          SkIntToScalar(points[base3+1] + yTrans),
    176                          weight);
    177         }
    178     }
    179 
    180     virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
    181 #if SK_SUPPORT_GPU
    182         GrContext* context = canvas->getGrContext();
    183         // This is a workaround for skbug.com/2078. See also skbug.com/2033.
    184         if (context) {
    185             GrTestTarget tt;
    186             context->getTestTarget(&tt);
    187             if (tt.target()->caps()->pathRenderingSupport()) {
    188                 return;
    189             }
    190         }
    191 #endif
    192         INHERITED::onDraw(loops, canvas);
    193     }
    194 
    195 private:
    196     typedef HairlinePathBench INHERITED;
    197 };
    198 
    199 class CubicPathBench : public HairlinePathBench {
    200 public:
    201     CubicPathBench(Flags flags) : INHERITED(flags) {}
    202 
    203     virtual void appendName(SkString* name) SK_OVERRIDE {
    204         name->append("cubic");
    205     }
    206     virtual void makePath(SkPath* path) SK_OVERRIDE {
    207         SkRandom rand;
    208         int size = SK_ARRAY_COUNT(points);
    209         int hSize = size / 2;
    210         for (int i = 0; i < kMaxPathSize; ++i) {
    211             int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
    212             int yTrans = 0;
    213             if (i > kMaxPathSize/2 - 1) {
    214                 yTrans = 40;
    215             }
    216             int base1 = 2 * rand.nextULessThan(hSize);
    217             int base2 = 2 * rand.nextULessThan(hSize);
    218             int base3 = 2 * rand.nextULessThan(hSize);
    219             int base4 = 2 * rand.nextULessThan(hSize);
    220             path->moveTo(SkIntToScalar(points[base1] + xTrans),
    221                          SkIntToScalar(points[base1+1] + yTrans));
    222             path->cubicTo(SkIntToScalar(points[base2] + xTrans),
    223                          SkIntToScalar(points[base2+1] + yTrans),
    224                          SkIntToScalar(points[base3] + xTrans),
    225                          SkIntToScalar(points[base3+1] + yTrans),
    226                          SkIntToScalar(points[base4] + xTrans),
    227                          SkIntToScalar(points[base4+1] + yTrans));
    228         }
    229     }
    230 private:
    231     typedef HairlinePathBench INHERITED;
    232 };
    233 
    234 // FLAG00 - no AA, small
    235 // FLAG01 - no AA, small
    236 // FLAG10 - AA, big
    237 // FLAG11 - AA, big
    238 
    239 DEF_BENCH( return new LinePathBench(FLAGS00); )
    240 DEF_BENCH( return new LinePathBench(FLAGS01); )
    241 DEF_BENCH( return new LinePathBench(FLAGS10); )
    242 DEF_BENCH( return new LinePathBench(FLAGS11); )
    243 
    244 DEF_BENCH( return new QuadPathBench(FLAGS00); )
    245 DEF_BENCH( return new QuadPathBench(FLAGS01); )
    246 DEF_BENCH( return new QuadPathBench(FLAGS10); )
    247 DEF_BENCH( return new QuadPathBench(FLAGS11); )
    248 
    249 // Don't have default path renderer for conics yet on GPU, so must use AA
    250 // DEF_BENCH( return new ConicPathBench(FLAGS00); )
    251 // DEF_BENCH( return new ConicPathBench(FLAGS01); )
    252 DEF_BENCH( return new ConicPathBench(FLAGS10); )
    253 DEF_BENCH( return new ConicPathBench(FLAGS11); )
    254 
    255 DEF_BENCH( return new CubicPathBench(FLAGS00); )
    256 DEF_BENCH( return new CubicPathBench(FLAGS01); )
    257 DEF_BENCH( return new CubicPathBench(FLAGS10); )
    258 DEF_BENCH( return new CubicPathBench(FLAGS11); )
    259