OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 <initializer_list> | 8 #include <initializer_list> |
9 #include <functional> | 9 #include <functional> |
10 #include "Test.h" | 10 #include "Test.h" |
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 | 1071 |
1072 void test_unknown_path_effect(skiatest::Reporter* reporter, const Geo& geo) { | 1072 void test_unknown_path_effect(skiatest::Reporter* reporter, const Geo& geo) { |
1073 /** | 1073 /** |
1074 * This path effect just adds two lineTos to the input path. | 1074 * This path effect just adds two lineTos to the input path. |
1075 */ | 1075 */ |
1076 class AddLineTosPathEffect : SkPathEffect { | 1076 class AddLineTosPathEffect : SkPathEffect { |
1077 public: | 1077 public: |
1078 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, | 1078 bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, |
1079 const SkRect* cullR) const override { | 1079 const SkRect* cullR) const override { |
1080 *dst = src; | 1080 *dst = src; |
1081 dst->lineTo(0, 0); | 1081 // To avoid triggering data-based keying of paths with few verbs we
add many segments. |
1082 dst->lineTo(10, 10); | 1082 for (int i = 0; i < 100; ++i) { |
| 1083 dst->lineTo(SkIntToScalar(i), SkIntToScalar(i)); |
| 1084 } |
1083 return true; | 1085 return true; |
1084 } | 1086 } |
1085 void computeFastBounds(SkRect* dst, const SkRect& src) const override { | 1087 void computeFastBounds(SkRect* dst, const SkRect& src) const override { |
1086 *dst = src; | 1088 *dst = src; |
1087 dst->growToInclude(0, 0); | 1089 dst->growToInclude(0, 0); |
1088 dst->growToInclude(10, 10); | 1090 dst->growToInclude(100, 100); |
1089 } | 1091 } |
1090 static sk_sp<SkPathEffect> Make() { return sk_sp<SkPathEffect>(new AddLi
neTosPathEffect); } | 1092 static sk_sp<SkPathEffect> Make() { return sk_sp<SkPathEffect>(new AddLi
neTosPathEffect); } |
1091 Factory getFactory() const override { return nullptr; } | 1093 Factory getFactory() const override { return nullptr; } |
1092 void toString(SkString*) const override {} | 1094 void toString(SkString*) const override {} |
1093 private: | 1095 private: |
1094 AddLineTosPathEffect() {} | 1096 AddLineTosPathEffect() {} |
1095 }; | 1097 }; |
1096 | 1098 |
1097 // This path effect should make the keys invalid when it is applied. We onl
y produce a path | 1099 // This path effect should make the keys invalid when it is applied. We onl
y produce a path |
1098 // effect key for dash path effects. So the only way another arbitrary path
effect can produce | 1100 // effect key for dash path effects. So the only way another arbitrary path
effect can produce |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 REPORTER_ASSERT(reporter, paths_fill_same(a, b)); | 1151 REPORTER_ASSERT(reporter, paths_fill_same(a, b)); |
1150 REPORTER_ASSERT(reporter, paths_fill_same(a, c)); | 1152 REPORTER_ASSERT(reporter, paths_fill_same(a, c)); |
1151 } else { | 1153 } else { |
1152 // The base shape cannot perform canonicalization on the path's fill typ
e because of an | 1154 // The base shape cannot perform canonicalization on the path's fill typ
e because of an |
1153 // unknown path effect. However, after the path effect is applied the re
sulting hairline | 1155 // unknown path effect. However, after the path effect is applied the re
sulting hairline |
1154 // shape will canonicalize the path fill type since hairlines (and strok
ing in general) | 1156 // shape will canonicalize the path fill type since hairlines (and strok
ing in general) |
1155 // don't distinguish between even/odd and non-zero winding. | 1157 // don't distinguish between even/odd and non-zero winding. |
1156 a.setFillType(b.getFillType()); | 1158 a.setFillType(b.getFillType()); |
1157 REPORTER_ASSERT(reporter, a == b); | 1159 REPORTER_ASSERT(reporter, a == b); |
1158 REPORTER_ASSERT(reporter, a == c); | 1160 REPORTER_ASSERT(reporter, a == c); |
1159 REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey().empty()); | 1161 // If the resulting path is small enough then it will have a key. |
1160 REPORTER_ASSERT(reporter, peCase.appliedFullStyleKey().empty()); | 1162 REPORTER_ASSERT(reporter, paths_fill_same(a, b)); |
| 1163 REPORTER_ASSERT(reporter, paths_fill_same(a, c)); |
| 1164 if (c.countVerbs() <= GrShape::kMaxKeyFromDataVerbCnt) { |
| 1165 REPORTER_ASSERT(reporter, !peCase.appliedPathEffectKey().empty()); |
| 1166 REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey() == |
| 1167 peCase.appliedFullStyleKey()); |
| 1168 } else { |
| 1169 REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey().empty()); |
| 1170 REPORTER_ASSERT(reporter, peCase.appliedFullStyleKey().empty()); |
| 1171 } |
1161 } | 1172 } |
1162 REPORTER_ASSERT(reporter, peCase.appliedPathEffectShape().style().isSimpleHa
irline()); | 1173 REPORTER_ASSERT(reporter, peCase.appliedPathEffectShape().style().isSimpleHa
irline()); |
1163 REPORTER_ASSERT(reporter, peCase.appliedFullStyleShape().style().isSimpleHai
rline()); | 1174 REPORTER_ASSERT(reporter, peCase.appliedFullStyleShape().style().isSimpleHai
rline()); |
1164 } | 1175 } |
1165 | 1176 |
1166 void test_volatile_path(skiatest::Reporter* reporter, const Geo& geo) { | 1177 void test_volatile_path(skiatest::Reporter* reporter, const Geo& geo) { |
1167 SkPath vPath = geo.path(); | 1178 SkPath vPath = geo.path(); |
1168 vPath.setIsVolatile(true); | 1179 vPath.setIsVolatile(true); |
1169 | 1180 |
1170 SkPaint dashAndStroke; | 1181 SkPaint dashAndStroke; |
1171 dashAndStroke.setPathEffect(make_dash()); | 1182 dashAndStroke.setPathEffect(make_dash()); |
1172 dashAndStroke.setStrokeWidth(2.f); | 1183 dashAndStroke.setStrokeWidth(2.f); |
1173 dashAndStroke.setStyle(SkPaint::kStroke_Style); | 1184 dashAndStroke.setStyle(SkPaint::kStroke_Style); |
1174 TestCase volatileCase(reporter, vPath, dashAndStroke); | 1185 TestCase volatileCase(reporter, vPath, dashAndStroke); |
1175 // We expect a shape made from a volatile path to have a key iff the shape i
s recognized | 1186 // We expect a shape made from a volatile path to have a key iff the shape i
s recognized |
1176 // as a specialized geometry. | 1187 // as a specialized geometry or it has a small verb count. |
1177 if (geo.isNonPath(dashAndStroke)) { | 1188 if (geo.isNonPath(dashAndStroke) || vPath.countVerbs() <= GrShape::kMaxKeyFr
omDataVerbCnt) { |
1178 REPORTER_ASSERT(reporter, SkToBool(volatileCase.baseKey().count())); | 1189 REPORTER_ASSERT(reporter, SkToBool(volatileCase.baseKey().count())); |
1179 // In this case all the keys should be identical to the non-volatile cas
e. | 1190 // In this case all the keys should be identical to the non-volatile cas
e. |
1180 TestCase nonVolatileCase(reporter, geo.path(), dashAndStroke); | 1191 TestCase nonVolatileCase(reporter, geo.path(), dashAndStroke); |
1181 volatileCase.compare(reporter, nonVolatileCase, TestCase::kAllSame_Compa
risonExpecation); | 1192 volatileCase.compare(reporter, nonVolatileCase, TestCase::kAllSame_Compa
risonExpecation); |
1182 } else { | 1193 } else { |
1183 // None of the keys should be valid. | 1194 // None of the keys should be valid. |
1184 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.baseKey().count())); | 1195 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.baseKey().count())); |
1185 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedPathEffectKey().
count())); | 1196 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedPathEffectKey().
count())); |
1186 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedFullStyleKey().c
ount())); | 1197 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedFullStyleKey().c
ount())); |
1187 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedPathEffectThenSt
rokeKey().count())); | 1198 REPORTER_ASSERT(reporter, !SkToBool(volatileCase.appliedPathEffectThenSt
rokeKey().count())); |
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1761 | 1772 |
1762 TestCase(r, linePath, buttCap).compare(r, TestCase(r, SkRect::MakeEmpty(), f
ill), | 1773 TestCase(r, linePath, buttCap).compare(r, TestCase(r, SkRect::MakeEmpty(), f
ill), |
1763 TestCase::kAllSame_ComparisonExpecati
on); | 1774 TestCase::kAllSame_ComparisonExpecati
on); |
1764 TestCase(r, linePath, squareCap).compare(r, TestCase(r, SkRect::MakeLTRB(2,
2, 6, 6), fill), | 1775 TestCase(r, linePath, squareCap).compare(r, TestCase(r, SkRect::MakeLTRB(2,
2, 6, 6), fill), |
1765 TestCase::kAllSame_ComparisonExpeca
tion); | 1776 TestCase::kAllSame_ComparisonExpeca
tion); |
1766 TestCase(r, linePath, roundCap).compare(r, | 1777 TestCase(r, linePath, roundCap).compare(r, |
1767 TestCase(r, SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 6), 2, 2), fil
l), | 1778 TestCase(r, SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 6), 2, 2), fil
l), |
1768 TestCase::kAllSame_ComparisonExpecation); | 1779 TestCase::kAllSame_ComparisonExpecation); |
1769 } | 1780 } |
1770 | 1781 |
| 1782 static void test_short_path_keys(skiatest::Reporter* r) { |
| 1783 SkPaint paints[4]; |
| 1784 paints[1].setStyle(SkPaint::kStroke_Style); |
| 1785 paints[1].setStrokeWidth(5.f); |
| 1786 paints[2].setStyle(SkPaint::kStroke_Style); |
| 1787 paints[2].setStrokeWidth(0.f); |
| 1788 paints[3].setStyle(SkPaint::kStrokeAndFill_Style); |
| 1789 paints[3].setStrokeWidth(5.f); |
| 1790 |
| 1791 auto compare = [r, &paints] (SkPath* pathA, SkPath* pathB, |
| 1792 TestCase::ComparisonExpecation expectation) { |
| 1793 for (const SkPaint& paint : paints) { |
| 1794 for (PathGeo::Invert invert : {PathGeo::Invert::kNo, PathGeo::Invert
::kYes}) { |
| 1795 for (bool aIsVolatile : {false, true}) { |
| 1796 for (bool bIsVolatile : {false, true}) { |
| 1797 pathA->setIsVolatile(aIsVolatile); |
| 1798 pathB->setIsVolatile(bIsVolatile); |
| 1799 TestCase caseA(PathGeo(*pathA, invert), paint, r); |
| 1800 TestCase caseB(PathGeo(*pathB, invert), paint, r); |
| 1801 caseA.compare(r, caseB, expectation); |
| 1802 } |
| 1803 } |
| 1804 } |
| 1805 } |
| 1806 }; |
| 1807 |
| 1808 SkPath pathA; |
| 1809 SkPath pathB; |
| 1810 |
| 1811 // Two identical paths |
| 1812 pathA.lineTo(10.f, 10.f); |
| 1813 pathA.conicTo(20.f, 20.f, 20.f, 30.f, 0.7f); |
| 1814 |
| 1815 pathB.lineTo(10.f, 10.f); |
| 1816 pathB.conicTo(20.f, 20.f, 20.f, 30.f, 0.7f); |
| 1817 compare(&pathA, &pathB, TestCase::kAllSame_ComparisonExpecation); |
| 1818 |
| 1819 // Give path b a different point |
| 1820 pathB.reset(); |
| 1821 pathB.lineTo(10.f, 10.f); |
| 1822 pathB.conicTo(21.f, 20.f, 20.f, 30.f, 0.7f); |
| 1823 compare(&pathA, &pathB, TestCase::kAllDifferent_ComparisonExpecation); |
| 1824 |
| 1825 // Give path b a different conic weight |
| 1826 pathB.reset(); |
| 1827 pathB.lineTo(10.f, 10.f); |
| 1828 pathB.conicTo(20.f, 20.f, 20.f, 30.f, 0.6f); |
| 1829 compare(&pathA, &pathB, TestCase::kAllDifferent_ComparisonExpecation); |
| 1830 |
| 1831 // Give path b an extra lineTo verb |
| 1832 pathB.reset(); |
| 1833 pathB.lineTo(10.f, 10.f); |
| 1834 pathB.conicTo(20.f, 20.f, 20.f, 30.f, 0.6f); |
| 1835 pathB.lineTo(50.f, 50.f); |
| 1836 compare(&pathA, &pathB, TestCase::kAllDifferent_ComparisonExpecation); |
| 1837 |
| 1838 // Give path b a close |
| 1839 pathB.reset(); |
| 1840 pathB.lineTo(10.f, 10.f); |
| 1841 pathB.conicTo(20.f, 20.f, 20.f, 30.f, 0.7f); |
| 1842 pathB.close(); |
| 1843 compare(&pathA, &pathB, TestCase::kAllDifferent_ComparisonExpecation); |
| 1844 } |
| 1845 |
1771 DEF_TEST(GrShape, reporter) { | 1846 DEF_TEST(GrShape, reporter) { |
1772 SkTArray<std::unique_ptr<Geo>> geos; | 1847 SkTArray<std::unique_ptr<Geo>> geos; |
1773 SkTArray<std::unique_ptr<RRectPathGeo>> rrectPathGeos; | 1848 SkTArray<std::unique_ptr<RRectPathGeo>> rrectPathGeos; |
1774 | 1849 |
1775 for (auto r : { SkRect::MakeWH(10, 20), | 1850 for (auto r : { SkRect::MakeWH(10, 20), |
1776 SkRect::MakeWH(-10, -20), | 1851 SkRect::MakeWH(-10, -20), |
1777 SkRect::MakeWH(-10, 20), | 1852 SkRect::MakeWH(-10, 20), |
1778 SkRect::MakeWH(10, -20)}) { | 1853 SkRect::MakeWH(10, -20)}) { |
1779 geos.emplace_back(new RectGeo(r)); | 1854 geos.emplace_back(new RectGeo(r)); |
1780 SkPath rectPath; | 1855 SkPath rectPath; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1887 } | 1962 } |
1888 | 1963 |
1889 // Test a volatile empty path. | 1964 // Test a volatile empty path. |
1890 test_volatile_path(reporter, PathGeo(SkPath(), PathGeo::Invert::kNo)); | 1965 test_volatile_path(reporter, PathGeo(SkPath(), PathGeo::Invert::kNo)); |
1891 | 1966 |
1892 test_empty_shape(reporter); | 1967 test_empty_shape(reporter); |
1893 | 1968 |
1894 test_lines(reporter); | 1969 test_lines(reporter); |
1895 | 1970 |
1896 test_stroked_lines(reporter); | 1971 test_stroked_lines(reporter); |
| 1972 |
| 1973 test_short_path_keys(reporter); |
1897 } | 1974 } |
1898 | 1975 |
1899 #endif | 1976 #endif |
OLD | NEW |