OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "SampleCode.h" | 8 #include "SampleCode.h" |
9 #include "SkView.h" | 9 #include "SkView.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 "kSetSkewY", | 124 "kSetSkewY", |
125 "kSetRotate", | 125 "kSetRotate", |
126 "kSetRotateTranslate", | 126 "kSetRotateTranslate", |
127 "kSetPerspectiveX", | 127 "kSetPerspectiveX", |
128 "kSetPerspectiveY", | 128 "kSetPerspectiveY", |
129 "kSetAll", | 129 "kSetAll", |
130 }; | 130 }; |
131 | 131 |
132 class FuzzPath { | 132 class FuzzPath { |
133 public: | 133 public: |
134 FuzzPath() | 134 FuzzPath() |
135 : fFloatMin(0) | 135 : fFloatMin(0) |
136 , fFloatMax(800) | 136 , fFloatMax(800) |
137 , fAddCount(0) | 137 , fAddCount(0) |
138 , fPrintName(false) | 138 , fPrintName(false) |
| 139 , fStrokeOnly(false) |
139 , fValidate(false) | 140 , fValidate(false) |
140 { | 141 { |
141 fTab = "
"; | 142 fTab = "
"; |
142 } | 143 } |
143 void randomize() { | 144 void randomize() { |
144 fPathDepth = 0; | 145 fPathDepth = 0; |
145 fPathDepthLimit = fRand.nextRangeU(1, 2); | 146 fPathDepthLimit = fRand.nextRangeU(1, 2); |
146 fPathContourCount = fRand.nextRangeU(1, 4); | 147 fPathContourCount = fRand.nextRangeU(1, 4); |
147 fPathSegmentLimit = fRand.nextRangeU(1, 8); | 148 fPathSegmentLimit = fRand.nextRangeU(1, 8); |
148 fClip = makePath(); | 149 fClip = makePath(); |
(...skipping 16 matching lines...) Expand all Loading... |
165 } | 166 } |
166 | 167 |
167 const SkPaint& getPaint() const { | 168 const SkPaint& getPaint() const { |
168 return fPaint; | 169 return fPaint; |
169 } | 170 } |
170 | 171 |
171 const SkPath& getPath() const { | 172 const SkPath& getPath() const { |
172 return fPath; | 173 return fPath; |
173 } | 174 } |
174 | 175 |
| 176 void setSeed(int seed) { |
| 177 fRand.setSeed(seed); |
| 178 } |
| 179 |
| 180 void setStrokeOnly() { |
| 181 fStrokeOnly = true; |
| 182 } |
| 183 |
175 private: | 184 private: |
176 | 185 |
177 SkPath::AddPathMode makeAddPathMode() { | 186 SkPath::AddPathMode makeAddPathMode() { |
178 return (SkPath::AddPathMode) fRand.nextRangeU(SkPath::kAppend_AddPathMode, | 187 return (SkPath::AddPathMode) fRand.nextRangeU(SkPath::kAppend_AddPathMode, |
179 SkPath::kExtend_AddPathMode); | 188 SkPath::kExtend_AddPathMode); |
180 } | 189 } |
181 | 190 |
182 RandomAddPath makeAddPathType() { | 191 RandomAddPath makeAddPathType() { |
183 return (RandomAddPath) fRand.nextRangeU(0, kRandomAddPath_Last); | 192 return (RandomAddPath) fRand.nextRangeU(0, kRandomAddPath_Last); |
184 } | 193 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 makeScalar(), makeScalar(), makeScalar()); | 267 makeScalar(), makeScalar(), makeScalar()); |
259 break; | 268 break; |
260 } | 269 } |
261 return matrix; | 270 return matrix; |
262 } | 271 } |
263 | 272 |
264 SkPaint makePaint() { | 273 SkPaint makePaint() { |
265 SkPaint paint; | 274 SkPaint paint; |
266 bool antiAlias = fRand.nextBool(); | 275 bool antiAlias = fRand.nextBool(); |
267 paint.setAntiAlias(antiAlias); | 276 paint.setAntiAlias(antiAlias); |
268 SkPaint::Style style = (SkPaint::Style) fRand.nextRangeU(SkPaint::kFill_Styl
e, | 277 SkPaint::Style style = fStrokeOnly ? SkPaint::kStroke_Style : |
269 SkPaint::kStrokeAndFill_Style); | 278 (SkPaint::Style) fRand.nextRangeU(SkPaint::kFill_Style, SkPaint::kStroke
AndFill_Style); |
270 paint.setStyle(style); | 279 paint.setStyle(style); |
271 SkColor color = (SkColor) fRand.nextU(); | 280 SkColor color = (SkColor) fRand.nextU(); |
272 paint.setColor(color); | 281 paint.setColor(color); |
273 SkScalar width = fRand.nextF(); | 282 SkScalar width = fRand.nextRangeF(0, 10); |
274 paint.setStrokeWidth(width); | 283 paint.setStrokeWidth(width); |
275 SkScalar miter = fRand.nextF(); | 284 SkScalar miter = makeScalar(); |
276 paint.setStrokeMiter(miter); | 285 paint.setStrokeMiter(miter); |
277 SkPaint::Cap cap = (SkPaint::Cap) fRand.nextRangeU(SkPaint::kButt_Cap, SkPai
nt::kSquare_Cap); | 286 SkPaint::Cap cap = (SkPaint::Cap) fRand.nextRangeU(SkPaint::kButt_Cap, SkPai
nt::kSquare_Cap); |
278 paint.setStrokeCap(cap); | 287 paint.setStrokeCap(cap); |
279 SkPaint::Join join = (SkPaint::Join) fRand.nextRangeU(SkPaint::kMiter_Join, | 288 SkPaint::Join join = (SkPaint::Join) fRand.nextRangeU(SkPaint::kMiter_Join, |
280 SkPaint::kBevel_Join); | 289 SkPaint::kBevel_Join); |
281 paint.setStrokeJoin(join); | 290 paint.setStrokeJoin(join); |
282 return paint; | 291 return paint; |
283 } | 292 } |
284 | 293 |
285 SkPoint makePoint() { | 294 SkPoint makePoint() { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 if (fPathDepth < fPathDepthLimit) { | 410 if (fPathDepth < fPathDepthLimit) { |
402 ++fPathDepth; | 411 ++fPathDepth; |
403 SkPath src = makePath(); | 412 SkPath src = makePath(); |
404 validate(src); | 413 validate(src); |
405 SkScalar dx = makeScalar(); | 414 SkScalar dx = makeScalar(); |
406 SkScalar dy = makeScalar(); | 415 SkScalar dy = makeScalar(); |
407 SkPath::AddPathMode mode = makeAddPathMode(); | 416 SkPath::AddPathMode mode = makeAddPathMode(); |
408 path.addPath(src, dx, dy, mode); | 417 path.addPath(src, dx, dy, mode); |
409 --fPathDepth; | 418 --fPathDepth; |
410 validate(path); | 419 validate(path); |
411 } | 420 } |
412 break; | 421 break; |
413 case kAddPath2: | 422 case kAddPath2: |
414 if (fPathDepth < fPathDepthLimit) { | 423 if (fPathDepth < fPathDepthLimit) { |
415 ++fPathDepth; | 424 ++fPathDepth; |
416 SkPath src = makePath(); | 425 SkPath src = makePath(); |
417 validate(src); | 426 validate(src); |
418 SkPath::AddPathMode mode = makeAddPathMode(); | 427 SkPath::AddPathMode mode = makeAddPathMode(); |
419 path.addPath(src, mode); | 428 path.addPath(src, mode); |
420 --fPathDepth; | 429 --fPathDepth; |
421 validate(path); | 430 validate(path); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 SkPaint fPaint; | 583 SkPaint fPaint; |
575 SkPath fPath; | 584 SkPath fPath; |
576 SkScalar fFloatMin; | 585 SkScalar fFloatMin; |
577 SkScalar fFloatMax; | 586 SkScalar fFloatMax; |
578 uint32_t fPathContourCount; | 587 uint32_t fPathContourCount; |
579 int fPathDepth; | 588 int fPathDepth; |
580 int fPathDepthLimit; | 589 int fPathDepthLimit; |
581 uint32_t fPathSegmentLimit; | 590 uint32_t fPathSegmentLimit; |
582 int fAddCount; | 591 int fAddCount; |
583 bool fPrintName; | 592 bool fPrintName; |
| 593 bool fStrokeOnly; |
584 bool fValidate; | 594 bool fValidate; |
585 const char* fTab; | 595 const char* fTab; |
586 }; | 596 }; |
587 | 597 |
588 ////////////////////////////////////////////////////////////////////////////// | |
589 static bool contains_only_moveTo(const SkPath& path) { | 598 static bool contains_only_moveTo(const SkPath& path) { |
590 int verbCount = path.countVerbs(); | 599 int verbCount = path.countVerbs(); |
591 if (verbCount == 0) { | 600 if (verbCount == 0) { |
592 return true; | 601 return true; |
593 } | 602 } |
594 SkTDArray<uint8_t> verbs; | 603 SkTDArray<uint8_t> verbs; |
595 verbs.setCount(verbCount); | 604 verbs.setCount(verbCount); |
596 SkDEBUGCODE(int getVerbResult = ) path.getVerbs(verbs.begin(), verbCount); | 605 SkDEBUGCODE(int getVerbResult = ) path.getVerbs(verbs.begin(), verbCount); |
597 SkASSERT(getVerbResult == verbCount); | 606 SkASSERT(getVerbResult == verbCount); |
598 for (int index = 0; index < verbCount; ++index) { | 607 for (int index = 0; index < verbCount; ++index) { |
599 if (verbs[index] != SkPath::kMove_Verb) { | 608 if (verbs[index] != SkPath::kMove_Verb) { |
600 return false; | 609 return false; |
601 } | 610 } |
602 } | 611 } |
603 return true; | 612 return true; |
604 } | 613 } |
605 | 614 |
| 615 #include "SkGraphics.h" |
| 616 #include "SkSurface.h" |
| 617 #include "SkTaskGroup.h" |
| 618 #include "SkTDArray.h" |
| 619 |
| 620 struct ThreadState { |
| 621 int fSeed; |
| 622 const SkBitmap* fBitmap; |
| 623 }; |
| 624 |
| 625 static void test_fuzz(ThreadState* data) { |
| 626 FuzzPath fuzzPath; |
| 627 fuzzPath.setStrokeOnly(); |
| 628 fuzzPath.setSeed(data->fSeed); |
| 629 fuzzPath.randomize(); |
| 630 const SkPath& path = fuzzPath.getPath(); |
| 631 const SkPaint& paint = fuzzPath.getPaint(); |
| 632 const SkImageInfo& info = data->fBitmap->info(); |
| 633 SkCanvas* canvas(SkCanvas::NewRasterDirect(info, data->fBitmap->getPixels(), |
| 634 data->fBitmap->rowBytes())); |
| 635 int w = info.width() / 4; |
| 636 int h = info.height() / 4; |
| 637 int x = data->fSeed / 4 % 4; |
| 638 int y = data->fSeed % 4; |
| 639 SkRect clipBounds = SkRect::MakeXYWH(SkIntToScalar(x) * w, SkIntToScalar(y)
* h, |
| 640 SkIntToScalar(w), SkIntToScalar(h)); |
| 641 canvas->save(); |
| 642 canvas->clipRect(clipBounds); |
| 643 canvas->translate(SkIntToScalar(x) * w, SkIntToScalar(y) * h); |
| 644 canvas->drawPath(path, paint); |
| 645 canvas->restore(); |
| 646 } |
| 647 |
| 648 static void path_fuzz_stroker(SkBitmap* bitmap, int seed) { |
| 649 ThreadState states[100]; |
| 650 for (size_t i = 0; i < SK_ARRAY_COUNT(states); i++) { |
| 651 states[i].fSeed = seed + (int) i; |
| 652 states[i].fBitmap = bitmap; |
| 653 } |
| 654 SkTaskGroup tg; |
| 655 tg.batch(test_fuzz, states, SK_ARRAY_COUNT(states)); |
| 656 } |
| 657 |
606 class PathFuzzView : public SampleView { | 658 class PathFuzzView : public SampleView { |
607 public: | 659 public: |
608 PathFuzzView() { | 660 PathFuzzView() |
609 fDots = 0; | 661 : fOneDraw(false) |
| 662 { |
610 } | 663 } |
611 protected: | 664 protected: |
612 // overrides from SkEventSink | 665 // overrides from SkEventSink |
613 virtual bool onQuery(SkEvent* evt) { | 666 virtual bool onQuery(SkEvent* evt) { |
614 if (SampleCode::TitleQ(*evt)) { | 667 if (SampleCode::TitleQ(*evt)) { |
615 SampleCode::TitleR(evt, "PathFuzzer"); | 668 SampleCode::TitleR(evt, "PathFuzzer"); |
616 return true; | 669 return true; |
617 } | 670 } |
618 return this->INHERITED::onQuery(evt); | 671 return this->INHERITED::onQuery(evt); |
619 } | 672 } |
620 | 673 |
| 674 void onOnceBeforeDraw() SK_OVERRIDE { |
| 675 fIndex = 0; |
| 676 SkImageInfo info(SkImageInfo::MakeN32Premul(SkScalarRoundToInt(width()),
|
| 677 SkScalarRoundToInt(height()))); |
| 678 offscreen.allocPixels(info); |
| 679 path_fuzz_stroker(&offscreen, fIndex); |
| 680 } |
| 681 |
621 virtual void onDrawContent(SkCanvas* canvas) { | 682 virtual void onDrawContent(SkCanvas* canvas) { |
622 fuzzPath.randomize(); | 683 if (fOneDraw) { |
623 const SkPath& path = fuzzPath.getPath(); | 684 fuzzPath.randomize(); |
624 const SkPaint& paint = fuzzPath.getPaint(); | 685 const SkPath& path = fuzzPath.getPath(); |
625 const SkPath& clip = fuzzPath.getClip(); | 686 const SkPaint& paint = fuzzPath.getPaint(); |
626 const SkMatrix& matrix = fuzzPath.getMatrix(); | 687 const SkPath& clip = fuzzPath.getClip(); |
627 if (!contains_only_moveTo(clip)) { | 688 const SkMatrix& matrix = fuzzPath.getMatrix(); |
628 canvas->clipPath(clip); | 689 if (!contains_only_moveTo(clip)) { |
| 690 canvas->clipPath(clip); |
| 691 } |
| 692 canvas->setMatrix(matrix); |
| 693 canvas->drawPath(path, paint); |
| 694 } else { |
| 695 path_fuzz_stroker(&offscreen, fIndex += 100); |
| 696 canvas->drawBitmap(offscreen, 0, 0); |
629 } | 697 } |
630 canvas->setMatrix(matrix); | |
631 canvas->drawPath(path, paint); | |
632 this->inval(NULL); | 698 this->inval(NULL); |
633 if (++fDots == 8000) { | |
634 SkDebugf("\n"); | |
635 fDots = 0; | |
636 } | |
637 if ((fDots % 100) == 99) { | |
638 SkDebugf("."); | |
639 } | |
640 } | 699 } |
641 | 700 |
642 private: | 701 private: |
| 702 int fIndex; |
| 703 SkBitmap offscreen; |
643 FuzzPath fuzzPath; | 704 FuzzPath fuzzPath; |
644 int fDots; | 705 bool fOneDraw; |
645 typedef SkView INHERITED; | 706 typedef SkView INHERITED; |
646 }; | 707 }; |
647 | 708 |
648 ////////////////////////////////////////////////////////////////////////////// | |
649 | |
650 static SkView* MyFactory() { return new PathFuzzView; } | 709 static SkView* MyFactory() { return new PathFuzzView; } |
651 static SkViewRegister reg(MyFactory); | 710 static SkViewRegister reg(MyFactory); |
| 711 |
| 712 |
OLD | NEW |