We often rgn-diff an area >= the other rgn. now we detect that and return empty
We do this when we update our devices in SkCanvas.cpp Review URL: https://codereview.appspot.com/6249073 git-svn-id: http://skia.googlecode.com/svn/trunk@4101 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
6f6efa90c4
commit
0d10280190
@ -25,6 +25,16 @@ static bool diff_proc(SkRegion& a, SkRegion& b) {
|
||||
return result.op(a, b, SkRegion::kDifference_Op);
|
||||
}
|
||||
|
||||
static bool diffrect_proc(SkRegion& a, SkRegion& b) {
|
||||
SkRegion result;
|
||||
return result.op(a, b.getBounds(), SkRegion::kDifference_Op);
|
||||
}
|
||||
|
||||
static bool diffrectbig_proc(SkRegion& a, SkRegion& b) {
|
||||
SkRegion result;
|
||||
return result.op(a, a.getBounds(), SkRegion::kDifference_Op);
|
||||
}
|
||||
|
||||
static bool containsrect_proc(SkRegion& a, SkRegion& b) {
|
||||
SkIRect r = a.getBounds();
|
||||
r.inset(r.width()/4, r.height()/4);
|
||||
@ -112,10 +122,12 @@ private:
|
||||
static SkBenchmark* gF0(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, union_proc, "union")); }
|
||||
static SkBenchmark* gF1(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, sect_proc, "intersect")); }
|
||||
static SkBenchmark* gF2(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, diff_proc, "difference")); }
|
||||
static SkBenchmark* gF3(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, containsrect_proc, "containsrect", 100)); }
|
||||
static SkBenchmark* gF4(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, sectsrgn_proc, "intersectsrgn", 10)); }
|
||||
static SkBenchmark* gF5(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, sectsrect_proc, "intersectsrect", 200)); }
|
||||
static SkBenchmark* gF6(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, containsxy_proc, "containsxy")); }
|
||||
static SkBenchmark* gF3(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, diffrect_proc, "differencerect")); }
|
||||
static SkBenchmark* gF4(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, diffrectbig_proc, "differencerectbig")); }
|
||||
static SkBenchmark* gF5(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, containsrect_proc, "containsrect", 100)); }
|
||||
static SkBenchmark* gF6(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, sectsrgn_proc, "intersectsrgn", 10)); }
|
||||
static SkBenchmark* gF7(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, sectsrect_proc, "intersectsrect", 200)); }
|
||||
static SkBenchmark* gF8(void* p) { return SkNEW_ARGS(RegionBench, (p, SMALL, containsxy_proc, "containsxy")); }
|
||||
|
||||
static BenchRegistry gR0(gF0);
|
||||
static BenchRegistry gR1(gF1);
|
||||
@ -124,3 +136,5 @@ static BenchRegistry gR3(gF3);
|
||||
static BenchRegistry gR4(gF4);
|
||||
static BenchRegistry gR5(gF5);
|
||||
static BenchRegistry gR6(gF6);
|
||||
static BenchRegistry gR7(gF7);
|
||||
static BenchRegistry gR8(gF8);
|
||||
|
@ -206,6 +206,10 @@ struct SK_API SkIRect {
|
||||
fRight >= right && fBottom >= bottom;
|
||||
}
|
||||
|
||||
bool containsNoEmptyCheck(const SkIRect& r) const {
|
||||
return containsNoEmptyCheck(r.fLeft, r.fTop, r.fRight, r.fBottom);
|
||||
}
|
||||
|
||||
/** If r intersects this rectangle, return true and set this rectangle to that
|
||||
intersection, otherwise return false and do not change this rectangle.
|
||||
If either rectangle is empty, do nothing and return false.
|
||||
@ -273,10 +277,20 @@ struct SK_API SkIRect {
|
||||
}
|
||||
|
||||
/** Returns true if a and b are not empty, and they intersect
|
||||
*/
|
||||
*/
|
||||
static bool Intersects(const SkIRect& a, const SkIRect& b) {
|
||||
return !a.isEmpty() && !b.isEmpty() && // check for empties
|
||||
a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a and b intersect. debug-asserts that neither are empty.
|
||||
*/
|
||||
static bool IntersectsNoEmptyCheck(const SkIRect& a, const SkIRect& b) {
|
||||
SkASSERT(!a.isEmpty());
|
||||
SkASSERT(!b.isEmpty());
|
||||
return a.fLeft < b.fRight && b.fLeft < a.fRight &&
|
||||
a.fTop < b.fBottom && b.fTop < a.fBottom;
|
||||
}
|
||||
|
||||
|
@ -992,9 +992,13 @@ bool SkRegion::Oper(const SkRegion& rgnaOrig, const SkRegion& rgnbOrig, Op op,
|
||||
if (a_empty) {
|
||||
return setEmptyCheck(result);
|
||||
}
|
||||
if (b_empty || !SkIRect::Intersects(rgna->fBounds, rgnb->fBounds)) {
|
||||
if (b_empty || !SkIRect::IntersectsNoEmptyCheck(rgna->fBounds,
|
||||
rgnb->fBounds)) {
|
||||
return setRegionCheck(result, *rgna);
|
||||
}
|
||||
if (b_rect && rgnb->fBounds.containsNoEmptyCheck(rgna->fBounds)) {
|
||||
return setEmptyCheck(result);
|
||||
}
|
||||
break;
|
||||
|
||||
case kIntersect_Op:
|
||||
|
Loading…
Reference in New Issue
Block a user