OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "Test.h" | 8 #include "Test.h" |
9 #if SK_SUPPORT_GPU | 9 #if SK_SUPPORT_GPU |
10 #include "GrReducedClip.h" | 10 #include "GrReducedClip.h" |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 | 787 |
788 { | 788 { |
789 SkClipStack stack; | 789 SkClipStack stack; |
790 SkPath path = nonIntersectingCircle; | 790 SkPath path = nonIntersectingCircle; |
791 path.toggleInverseFillType(); | 791 path.toggleInverseFillType(); |
792 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); | 792 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); |
793 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); | 793 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); |
794 } | 794 } |
795 } | 795 } |
796 | 796 |
| 797 static void set_region_to_stack(const SkClipStack& stack, const SkIRect& bounds,
SkRegion* region) { |
| 798 region->setRect(bounds); |
| 799 SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); |
| 800 while (const SkClipStack::Element *element = iter.next()) { |
| 801 SkRegion elemRegion; |
| 802 SkRegion boundsRgn(bounds); |
| 803 SkPath path; |
| 804 |
| 805 switch (element->getType()) { |
| 806 case SkClipStack::Element::kEmpty_Type: |
| 807 elemRegion.setEmpty(); |
| 808 break; |
| 809 default: |
| 810 element->asPath(&path); |
| 811 elemRegion.setPath(path, boundsRgn); |
| 812 break; |
| 813 } |
| 814 region->op(elemRegion, element->getOp()); |
| 815 } |
| 816 } |
| 817 |
| 818 static void test_invfill_diff_bug(skiatest::Reporter* reporter) { |
| 819 SkClipStack stack; |
| 820 stack.clipDevRect({10, 10, 20, 20}, SkRegion::kIntersect_Op, false); |
| 821 |
| 822 SkPath path; |
| 823 path.addRect({30, 10, 40, 20}); |
| 824 path.setFillType(SkPath::kInverseWinding_FillType); |
| 825 stack.clipDevPath(path, SkRegion::kDifference_Op, false); |
| 826 |
| 827 REPORTER_ASSERT(reporter, SkClipStack::kEmptyGenID == stack.getTopmostGenID(
)); |
| 828 |
| 829 SkRect stackBounds; |
| 830 SkClipStack::BoundsType stackBoundsType; |
| 831 stack.getBounds(&stackBounds, &stackBoundsType); |
| 832 |
| 833 REPORTER_ASSERT(reporter, stackBounds.isEmpty()); |
| 834 REPORTER_ASSERT(reporter, SkClipStack::kNormal_BoundsType == stackBoundsType
); |
| 835 |
| 836 SkRegion region; |
| 837 set_region_to_stack(stack, {0, 0, 50, 30}, ®ion); |
| 838 |
| 839 REPORTER_ASSERT(reporter, region.isEmpty()); |
| 840 } |
| 841 |
797 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 842 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
798 | 843 |
799 #if SK_SUPPORT_GPU | 844 #if SK_SUPPORT_GPU |
800 // Functions that add a shape to the clip stack. The shape is computed from a re
ctangle. | 845 // Functions that add a shape to the clip stack. The shape is computed from a re
ctangle. |
801 // AA is always disabled since the clip stack reducer can cause changes in aa ra
sterization of the | 846 // AA is always disabled since the clip stack reducer can cause changes in aa ra
sterization of the |
802 // stack. A fractional edge repeated in different elements may be rasterized few
er times using the | 847 // stack. A fractional edge repeated in different elements may be rasterized few
er times using the |
803 // reduced stack. | 848 // reduced stack. |
804 typedef void (*AddElementFunc) (const SkRect& rect, | 849 typedef void (*AddElementFunc) (const SkRect& rect, |
805 bool invert, | 850 bool invert, |
806 SkRegion::Op op, | 851 SkRegion::Op op, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 case SkClipStack::Element::kPath_Type: | 897 case SkClipStack::Element::kPath_Type: |
853 stack->clipDevPath(element.getPath(), element.getOp(), element.isAA(
)); | 898 stack->clipDevPath(element.getPath(), element.getOp(), element.isAA(
)); |
854 break; | 899 break; |
855 case SkClipStack::Element::kEmpty_Type: | 900 case SkClipStack::Element::kEmpty_Type: |
856 SkDEBUGFAIL("Why did the reducer produce an explicit empty."); | 901 SkDEBUGFAIL("Why did the reducer produce an explicit empty."); |
857 stack->clipEmpty(); | 902 stack->clipEmpty(); |
858 break; | 903 break; |
859 } | 904 } |
860 } | 905 } |
861 | 906 |
862 static void add_elem_to_region(const SkClipStack::Element& element, | |
863 const SkIRect& bounds, | |
864 SkRegion* region) { | |
865 SkRegion elemRegion; | |
866 SkRegion boundsRgn(bounds); | |
867 SkPath path; | |
868 | |
869 switch (element.getType()) { | |
870 case SkClipStack::Element::kEmpty_Type: | |
871 elemRegion.setEmpty(); | |
872 break; | |
873 default: | |
874 element.asPath(&path); | |
875 elemRegion.setPath(path, boundsRgn); | |
876 break; | |
877 } | |
878 region->op(elemRegion, element.getOp()); | |
879 } | |
880 | |
881 static void test_reduced_clip_stack(skiatest::Reporter* reporter) { | 907 static void test_reduced_clip_stack(skiatest::Reporter* reporter) { |
882 // We construct random clip stacks, reduce them, and then rasterize both ver
sions to verify that | 908 // We construct random clip stacks, reduce them, and then rasterize both ver
sions to verify that |
883 // they are equal. | 909 // they are equal. |
884 | 910 |
885 // All the clip elements will be contained within these bounds. | 911 // All the clip elements will be contained within these bounds. |
886 static const SkRect kBounds = SkRect::MakeWH(100, 100); | 912 static const SkRect kBounds = SkRect::MakeWH(100, 100); |
887 | 913 |
888 enum { | 914 enum { |
889 kNumTests = 200, | 915 kNumTests = 200, |
890 kMinElemsPerTest = 1, | 916 kMinElemsPerTest = 1, |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 for (ElementList::Iter iter = reducedClips.headIter(); iter.get(); iter.
next()) { | 1010 for (ElementList::Iter iter = reducedClips.headIter(); iter.get(); iter.
next()) { |
985 add_elem_to_stack(*iter.get(), &reducedStack); | 1011 add_elem_to_stack(*iter.get(), &reducedStack); |
986 } | 1012 } |
987 | 1013 |
988 // GrReducedClipStack assumes that the final result is clipped to the re
turned bounds | 1014 // GrReducedClipStack assumes that the final result is clipped to the re
turned bounds |
989 reducedStack.clipDevRect(tighterBounds, SkRegion::kIntersect_Op); | 1015 reducedStack.clipDevRect(tighterBounds, SkRegion::kIntersect_Op); |
990 stack.clipDevRect(tighterBounds, SkRegion::kIntersect_Op); | 1016 stack.clipDevRect(tighterBounds, SkRegion::kIntersect_Op); |
991 | 1017 |
992 // convert both the original stack and reduced stack to SkRegions and se
e if they're equal | 1018 // convert both the original stack and reduced stack to SkRegions and se
e if they're equal |
993 SkRegion region; | 1019 SkRegion region; |
| 1020 set_region_to_stack(stack, inflatedIBounds, ®ion); |
| 1021 |
994 SkRegion reducedRegion; | 1022 SkRegion reducedRegion; |
| 1023 set_region_to_stack(reducedStack, inflatedIBounds, &reducedRegion); |
995 | 1024 |
996 region.setRect(inflatedIBounds); | |
997 const SkClipStack::Element* element; | |
998 SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); | |
999 while ((element = iter.next())) { | |
1000 add_elem_to_region(*element, inflatedIBounds, ®ion); | |
1001 } | |
1002 | |
1003 reducedRegion.setRect(inflatedIBounds); | |
1004 iter.reset(reducedStack, SkClipStack::Iter::kBottom_IterStart); | |
1005 while ((element = iter.next())) { | |
1006 add_elem_to_region(*element, inflatedIBounds, &reducedRegion); | |
1007 } | |
1008 SkString testCase; | 1025 SkString testCase; |
1009 testCase.printf("Iteration %d", i); | 1026 testCase.printf("Iteration %d", i); |
1010 REPORTER_ASSERT_MESSAGE(reporter, region == reducedRegion, testCase.c_st
r()); | 1027 REPORTER_ASSERT_MESSAGE(reporter, region == reducedRegion, testCase.c_st
r()); |
1011 } | 1028 } |
1012 } | 1029 } |
1013 | 1030 |
1014 #ifdef SK_BUILD_FOR_WIN | 1031 #ifdef SK_BUILD_FOR_WIN |
1015 #define SUPPRESS_VISIBILITY_WARNING | 1032 #define SUPPRESS_VISIBILITY_WARNING |
1016 #else | 1033 #else |
1017 #define SUPPRESS_VISIBILITY_WARNING __attribute__((visibility("hidden"))) | 1034 #define SUPPRESS_VISIBILITY_WARNING __attribute__((visibility("hidden"))) |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1197 test_iterators(reporter); | 1214 test_iterators(reporter); |
1198 test_bounds(reporter, SkClipStack::Element::kRect_Type); | 1215 test_bounds(reporter, SkClipStack::Element::kRect_Type); |
1199 test_bounds(reporter, SkClipStack::Element::kRRect_Type); | 1216 test_bounds(reporter, SkClipStack::Element::kRRect_Type); |
1200 test_bounds(reporter, SkClipStack::Element::kPath_Type); | 1217 test_bounds(reporter, SkClipStack::Element::kPath_Type); |
1201 test_isWideOpen(reporter); | 1218 test_isWideOpen(reporter); |
1202 test_rect_merging(reporter); | 1219 test_rect_merging(reporter); |
1203 test_rect_replace(reporter); | 1220 test_rect_replace(reporter); |
1204 test_rect_inverse_fill(reporter); | 1221 test_rect_inverse_fill(reporter); |
1205 test_path_replace(reporter); | 1222 test_path_replace(reporter); |
1206 test_quickContains(reporter); | 1223 test_quickContains(reporter); |
| 1224 test_invfill_diff_bug(reporter); |
1207 #if SK_SUPPORT_GPU | 1225 #if SK_SUPPORT_GPU |
1208 test_reduced_clip_stack(reporter); | 1226 test_reduced_clip_stack(reporter); |
1209 test_reduced_clip_stack_genid(reporter); | 1227 test_reduced_clip_stack_genid(reporter); |
1210 test_reduced_clip_stack_no_aa_crash(reporter); | 1228 test_reduced_clip_stack_no_aa_crash(reporter); |
1211 #endif | 1229 #endif |
1212 } | 1230 } |
OLD | NEW |