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 "SkRandom.h"
     10 #include "SkRegion.h"
     11 #include "SkString.h"
     12 
     13 static bool union_proc(SkRegion& a, SkRegion& b) {
     14     SkRegion result;
     15     return result.op(a, b, SkRegion::kUnion_Op);
     16 }
     17 
     18 static bool sect_proc(SkRegion& a, SkRegion& b) {
     19     SkRegion result;
     20     return result.op(a, b, SkRegion::kIntersect_Op);
     21 }
     22 
     23 static bool diff_proc(SkRegion& a, SkRegion& b) {
     24     SkRegion result;
     25     return result.op(a, b, SkRegion::kDifference_Op);
     26 }
     27 
     28 static bool diffrect_proc(SkRegion& a, SkRegion& b) {
     29     SkRegion result;
     30     return result.op(a, b.getBounds(), SkRegion::kDifference_Op);
     31 }
     32 
     33 static bool diffrectbig_proc(SkRegion& a, SkRegion& b) {
     34     SkRegion result;
     35     return result.op(a, a.getBounds(), SkRegion::kDifference_Op);
     36 }
     37 
     38 static bool containsrect_proc(SkRegion& a, SkRegion& b) {
     39     SkIRect r = a.getBounds();
     40     r.inset(r.width()/4, r.height()/4);
     41     (void)a.contains(r);
     42 
     43     r = b.getBounds();
     44     r.inset(r.width()/4, r.height()/4);
     45     return b.contains(r);
     46 }
     47 
     48 static bool sectsrgn_proc(SkRegion& a, SkRegion& b) {
     49     return a.intersects(b);
     50 }
     51 
     52 static bool sectsrect_proc(SkRegion& a, SkRegion& b) {
     53     SkIRect r = a.getBounds();
     54     r.inset(r.width()/4, r.height()/4);
     55     return a.intersects(r);
     56 }
     57 
     58 static bool containsxy_proc(SkRegion& a, SkRegion& b) {
     59     const SkIRect& r = a.getBounds();
     60     const int dx = r.width() / 8;
     61     const int dy = r.height() / 8;
     62     for (int y = r.fTop; y < r.fBottom; y += dy) {
     63         for (int x = r.fLeft; x < r.fRight; x += dx) {
     64             (void)a.contains(x, y);
     65         }
     66     }
     67     return true;
     68 }
     69 
     70 class RegionBench : public Benchmark {
     71 public:
     72     typedef bool (*Proc)(SkRegion& a, SkRegion& b);
     73 
     74     SkRegion fA, fB;
     75     Proc     fProc;
     76     SkString fName;
     77 
     78     enum {
     79         W = 1024,
     80         H = 768,
     81     };
     82 
     83     SkIRect randrect(SkRandom& rand) {
     84         int x = rand.nextU() % W;
     85         int y = rand.nextU() % H;
     86         int w = rand.nextU() % W;
     87         int h = rand.nextU() % H;
     88         return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1);
     89     }
     90 
     91     RegionBench(int count, Proc proc, const char name[])  {
     92         fProc = proc;
     93         fName.printf("region_%s_%d", name, count);
     94 
     95         SkRandom rand;
     96         for (int i = 0; i < count; i++) {
     97             fA.op(randrect(rand), SkRegion::kXOR_Op);
     98             fB.op(randrect(rand), SkRegion::kXOR_Op);
     99         }
    100     }
    101 
    102     virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
    103         return backend == kNonRendering_Backend;
    104     }
    105 
    106 protected:
    107     virtual const char* onGetName() { return fName.c_str(); }
    108 
    109     virtual void onDraw(const int loops, SkCanvas* canvas) {
    110         Proc proc = fProc;
    111         for (int i = 0; i < loops; ++i) {
    112             proc(fA, fB);
    113         }
    114     }
    115 
    116 private:
    117     typedef Benchmark INHERITED;
    118 };
    119 
    120 class RectSectBench : public Benchmark {
    121     enum {
    122         N = 1000
    123     };
    124     SkRect fArray0[N];
    125     SkRect fArray1[N];
    126     SkString fName;
    127     bool fNewWay;
    128 
    129 public:
    130     static void RandRect(SkRect* r, SkRandom& rand) {
    131         r->set(rand.nextSScalar1(), rand.nextSScalar1(),
    132                rand.nextSScalar1(), rand.nextSScalar1());
    133         r->sort();
    134     }
    135 
    136     RectSectBench(bool newWay) : fNewWay(newWay) {
    137         fName.printf("rect_intersect_%s", newWay ? "new" : "old");
    138 
    139         SkRandom rand;
    140         for (int i = 0; i < N; i++) {
    141             RandRect(&fArray0[i], rand);
    142             RandRect(&fArray1[i], rand);
    143         }
    144     }
    145 
    146     virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
    147         return backend == kNonRendering_Backend;
    148     }
    149 
    150 protected:
    151     virtual const char* onGetName() { return fName.c_str(); }
    152 
    153     virtual void onDraw(const int loops, SkCanvas* canvas) {
    154         for (int i = 0; i < loops; ++i) {
    155             if (fNewWay) {
    156                 for (int j = 0; j < N; ++j) {
    157                     SkRect r = fArray0[j];
    158                     r.intersect2(fArray1[j]);
    159                 }
    160             } else {
    161                 for (int j = 0; j < N; ++j) {
    162                     SkRect r = fArray0[j];
    163                     r.intersect(fArray1[j]);
    164                 }
    165             }
    166         }
    167     }
    168 
    169 private:
    170     typedef Benchmark INHERITED;
    171 };
    172 
    173 ///////////////////////////////////////////////////////////////////////////////
    174 
    175 #define SMALL   16
    176 
    177 DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, union_proc, "union")); )
    178 DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, sect_proc, "intersect")); )
    179 DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, diff_proc, "difference")); )
    180 DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, diffrect_proc, "differencerect")); )
    181 DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, diffrectbig_proc, "differencerectbig")); )
    182 DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, containsrect_proc, "containsrect")); )
    183 DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, sectsrgn_proc, "intersectsrgn")); )
    184 DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, sectsrect_proc, "intersectsrect")); )
    185 DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, containsxy_proc, "containsxy")); )
    186 
    187 DEF_BENCH( return SkNEW_ARGS(RectSectBench, (false)); )
    188 DEF_BENCH( return SkNEW_ARGS(RectSectBench, (true)); )
    189