diff options
author | mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-01-01 20:32:45 +0000 |
---|---|---|
committer | mike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-01-01 20:32:45 +0000 |
commit | ae8f9528fd0052e06653272abb44a1f49a3b726b (patch) | |
tree | 6ec6ff2239699ce32d69046ae5330fc8e5f2fa71 | |
parent | 725a64cf89605680ebb0f56cd6727f29d8b9899b (diff) |
speedup SkRect::intersect
git-svn-id: http://skia.googlecode.com/svn/trunk@12851 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | bench/RegionBench.cpp | 58 | ||||
-rw-r--r-- | include/core/SkRect.h | 1 | ||||
-rw-r--r-- | src/core/SkRect.cpp | 16 |
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); |