Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: tests/ClipStackTest.cpp

Issue 2175493002: Fix SkClipStack bug with inverse-filled difference elements (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkClipStack.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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}, &region);
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
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
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, &region);
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, &region);
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
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 }
OLDNEW
« no previous file with comments | « src/core/SkClipStack.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698