From ae8f9528fd0052e06653272abb44a1f49a3b726b Mon Sep 17 00:00:00 2001 From: "mike@reedtribe.org" Date: Wed, 1 Jan 2014 20:32:45 +0000 Subject: [PATCH] speedup SkRect::intersect git-svn-id: http://skia.googlecode.com/svn/trunk@12851 2bbb7eff-a529-9590-31e7-b0007b416f81 --- bench/RegionBench.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/core/SkRect.h | 1 + src/core/SkRect.cpp | 16 ++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/bench/RegionBench.cpp b/bench/RegionBench.cpp index ed58e3b..4ab173a 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 0a5439c..397e4a0 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 bb51ede..3cff5d8 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); -- 2.7.4