speedup SkRect::intersect
authormike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 1 Jan 2014 20:32:45 +0000 (20:32 +0000)
committermike@reedtribe.org <mike@reedtribe.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 1 Jan 2014 20:32:45 +0000 (20:32 +0000)
git-svn-id: http://skia.googlecode.com/svn/trunk@12851 2bbb7eff-a529-9590-31e7-b0007b416f81

bench/RegionBench.cpp
include/core/SkRect.h
src/core/SkRect.cpp

index ed58e3b..4ab173a 100644 (file)
@@ -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)); )
index 0a5439c..397e4a0 100644 (file)
@@ -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
index bb51ede..3cff5d8 100644 (file)
@@ -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);