1 /* 2 * Copyright 2011 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 #include "Benchmark.h" 8 #include "SkRandom.h" 9 #include "SkRegion.h" 10 #include "SkString.h" 11 12 static bool union_proc(SkRegion& a, SkRegion& b) { 13 SkRegion result; 14 return result.op(a, b, SkRegion::kUnion_Op); 15 } 16 17 static bool sect_proc(SkRegion& a, SkRegion& b) { 18 SkRegion result; 19 return result.op(a, b, SkRegion::kIntersect_Op); 20 } 21 22 static bool diff_proc(SkRegion& a, SkRegion& b) { 23 SkRegion result; 24 return result.op(a, b, SkRegion::kDifference_Op); 25 } 26 27 static bool diffrect_proc(SkRegion& a, SkRegion& b) { 28 SkRegion result; 29 return result.op(a, b.getBounds(), SkRegion::kDifference_Op); 30 } 31 32 static bool diffrectbig_proc(SkRegion& a, SkRegion& b) { 33 SkRegion result; 34 return result.op(a, a.getBounds(), SkRegion::kDifference_Op); 35 } 36 37 static bool containsrect_proc(SkRegion& a, SkRegion& b) { 38 SkIRect r = a.getBounds(); 39 r.inset(r.width()/4, r.height()/4); 40 (void)a.contains(r); 41 42 r = b.getBounds(); 43 r.inset(r.width()/4, r.height()/4); 44 return b.contains(r); 45 } 46 47 static bool sectsrgn_proc(SkRegion& a, SkRegion& b) { 48 return a.intersects(b); 49 } 50 51 static bool sectsrect_proc(SkRegion& a, SkRegion& b) { 52 SkIRect r = a.getBounds(); 53 r.inset(r.width()/4, r.height()/4); 54 return a.intersects(r); 55 } 56 57 static bool containsxy_proc(SkRegion& a, SkRegion& b) { 58 const SkIRect& r = a.getBounds(); 59 const int dx = r.width() / 8; 60 const int dy = r.height() / 8; 61 for (int y = r.fTop; y < r.fBottom; y += dy) { 62 for (int x = r.fLeft; x < r.fRight; x += dx) { 63 (void)a.contains(x, y); 64 } 65 } 66 return true; 67 } 68 69 class RegionBench : public Benchmark { 70 public: 71 typedef bool (*Proc)(SkRegion& a, SkRegion& b); 72 73 SkRegion fA, fB; 74 Proc fProc; 75 SkString fName; 76 77 enum { 78 W = 1024, 79 H = 768, 80 }; 81 82 SkIRect randrect(SkRandom& rand) { 83 int x = rand.nextU() % W; 84 int y = rand.nextU() % H; 85 int w = rand.nextU() % W; 86 int h = rand.nextU() % H; 87 return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1); 88 } 89 90 RegionBench(int count, Proc proc, const char name[]) { 91 fProc = proc; 92 fName.printf("region_%s_%d", name, count); 93 94 SkRandom rand; 95 for (int i = 0; i < count; i++) { 96 fA.op(randrect(rand), SkRegion::kXOR_Op); 97 fB.op(randrect(rand), SkRegion::kXOR_Op); 98 } 99 } 100 101 bool isSuitableFor(Backend backend) override { 102 return backend == kNonRendering_Backend; 103 } 104 105 protected: 106 const char* onGetName() override { return fName.c_str(); } 107 108 void onDraw(int loops, SkCanvas* canvas) override { 109 Proc proc = fProc; 110 for (int i = 0; i < loops; ++i) { 111 proc(fA, fB); 112 } 113 } 114 115 private: 116 typedef Benchmark INHERITED; 117 }; 118 119 /////////////////////////////////////////////////////////////////////////////// 120 121 #define SMALL 16 122 123 DEF_BENCH(return new RegionBench(SMALL, union_proc, "union");) 124 DEF_BENCH(return new RegionBench(SMALL, sect_proc, "intersect");) 125 DEF_BENCH(return new RegionBench(SMALL, diff_proc, "difference");) 126 DEF_BENCH(return new RegionBench(SMALL, diffrect_proc, "differencerect");) 127 DEF_BENCH(return new RegionBench(SMALL, diffrectbig_proc, "differencerectbig");) 128 DEF_BENCH(return new RegionBench(SMALL, containsrect_proc, "containsrect");) 129 DEF_BENCH(return new RegionBench(SMALL, sectsrgn_proc, "intersectsrgn");) 130 DEF_BENCH(return new RegionBench(SMALL, sectsrect_proc, "intersectsrect");) 131 DEF_BENCH(return new RegionBench(SMALL, containsxy_proc, "containsxy");) 132