Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright 2016 Google Inc. | |
| 3 * | |
| 4 * Use of this source code is governed by a BSD-style license that can be | |
| 5 * found in the LICENSE file. | |
| 6 */ | |
| 7 | |
| 8 #include "Test.h" | |
| 9 #if SK_SUPPORT_GPU | |
| 10 #include "GrShape.h" | |
| 11 #include "SkPath.h" | |
| 12 #include "SkDashPathEffect.h" | |
| 13 | |
| 14 namespace { | |
| 15 class TestCase { | |
| 16 public: | |
| 17 TestCase(const SkRRect& rrect, const SkPaint& paint) : fBase(rrect, paint) { | |
| 18 this->init(); | |
| 19 } | |
| 20 | |
| 21 struct SelfExpectations { | |
| 22 bool fPEHasEffect; | |
| 23 bool fPEHasValidKey; | |
| 24 bool fStrokeApplies; | |
| 25 }; | |
| 26 | |
| 27 void testExpectations(skiatest::Reporter* reporter, SelfExpectations expecta tions) const; | |
| 28 | |
| 29 enum ComparisonExpecation { | |
| 30 kAllDifferent_ComparisonExpecation, | |
| 31 kSameUpToPE_ComparisonExpecation, | |
| 32 kSameUpToStroke_ComparisonExpecation, | |
| 33 kAllSame_ComparisonExpecation, | |
| 34 }; | |
| 35 | |
| 36 void compare(skiatest::Reporter*, const TestCase& that, ComparisonExpecation ) const; | |
| 37 | |
| 38 private: | |
| 39 void init() { | |
| 40 fAppliedPE = fBase.applyPathEffect(); | |
| 41 fAppliedPEThenStroke = fAppliedPE.applyFullStyle(); | |
| 42 fAppliedFull = fBase.applyFullStyle(); | |
| 43 | |
| 44 fBaseKeyIsValid = MakeKey(&fBaseKey, fBase); | |
| 45 fAppliedPEKeyIsValid = MakeKey(&fAppliedPEKey, fAppliedPE); | |
| 46 fAppliedPEThenStrokeKeyIsValid = MakeKey(&fAppliedPEThenStrokeKey, fAppl iedPEThenStroke); | |
| 47 fAppliedFullKeyIsValid = MakeKey(&fAppliedFullKey, fAppliedFull) ; | |
| 48 } | |
| 49 | |
| 50 using Key = SkTArray<uint32_t>; | |
| 51 | |
| 52 static bool MakeKey(Key* key, const GrShape& shape) { | |
| 53 int size = shape.unstyledKeySize(); | |
| 54 if (size <= 0) { | |
| 55 return false; | |
| 56 } | |
| 57 key->reset(size); | |
| 58 shape.writeUnstyledKey(key->begin()); | |
| 59 return true; | |
| 60 } | |
| 61 | |
| 62 GrShape fBase; | |
| 63 GrShape fAppliedPE; | |
| 64 GrShape fAppliedPEThenStroke; | |
| 65 GrShape fAppliedFull; | |
| 66 | |
| 67 Key fBaseKey; | |
| 68 Key fAppliedPEKey; | |
| 69 Key fAppliedPEThenStrokeKey; | |
| 70 Key fAppliedFullKey; | |
| 71 | |
| 72 bool fBaseKeyIsValid; | |
| 73 bool fAppliedPEKeyIsValid; | |
| 74 bool fAppliedPEThenStrokeKeyIsValid; | |
| 75 bool fAppliedFullKeyIsValid; | |
| 76 }; | |
| 77 | |
| 78 void TestCase::testExpectations(skiatest::Reporter* reporter, SelfExpectations e xpectations) const { | |
| 79 // Applying the path effect and then the stroke should always be the same as applying | |
| 80 // both in one go. | |
| 81 REPORTER_ASSERT(reporter, fAppliedPEThenStrokeKey == | |
|
robertphillips
2016/04/25 12:07:06
one line ?
bsalomon
2016/04/25 13:32:27
Done.
| |
| 82 fAppliedFullKey); | |
| 83 // The base's key should always be valid (unless the path is volatile) | |
| 84 REPORTER_ASSERT(reporter, fBaseKeyIsValid); | |
| 85 if (expectations.fPEHasEffect) { | |
| 86 REPORTER_ASSERT(reporter, fBaseKey != fAppliedPEKey); | |
| 87 REPORTER_ASSERT(reporter, expectations.fPEHasEffect == fAppliedPEKeyIsVa lid); | |
| 88 REPORTER_ASSERT(reporter, fBaseKey != fAppliedFullKey); | |
| 89 REPORTER_ASSERT(reporter, expectations.fPEHasEffect == fAppliedFullKeyIs Valid); | |
| 90 if (expectations.fStrokeApplies && expectations.fPEHasValidKey) { | |
| 91 REPORTER_ASSERT(reporter, fAppliedPEKey != fAppliedFullKey); | |
| 92 REPORTER_ASSERT(reporter, expectations.fPEHasEffect == fAppliedFullK eyIsValid); | |
| 93 } | |
| 94 } else { | |
| 95 REPORTER_ASSERT(reporter, fBaseKey == fAppliedPEKey); | |
| 96 if (expectations.fStrokeApplies) { | |
| 97 REPORTER_ASSERT(reporter, fBaseKey != fAppliedFullKey); | |
| 98 } else { | |
| 99 REPORTER_ASSERT(reporter, fBaseKey == fAppliedFullKey); | |
| 100 } | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 void TestCase::compare(skiatest::Reporter* reporter, const TestCase& that, | |
| 105 ComparisonExpecation expectation) const { | |
| 106 switch (expectation) { | |
| 107 case kAllDifferent_ComparisonExpecation: | |
| 108 REPORTER_ASSERT(reporter, fBaseKey != that.fBaseKey); | |
| 109 REPORTER_ASSERT(reporter, fAppliedPEKey != that.fAppliedPEKey); | |
|
robertphillips
2016/04/25 12:07:06
1 line ? + the 3 clones below ?
bsalomon
2016/04/25 13:32:27
Done.
| |
| 110 REPORTER_ASSERT(reporter, fAppliedFullKey != | |
| 111 that.fAppliedFullKey); | |
| 112 break; | |
| 113 case kSameUpToPE_ComparisonExpecation: | |
| 114 REPORTER_ASSERT(reporter, fBaseKey == that.fBaseKey); | |
| 115 REPORTER_ASSERT(reporter, fAppliedPEKey != that.fAppliedPEKey); | |
| 116 REPORTER_ASSERT(reporter, fAppliedFullKey != | |
| 117 that.fAppliedFullKey); | |
| 118 break; | |
| 119 case kSameUpToStroke_ComparisonExpecation: | |
| 120 REPORTER_ASSERT(reporter, fBaseKey == that.fBaseKey); | |
| 121 REPORTER_ASSERT(reporter, fAppliedPEKey == that.fAppliedPEKey); | |
| 122 REPORTER_ASSERT(reporter, fAppliedFullKey != | |
| 123 that.fAppliedFullKey); | |
| 124 break; | |
| 125 case kAllSame_ComparisonExpecation: | |
| 126 REPORTER_ASSERT(reporter, fBaseKey == that.fBaseKey); | |
| 127 REPORTER_ASSERT(reporter, fAppliedPEKey == that.fAppliedPEKey); | |
| 128 REPORTER_ASSERT(reporter, fAppliedFullKey == | |
| 129 that.fAppliedFullKey); | |
| 130 break; | |
| 131 } | |
| 132 } | |
| 133 } // namespace | |
| 134 | |
|
robertphillips
2016/04/25 12:07:06
static ?
bsalomon
2016/04/25 13:32:27
Done.
| |
| 135 sk_sp<SkPathEffect> make_dash() { | |
| 136 static const SkScalar kIntervals[] = { 0.25, 3.f, 0.5, 2.f }; | |
| 137 static const SkScalar kPhase = 0.75; | |
| 138 return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), kPhase ); | |
| 139 } | |
| 140 | |
|
robertphillips
2016/04/25 12:07:06
static ?
bsalomon
2016/04/25 13:32:27
Done.
| |
| 141 sk_sp<SkPathEffect> make_null_dash() { | |
| 142 static const SkScalar kNullIntervals[] = {0, 0, 0, 0, 0, 0}; | |
| 143 return SkDashPathEffect::Make(kNullIntervals, SK_ARRAY_COUNT(kNullIntervals) , 0.f); | |
| 144 } | |
| 145 | |
| 146 static void test_basic(skiatest::Reporter* reporter, const SkRRect& rrect) { | |
| 147 sk_sp<SkPathEffect> dashPE = make_dash(); | |
| 148 | |
| 149 TestCase::SelfExpectations expectations; | |
| 150 SkPaint fill; | |
| 151 | |
| 152 TestCase fillCase(rrect, fill); | |
| 153 expectations.fPEHasEffect = false; | |
| 154 expectations.fPEHasValidKey = false; | |
| 155 expectations.fStrokeApplies = false; | |
| 156 fillCase.testExpectations(reporter, expectations); | |
| 157 // Test that another GrShape instance built from the same primitive is the s ame. | |
| 158 TestCase(rrect, fill).compare(reporter, fillCase, TestCase::kAllSame_Compari sonExpecation); | |
| 159 | |
| 160 SkPaint stroke2RoundBevel; | |
| 161 stroke2RoundBevel.setStyle(SkPaint::kStroke_Style); | |
| 162 stroke2RoundBevel.setStrokeCap(SkPaint::kRound_Cap); | |
| 163 stroke2RoundBevel.setStrokeJoin(SkPaint::kBevel_Join); | |
| 164 stroke2RoundBevel.setStrokeWidth(2.f); | |
| 165 TestCase stroke2RoundBevelCase(rrect, stroke2RoundBevel); | |
| 166 expectations.fPEHasValidKey = true; | |
| 167 expectations.fPEHasEffect = false; | |
| 168 expectations.fStrokeApplies = true; | |
| 169 stroke2RoundBevelCase.testExpectations(reporter, expectations); | |
| 170 TestCase(rrect, stroke2RoundBevel).compare(reporter, stroke2RoundBevelCase, | |
| 171 TestCase::kAllSame_ComparisonExpe cation); | |
| 172 | |
| 173 SkPaint stroke2RoundBevelDash = stroke2RoundBevel; | |
| 174 stroke2RoundBevelDash.setPathEffect(make_dash()); | |
| 175 TestCase stroke2RoundBevelDashCase(rrect, stroke2RoundBevelDash); | |
| 176 expectations.fPEHasValidKey = true; | |
| 177 expectations.fPEHasEffect = true; | |
| 178 expectations.fStrokeApplies = true; | |
| 179 stroke2RoundBevelDashCase.testExpectations(reporter, expectations); | |
| 180 TestCase(rrect, stroke2RoundBevelDash).compare(reporter, stroke2RoundBevelDa shCase, | |
| 181 TestCase::kAllSame_Comparison Expecation); | |
| 182 | |
| 183 fillCase.compare(reporter, stroke2RoundBevelCase, | |
| 184 TestCase::kSameUpToStroke_ComparisonExpecation); | |
| 185 fillCase.compare(reporter, stroke2RoundBevelDashCase, | |
| 186 TestCase::kSameUpToPE_ComparisonExpecation); | |
| 187 stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase, | |
| 188 TestCase::kSameUpToPE_ComparisonExpecation); | |
| 189 } | |
| 190 | |
| 191 template <typename T> | |
| 192 static void test_stroke_param(skiatest::Reporter* reporter, const SkRRect& rrect , | |
| 193 std::function<void(SkPaint*, T)> setter, T a, T b) { | |
| 194 // Set the stroke width so that we don't get hairline. However, call the fun ction second so that | |
| 195 // it can override. | |
| 196 SkPaint strokeA; | |
| 197 strokeA.setStyle(SkPaint::kStroke_Style); | |
| 198 strokeA.setStrokeWidth(2.f); | |
| 199 setter(&strokeA, a); | |
| 200 SkPaint strokeB; | |
| 201 strokeB.setStyle(SkPaint::kStroke_Style); | |
| 202 strokeB.setStrokeWidth(2.f); | |
| 203 setter(&strokeB, b); | |
| 204 | |
| 205 TestCase strokeACase(rrect, strokeA); | |
| 206 TestCase strokeBCase(rrect, strokeB); | |
| 207 strokeACase.compare(reporter, strokeBCase, TestCase::kSameUpToStroke_Compari sonExpecation); | |
| 208 | |
| 209 // Make sure stroking params don't affect fill style. | |
| 210 SkPaint fillA = strokeA, fillB = strokeB; | |
| 211 fillA.setStyle(SkPaint::kFill_Style); | |
| 212 fillB.setStyle(SkPaint::kFill_Style); | |
| 213 TestCase fillACase(rrect, fillA); | |
| 214 TestCase fillBCase(rrect, fillB); | |
| 215 fillACase.compare(reporter, fillBCase, TestCase::kAllSame_ComparisonExpecati on); | |
| 216 | |
| 217 // Make sure just applying the dash but not stroke gives the same key for bo th stroking | |
| 218 // variations. | |
| 219 SkPaint dashA = strokeA, dashB = strokeB; | |
| 220 dashA.setPathEffect(make_dash()); | |
| 221 dashB.setPathEffect(make_dash()); | |
| 222 TestCase dashACase(rrect, dashA); | |
| 223 TestCase dashBCase(rrect, dashB); | |
| 224 dashACase.compare(reporter, dashBCase, TestCase::kSameUpToStroke_ComparisonE xpecation); | |
| 225 } | |
| 226 | |
| 227 static void test_miter_limit(skiatest::Reporter* reporter, const SkRRect& rrect) { | |
| 228 // Miter limit should only matter when stroking with miter joins. It shouldn 't affect other | |
| 229 // joins or fills. | |
| 230 SkPaint miterA; | |
| 231 miterA.setStyle(SkPaint::kStroke_Style); | |
| 232 miterA.setStrokeWidth(2.f); | |
| 233 miterA.setStrokeJoin(SkPaint::kMiter_Join); | |
| 234 miterA.setStrokeMiter(0.5); | |
| 235 SkPaint miterB = miterA; | |
| 236 miterA.setStrokeMiter(0.6); | |
| 237 | |
| 238 TestCase miterACase(rrect, miterA); | |
| 239 TestCase miterBCase(rrect, miterB); | |
| 240 miterACase.compare(reporter, miterBCase, TestCase::kSameUpToStroke_Compariso nExpecation); | |
| 241 | |
| 242 SkPaint noMiterA = miterA, noMiterB = miterB; | |
| 243 noMiterA.setStrokeJoin(SkPaint::kRound_Join); | |
| 244 noMiterB.setStrokeJoin(SkPaint::kRound_Join); | |
| 245 TestCase noMiterACase(rrect, noMiterA); | |
| 246 TestCase noMiterBCase(rrect, noMiterB); | |
| 247 noMiterACase.compare(reporter, noMiterBCase, TestCase::kAllSame_ComparisonEx pecation); | |
| 248 | |
| 249 SkPaint fillA = miterA, fillB = miterB; | |
| 250 fillA.setStyle(SkPaint::kFill_Style); | |
| 251 fillB.setStyle(SkPaint::kFill_Style); | |
| 252 TestCase fillACase(rrect, fillA); | |
| 253 TestCase fillBCase(rrect, fillB); | |
| 254 fillACase.compare(reporter, fillBCase, TestCase::kAllSame_ComparisonExpecati on); | |
| 255 } | |
| 256 | |
| 257 static void test_dash_fill(skiatest::Reporter* reporter, const SkRRect& rrect) { | |
| 258 // A dash with no stroke should have no effect | |
| 259 for (auto md : {make_dash, make_null_dash}) { | |
| 260 SkPaint dashFill; | |
| 261 dashFill.setPathEffect(md()); | |
| 262 TestCase dashFillCase(rrect, dashFill); | |
| 263 | |
| 264 TestCase fillCase(rrect, SkPaint()); | |
| 265 dashFillCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonEx pecation); | |
| 266 } | |
| 267 } | |
| 268 | |
| 269 void test_null_dash(skiatest::Reporter* reporter, const SkRRect& rrect) { | |
| 270 SkPaint fill; | |
| 271 SkPaint stroke; | |
| 272 stroke.setStyle(SkPaint::kStroke_Style); | |
| 273 stroke.setStrokeWidth(1.f); | |
| 274 SkPaint dash; | |
| 275 dash.setStyle(SkPaint::kStroke_Style); | |
| 276 dash.setStrokeWidth(1.f); | |
| 277 dash.setPathEffect(make_dash()); | |
| 278 SkPaint nullDash; | |
| 279 nullDash.setStyle(SkPaint::kStroke_Style); | |
| 280 nullDash.setStrokeWidth(1.f); | |
| 281 nullDash.setPathEffect(make_null_dash()); | |
| 282 | |
| 283 TestCase fillCase(rrect, fill); | |
| 284 TestCase strokeCase(rrect, stroke); | |
| 285 TestCase dashCase(rrect, dash); | |
| 286 TestCase nullDashCase(rrect, nullDash); | |
| 287 | |
| 288 nullDashCase.compare(reporter, fillCase, TestCase::kSameUpToStroke_Compariso nExpecation); | |
| 289 nullDashCase.compare(reporter, strokeCase, TestCase::kAllSame_ComparisonExpe cation); | |
| 290 nullDashCase.compare(reporter, dashCase, TestCase::kSameUpToPE_ComparisonExp ecation); | |
| 291 } | |
| 292 | |
| 293 DEF_TEST(GrShape, reporter) { | |
| 294 sk_sp<SkPathEffect> dashPE = make_dash(); | |
| 295 | |
| 296 for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), | |
| 297 SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4)}) { | |
| 298 test_basic(reporter, rr); | |
|
robertphillips
2016/04/25 12:07:06
why two test_basic(reporter, rr) calls ?
bsalomon
2016/04/25 13:32:27
Done.
| |
| 299 test_basic(reporter, rr); | |
| 300 test_dash_fill(reporter, rr); | |
| 301 test_null_dash(reporter, rr); | |
|
robertphillips
2016/04/25 12:07:06
setting modifying -> modifying ?
bsalomon
2016/04/25 13:32:27
Done.
| |
| 302 // Test setting modifying various stroke params. | |
| 303 test_stroke_param<SkScalar>( | |
| 304 reporter, rr, | |
| 305 [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, | |
| 306 SkIntToScalar(2), SkIntToScalar(4)); | |
| 307 test_stroke_param<SkPaint::Cap>( | |
| 308 reporter, rr, | |
| 309 [](SkPaint* p, SkPaint::Cap c) { p->setStrokeCap(c);}, | |
| 310 SkPaint::kButt_Cap, SkPaint::kRound_Cap); | |
| 311 test_stroke_param<SkPaint::Join>( | |
| 312 reporter, rr, | |
| 313 [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j); }, | |
| 314 SkPaint::kMiter_Join, SkPaint::kRound_Join); | |
| 315 test_miter_limit(reporter, rr); | |
| 316 } | |
| 317 } | |
| 318 | |
| 319 #endif | |
| OLD | NEW |