speedup SkRect::intersect

git-svn-id: http://skia.googlecode.com/svn/trunk@12851 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
mike@reedtribe.org 2014-01-01 20:32:45 +00:00
parent 725a64cf89
commit ae8f9528fd
3 changed files with 75 additions and 0 deletions

View 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)); )

View 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

View 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);