aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/ClipStackTest.cpp
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-07 21:19:10 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-07 21:19:10 +0000
commite8ca6c6e3a55634ac76efe5aceafaf8d669f43ba (patch)
tree5117b031a0d5bb1fc1cd6eb1b6c4de401abca782 /tests/ClipStackTest.cpp
parent4f6fba366387c9a19fb982479cdf6ac9e0355118 (diff)
Combine multiple intersecting rects in SkClipStack::Iter.
R=robertphillips@google.com Review URL: https://codereview.appspot.com/6816104 git-svn-id: http://skia.googlecode.com/svn/trunk@6339 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tests/ClipStackTest.cpp')
-rw-r--r--tests/ClipStackTest.cpp168
1 files changed, 168 insertions, 0 deletions
diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp
index 8a74dc8712..0516d9eba7 100644
--- a/tests/ClipStackTest.cpp
+++ b/tests/ClipStackTest.cpp
@@ -473,6 +473,173 @@ static void test_rect_merging(skiatest::Reporter* reporter) {
}
}
+
+// This is similar to the above test but tests the iterator's ability to merge rects in the
+// middle of a clip stack's sequence using nextCombined(). There is a save after every clip
+// element to prevent the clip stack from merging the rectangles as they are added.
+static void test_iter_rect_merging(skiatest::Reporter* reporter) {
+
+ SkRect overlapLeft = SkRect::MakeLTRB(10, 10, 50, 50);
+ SkRect overlapRight = SkRect::MakeLTRB(40, 40, 80, 80);
+
+ SkRect nestedParent = SkRect::MakeLTRB(10, 10, 90, 90);
+ SkRect nestedChild = SkRect::MakeLTRB(40, 40, 60, 60);
+
+ SkRect farAway = SkRect::MakeLTRB(1000, 1000, 1010, 1010);
+
+ SkRect overlapIntersect;
+ overlapIntersect.intersect(overlapLeft, overlapRight);
+
+ SkPath path1, path2;
+ path1.addCircle(SkIntToScalar(30), SkIntToScalar(30), SkIntToScalar(1000));
+ path2.addOval(SkRect::MakeWH(500, 600));
+
+ const SkClipStack::Iter::Clip* clip;
+
+ // call nextCombined with an empty clip stack
+ {
+ SkClipStack stack;
+ SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
+ REPORTER_ASSERT(reporter, NULL == iter.nextCombined());
+ }
+
+ // two bw overlapping - should merge, bracketed by paths
+ {
+ SkClipStack stack;
+ stack.clipDevPath(path1, SkRegion::kIntersect_Op, false); stack.save();
+
+ stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, false); stack.save();
+
+ stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); stack.save();
+
+ stack.clipDevPath(path2, SkRegion::kIntersect_Op, false); stack.save();
+
+ SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, *clip->fPath == path1 && !clip->fDoAA);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, !clip->fDoAA && *clip->fRect == overlapIntersect);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, *clip->fPath == path2 && !clip->fDoAA);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, NULL == clip);
+ }
+
+ // same as above but rects are aa and no final path.
+ {
+ SkClipStack stack;
+ stack.clipDevPath(path1, SkRegion::kIntersect_Op, false); stack.save();
+
+ stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, true); stack.save();
+
+ stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); stack.save();
+
+ SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, *clip->fPath == path1 && !clip->fDoAA);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == overlapIntersect);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, NULL == clip);
+ }
+
+ // mixed overlapping - no paths - should _not_ merge
+ {
+ SkClipStack stack;
+
+ stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, true); stack.save();
+ stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); stack.save();
+
+ SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == overlapLeft);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, !clip->fDoAA && *clip->fRect == overlapRight);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, NULL == clip);
+ }
+
+ // three rects in a row where the third rect uses a non-intersect op.
+ {
+ SkClipStack stack;
+
+ stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, true); stack.save();
+ stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); stack.save();
+ stack.clipDevRect(nestedParent, SkRegion::kXOR_Op, true); stack.save();
+
+ SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == overlapIntersect);
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == nestedParent);
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, NULL == clip);
+ }
+
+ // mixed nested (bw inside aa) - should merge
+ {
+ SkClipStack stack;
+ stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, false); stack.save();
+
+ stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, true); stack.save();
+
+ SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, clip->fDoAA && *clip->fRect == nestedChild);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, NULL == clip);
+ }
+
+ // mixed nested (aa inside bw) - should merge
+ {
+ SkClipStack stack;
+ stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, false); stack.save();
+
+ stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, true); stack.save();
+
+ SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, !clip->fDoAA && *clip->fRect == nestedChild);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, NULL == clip);
+ }
+
+ // three rect intersects in a row where result is empty after the second.
+ {
+ SkClipStack stack;
+
+ stack.clipDevRect(overlapLeft, SkRegion::kIntersect_Op, false); stack.save();
+ stack.clipDevRect(farAway, SkRegion::kIntersect_Op, false); stack.save();
+ stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); stack.save();
+
+ SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, clip->fRect->isEmpty());
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, *clip->fRect == overlapRight);
+
+ clip = iter.nextCombined();
+ REPORTER_ASSERT(reporter, NULL == clip);
+ }
+}
+
static void TestClipStack(skiatest::Reporter* reporter) {
SkClipStack stack;
@@ -513,6 +680,7 @@ static void TestClipStack(skiatest::Reporter* reporter) {
test_bounds(reporter, false); // once with paths
test_isWideOpen(reporter);
test_rect_merging(reporter);
+ test_iter_rect_merging(reporter);
}
#include "TestClassDef.h"