aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-01 20:32:45 +0000
committerGravatar mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-01-01 20:32:45 +0000
commitae8f9528fd0052e06653272abb44a1f49a3b726b (patch)
tree6ec6ff2239699ce32d69046ae5330fc8e5f2fa71
parent725a64cf89605680ebb0f56cd6727f29d8b9899b (diff)
speedup SkRect::intersect
git-svn-id: http://skia.googlecode.com/svn/trunk@12851 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--bench/RegionBench.cpp58
-rw-r--r--include/core/SkRect.h1
-rw-r--r--src/core/SkRect.cpp16
3 files changed, 75 insertions, 0 deletions
diff --git a/bench/RegionBench.cpp b/bench/RegionBench.cpp
index ed58e3bdeb..4ab173a53b 100644
--- a/bench/RegionBench.cpp
+++ b/bench/RegionBench.cpp
@@ -117,6 +117,61 @@ private:
typedef SkBenchmark INHERITED;
};
+class RectSectBench : public SkBenchmark {
+ enum {
+ N = 1000
+ };
+ SkRect fArray0[N];
+ SkRect fArray1[N];
+ SkString fName;
+ bool fNewWay;
+
+public:
+ static void RandRect(SkRect* r, SkRandom& rand) {
+ r->set(rand.nextSScalar1(), rand.nextSScalar1(),
+ rand.nextSScalar1(), rand.nextSScalar1());
+ r->sort();
+ }
+
+ RectSectBench(bool newWay) : fNewWay(newWay) {
+ fName.printf("rect_intersect_%s", newWay ? "new" : "old");
+
+ SkRandom rand;
+ for (int i = 0; i < N; i++) {
+ RandRect(&fArray0[i], rand);
+ RandRect(&fArray1[i], rand);
+ }
+ }
+
+ virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
+ return backend == kNonRendering_Backend;
+ }
+
+protected:
+ virtual const char* onGetName() { return fName.c_str(); }
+
+ virtual void onDraw(const int loops, SkCanvas* canvas) {
+ for (int i = 0; i < loops; ++i) {
+ if (fNewWay) {
+ for (int j = 0; j < N; ++j) {
+ SkRect r = fArray0[j];
+ r.intersect2(fArray1[j]);
+ }
+ } else {
+ for (int j = 0; j < N; ++j) {
+ SkRect r = fArray0[j];
+ r.intersect(fArray1[j]);
+ }
+ }
+ }
+ }
+
+private:
+ typedef SkBenchmark INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
#define SMALL 16
DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, union_proc, "union")); )
@@ -128,3 +183,6 @@ DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, containsrect_proc, "containsre
DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, sectsrgn_proc, "intersectsrgn")); )
DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, sectsrect_proc, "intersectsrect")); )
DEF_BENCH( return SkNEW_ARGS(RegionBench, (SMALL, containsxy_proc, "containsxy")); )
+
+DEF_BENCH( return SkNEW_ARGS(RectSectBench, (false)); )
+DEF_BENCH( return SkNEW_ARGS(RectSectBench, (true)); )
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index 0a5439cdfc..397e4a03ee 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -625,6 +625,7 @@ struct SK_API SkRect {
If either rectangle is empty, do nothing and return false.
*/
bool intersect(const SkRect& r);
+ bool intersect2(const SkRect& r);
/** If this rectangle intersects the rectangle specified by left, top, right, bottom,
return true and set this rectangle to that intersection, otherwise return false
diff --git a/src/core/SkRect.cpp b/src/core/SkRect.cpp
index bb51ede757..3cff5d81e5 100644
--- a/src/core/SkRect.cpp
+++ b/src/core/SkRect.cpp
@@ -118,6 +118,22 @@ bool SkRect::intersect(const SkRect& r) {
return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom);
}
+bool SkRect::intersect2(const SkRect& r) {
+ SkASSERT(&r);
+ SkScalar L = SkMaxScalar(fLeft, r.fLeft);
+ SkScalar R = SkMinScalar(fRight, r.fRight);
+ if (L >= R) {
+ return false;
+ }
+ SkScalar T = SkMaxScalar(fTop, r.fTop);
+ SkScalar B = SkMinScalar(fBottom, r.fBottom);
+ if (T >= B) {
+ return false;
+ }
+ this->set(L, T, R, B);
+ return true;
+}
+
bool SkRect::intersect(const SkRect& a, const SkRect& b) {
SkASSERT(&a && &b);