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