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