| 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
|
|
|