Home | History | Annotate | Download | only in bench
      1 /*
      2  * Copyright 2014 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 "SkGeometry.h"
     10 #include "SkRandom.h"
     11 #include "SkRect.h"
     12 
     13 class GeometryBench : public Benchmark {
     14 public:
     15     GeometryBench(const char suffix[]) : fVolatileInt(0) {
     16         fName.printf("geo_%s", suffix);
     17     }
     18 
     19     const char* onGetName() override {
     20         return fName.c_str();
     21     }
     22 
     23     bool isSuitableFor(Backend backend) override {
     24         return kNonRendering_Backend == backend;
     25     }
     26 
     27 protected:
     28     volatile int fVolatileInt;
     29 
     30     /**
     31      *  Subclasses can call this to try to defeat the optimizer (with some result of their
     32      *  inner loop), since it will fool the compiler into assuming that "n" is actually
     33      *  needed somewhere, and since this method is not const, the member fields cannot
     34      *  be assumed to be const before and after the call.
     35      */
     36     virtual void virtualCallToFoilOptimizers(int n) { fVolatileInt += n; }
     37 
     38 private:
     39     SkString fName;
     40 };
     41 
     42 class GeoRectBench : public GeometryBench {
     43 public:
     44     GeoRectBench(const char suffix[]) : GeometryBench(suffix) {}
     45 
     46 protected:
     47     SkRect fRects[2048];
     48 
     49     virtual void onDelayedSetup() {
     50         const SkScalar min = -100;
     51         const SkScalar max = 100;
     52         SkRandom rand;
     53         for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
     54             SkScalar x = rand.nextRangeScalar(min, max);
     55             SkScalar y = rand.nextRangeScalar(min, max);
     56             SkScalar w = rand.nextRangeScalar(min, max);
     57             SkScalar h = rand.nextRangeScalar(min, max);
     58             fRects[i].setXYWH(x, y, w, h);
     59         }
     60     }
     61 };
     62 
     63 class GeoRectBench_intersect : public GeoRectBench {
     64 public:
     65     GeoRectBench_intersect() : GeoRectBench("rect_intersect") {}
     66 
     67 protected:
     68     void onDraw(int loops, SkCanvas* canvas) override {
     69         for (int outer = 0; outer < loops; ++outer) {
     70             int count = 0;
     71             for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
     72                 SkRect r = fRects[0];
     73                 count += r.intersect(fRects[i]);
     74             }
     75             this->virtualCallToFoilOptimizers(count);
     76         }
     77     }
     78 };
     79 
     80 class GeoRectBench_intersect_rect : public GeoRectBench {
     81 public:
     82     GeoRectBench_intersect_rect() : GeoRectBench("rect_intersect_rect") {}
     83 
     84 protected:
     85     void onDraw(int loops, SkCanvas* canvas) override {
     86         for (int outer = 0; outer < loops; ++outer) {
     87             int count = 0;
     88             SkRect r;
     89             for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
     90                 count += r.intersect(fRects[0], fRects[i]);
     91             }
     92             this->virtualCallToFoilOptimizers(count);
     93         }
     94     }
     95 };
     96 
     97 class GeoRectBench_Intersects : public GeoRectBench {
     98 public:
     99     GeoRectBench_Intersects() : GeoRectBench("rect_Intersects") {}
    100 
    101 protected:
    102     void onDraw(int loops, SkCanvas* canvas) override {
    103         for (int outer = 0; outer < loops; ++outer) {
    104             int count = 0;
    105             for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
    106                 count += SkRect::Intersects(fRects[0], fRects[i]);
    107             }
    108             this->virtualCallToFoilOptimizers(count);
    109         }
    110     }
    111 };
    112 
    113 class GeoRectBench_sort : public GeoRectBench {
    114 public:
    115     GeoRectBench_sort() : GeoRectBench("rect_sort") {}
    116 
    117 protected:
    118     void onDraw(int loops, SkCanvas* canvas) override {
    119         for (int outer = 0; outer < loops; ++outer) {
    120             for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
    121                 fRects[i].sort();
    122             }
    123         }
    124     }
    125 };
    126 
    127 DEF_BENCH( return new GeoRectBench_intersect; )
    128 DEF_BENCH( return new GeoRectBench_intersect_rect; )
    129 DEF_BENCH( return new GeoRectBench_Intersects; )
    130 
    131 DEF_BENCH( return new GeoRectBench_sort; )
    132 
    133 ///////////////////////////////////////////////////////////////////////////////////////////////////
    134 
    135 class QuadBenchBase : public GeometryBench {
    136 protected:
    137     SkPoint fPts[4];
    138 public:
    139     QuadBenchBase(const char name[]) : GeometryBench(name) {
    140         SkRandom rand;
    141         for (int i = 0; i < 4; ++i) {
    142             fPts[i].set(rand.nextUScalar1(), rand.nextUScalar1());
    143         }
    144     }
    145 };
    146 
    147 class EvalQuadAt0 : public QuadBenchBase {
    148 public:
    149     EvalQuadAt0() : QuadBenchBase("evalquadat0") {}
    150 protected:
    151     void onDraw(int loops, SkCanvas* canvas) override {
    152         SkPoint result;
    153         for (int outer = 0; outer < loops; ++outer) {
    154             SkEvalQuadAt(fPts, 0.5f, &result);
    155             SkEvalQuadAt(fPts, 0.5f, &result);
    156             SkEvalQuadAt(fPts, 0.5f, &result);
    157             SkEvalQuadAt(fPts, 0.5f, &result);
    158         }
    159     }
    160 };
    161 DEF_BENCH( return new EvalQuadAt0; )
    162 
    163 class EvalQuadAt1 : public QuadBenchBase {
    164 public:
    165     EvalQuadAt1() : QuadBenchBase("evalquadat1") {}
    166 protected:
    167     void onDraw(int loops, SkCanvas* canvas) override {
    168         SkPoint result;
    169         for (int outer = 0; outer < loops; ++outer) {
    170             result = SkEvalQuadAt(fPts, 0.5f);
    171             result = SkEvalQuadAt(fPts, 0.5f);
    172             result = SkEvalQuadAt(fPts, 0.5f);
    173             result = SkEvalQuadAt(fPts, 0.5f);
    174         }
    175     }
    176 };
    177 DEF_BENCH( return new EvalQuadAt1; )
    178 
    179 ////////
    180 
    181 class EvalQuadTangentAt0 : public QuadBenchBase {
    182 public:
    183     EvalQuadTangentAt0() : QuadBenchBase("evalquadtangentat0") {}
    184 protected:
    185     void onDraw(int loops, SkCanvas* canvas) override {
    186         SkPoint result;
    187         for (int outer = 0; outer < loops; ++outer) {
    188             SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
    189             SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
    190             SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
    191             SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
    192         }
    193     }
    194 };
    195 DEF_BENCH( return new EvalQuadTangentAt0; )
    196 
    197 class EvalQuadTangentAt1 : public QuadBenchBase {
    198 public:
    199     EvalQuadTangentAt1() : QuadBenchBase("evalquadtangentat1") {}
    200 protected:
    201     void onDraw(int loops, SkCanvas* canvas) override {
    202         SkPoint result;
    203         for (int outer = 0; outer < loops; ++outer) {
    204             result = SkEvalQuadTangentAt(fPts, 0.5f);
    205             result = SkEvalQuadTangentAt(fPts, 0.5f);
    206             result = SkEvalQuadTangentAt(fPts, 0.5f);
    207             result = SkEvalQuadTangentAt(fPts, 0.5f);
    208         }
    209     }
    210 };
    211 DEF_BENCH( return new EvalQuadTangentAt1; )
    212 
    213 ////////
    214 
    215 class ChopQuadAt : public QuadBenchBase {
    216 public:
    217     ChopQuadAt() : QuadBenchBase("chopquadat") {}
    218 protected:
    219     void onDraw(int loops, SkCanvas* canvas) override {
    220         SkPoint dst[5];
    221         for (int outer = 0; outer < loops; ++outer) {
    222             SkChopQuadAt(fPts, dst, 0.5f);
    223             SkChopQuadAt(fPts, dst, 0.5f);
    224             SkChopQuadAt(fPts, dst, 0.5f);
    225             SkChopQuadAt(fPts, dst, 0.5f);
    226         }
    227     }
    228 };
    229 DEF_BENCH( return new ChopQuadAt; )
    230 
    231 class ChopCubicAt : public QuadBenchBase {
    232 public:
    233     ChopCubicAt() : QuadBenchBase("chopcubicat0") {}
    234 protected:
    235     void onDraw(int loops, SkCanvas* canvas) override {
    236         SkPoint dst[7];
    237         for (int outer = 0; outer < loops; ++outer) {
    238             SkChopCubicAt(fPts, dst, 0.5f);
    239             SkChopCubicAt(fPts, dst, 0.5f);
    240             SkChopCubicAt(fPts, dst, 0.5f);
    241             SkChopCubicAt(fPts, dst, 0.5f);
    242         }
    243     }
    244 };
    245 DEF_BENCH( return new ChopCubicAt; )
    246