Index: tests/GrShapeTest.cpp |
diff --git a/tests/GrShapeTest.cpp b/tests/GrShapeTest.cpp |
index 36ebd7b21e68d8b09381244e0db0d665f095c50b..4f96a038e3e27bc0a042562702db6255ac05f39b 100644 |
--- a/tests/GrShapeTest.cpp |
+++ b/tests/GrShapeTest.cpp |
@@ -1078,14 +1078,16 @@ void test_unknown_path_effect(skiatest::Reporter* reporter, const Geo& geo) { |
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, |
const SkRect* cullR) const override { |
*dst = src; |
- dst->lineTo(0, 0); |
- dst->lineTo(10, 10); |
+ // To avoid triggering data-based keying of paths with few verbs we add many segments. |
+ for (int i = 0; i < 100; ++i) { |
+ dst->lineTo(SkIntToScalar(i), SkIntToScalar(i)); |
+ } |
return true; |
} |
void computeFastBounds(SkRect* dst, const SkRect& src) const override { |
*dst = src; |
dst->growToInclude(0, 0); |
- dst->growToInclude(10, 10); |
+ dst->growToInclude(100, 100); |
} |
static sk_sp<SkPathEffect> Make() { return sk_sp<SkPathEffect>(new AddLineTosPathEffect); } |
Factory getFactory() const override { return nullptr; } |
@@ -1156,8 +1158,17 @@ void test_make_hairline_path_effect(skiatest::Reporter* reporter, const Geo& geo |
a.setFillType(b.getFillType()); |
REPORTER_ASSERT(reporter, a == b); |
REPORTER_ASSERT(reporter, a == c); |
- REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey().empty()); |
- REPORTER_ASSERT(reporter, peCase.appliedFullStyleKey().empty()); |
+ // If the resulting path is small enough then it will have a key. |
+ REPORTER_ASSERT(reporter, paths_fill_same(a, b)); |
+ REPORTER_ASSERT(reporter, paths_fill_same(a, c)); |
+ if (c.countVerbs() <= GrShape::kMaxKeyFromDataVerbCnt) { |
+ REPORTER_ASSERT(reporter, !peCase.appliedPathEffectKey().empty()); |
+ REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey() == |
+ peCase.appliedFullStyleKey()); |
+ } else { |
+ REPORTER_ASSERT(reporter, peCase.appliedPathEffectKey().empty()); |
+ REPORTER_ASSERT(reporter, peCase.appliedFullStyleKey().empty()); |
+ } |
} |
REPORTER_ASSERT(reporter, peCase.appliedPathEffectShape().style().isSimpleHairline()); |
REPORTER_ASSERT(reporter, peCase.appliedFullStyleShape().style().isSimpleHairline()); |
@@ -1173,8 +1184,8 @@ void test_volatile_path(skiatest::Reporter* reporter, const Geo& geo) { |
dashAndStroke.setStyle(SkPaint::kStroke_Style); |
TestCase volatileCase(reporter, vPath, dashAndStroke); |
// We expect a shape made from a volatile path to have a key iff the shape is recognized |
- // as a specialized geometry. |
- if (geo.isNonPath(dashAndStroke)) { |
+ // as a specialized geometry or it has a small verb count. |
+ if (geo.isNonPath(dashAndStroke) || vPath.countVerbs() <= GrShape::kMaxKeyFromDataVerbCnt) { |
REPORTER_ASSERT(reporter, SkToBool(volatileCase.baseKey().count())); |
// In this case all the keys should be identical to the non-volatile case. |
TestCase nonVolatileCase(reporter, geo.path(), dashAndStroke); |
@@ -1768,6 +1779,70 @@ static void test_stroked_lines(skiatest::Reporter* r) { |
TestCase::kAllSame_ComparisonExpecation); |
} |
+static void test_short_path_keys(skiatest::Reporter* r) { |
+ SkPaint paints[4]; |
+ paints[1].setStyle(SkPaint::kStroke_Style); |
+ paints[1].setStrokeWidth(5.f); |
+ paints[2].setStyle(SkPaint::kStroke_Style); |
+ paints[2].setStrokeWidth(0.f); |
+ paints[3].setStyle(SkPaint::kStrokeAndFill_Style); |
+ paints[3].setStrokeWidth(5.f); |
+ |
+ auto compare = [r, &paints] (SkPath* pathA, SkPath* pathB, |
+ TestCase::ComparisonExpecation expectation) { |
+ for (const SkPaint& paint : paints) { |
+ for (PathGeo::Invert invert : {PathGeo::Invert::kNo, PathGeo::Invert::kYes}) { |
+ for (bool aIsVolatile : {false, true}) { |
+ for (bool bIsVolatile : {false, true}) { |
+ pathA->setIsVolatile(aIsVolatile); |
+ pathB->setIsVolatile(bIsVolatile); |
+ TestCase caseA(PathGeo(*pathA, invert), paint, r); |
+ TestCase caseB(PathGeo(*pathB, invert), paint, r); |
+ caseA.compare(r, caseB, expectation); |
+ } |
+ } |
+ } |
+ } |
+ }; |
+ |
+ SkPath pathA; |
+ SkPath pathB; |
+ |
+ // Two identical paths |
+ pathA.lineTo(10.f, 10.f); |
+ pathA.conicTo(20.f, 20.f, 20.f, 30.f, 0.7f); |
+ |
+ pathB.lineTo(10.f, 10.f); |
+ pathB.conicTo(20.f, 20.f, 20.f, 30.f, 0.7f); |
+ compare(&pathA, &pathB, TestCase::kAllSame_ComparisonExpecation); |
+ |
+ // Give path b a different point |
+ pathB.reset(); |
+ pathB.lineTo(10.f, 10.f); |
+ pathB.conicTo(21.f, 20.f, 20.f, 30.f, 0.7f); |
+ compare(&pathA, &pathB, TestCase::kAllDifferent_ComparisonExpecation); |
+ |
+ // Give path b a different conic weight |
+ pathB.reset(); |
+ pathB.lineTo(10.f, 10.f); |
+ pathB.conicTo(20.f, 20.f, 20.f, 30.f, 0.6f); |
+ compare(&pathA, &pathB, TestCase::kAllDifferent_ComparisonExpecation); |
+ |
+ // Give path b an extra lineTo verb |
+ pathB.reset(); |
+ pathB.lineTo(10.f, 10.f); |
+ pathB.conicTo(20.f, 20.f, 20.f, 30.f, 0.6f); |
+ pathB.lineTo(50.f, 50.f); |
+ compare(&pathA, &pathB, TestCase::kAllDifferent_ComparisonExpecation); |
+ |
+ // Give path b a close |
+ pathB.reset(); |
+ pathB.lineTo(10.f, 10.f); |
+ pathB.conicTo(20.f, 20.f, 20.f, 30.f, 0.7f); |
+ pathB.close(); |
+ compare(&pathA, &pathB, TestCase::kAllDifferent_ComparisonExpecation); |
+} |
+ |
DEF_TEST(GrShape, reporter) { |
SkTArray<std::unique_ptr<Geo>> geos; |
SkTArray<std::unique_ptr<RRectPathGeo>> rrectPathGeos; |
@@ -1894,6 +1969,8 @@ DEF_TEST(GrShape, reporter) { |
test_lines(reporter); |
test_stroked_lines(reporter); |
+ |
+ test_short_path_keys(reporter); |
} |
#endif |