OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkBenchmark.h" | 8 #include "Benchmark.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
11 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
12 #include "SkPaint.h" | 12 #include "SkPaint.h" |
13 #include "SkRandom.h" | 13 #include "SkRandom.h" |
14 #include "SkShader.h" | 14 #include "SkShader.h" |
15 #include "SkString.h" | 15 #include "SkString.h" |
16 #include "SkTArray.h" | 16 #include "SkTArray.h" |
17 | 17 |
18 enum Flags { | 18 enum Flags { |
19 kStroke_Flag = 1 << 0, | 19 kStroke_Flag = 1 << 0, |
20 kBig_Flag = 1 << 1 | 20 kBig_Flag = 1 << 1 |
21 }; | 21 }; |
22 | 22 |
23 #define FLAGS00 Flags(0) | 23 #define FLAGS00 Flags(0) |
24 #define FLAGS01 Flags(kStroke_Flag) | 24 #define FLAGS01 Flags(kStroke_Flag) |
25 #define FLAGS10 Flags(kBig_Flag) | 25 #define FLAGS10 Flags(kBig_Flag) |
26 #define FLAGS11 Flags(kStroke_Flag | kBig_Flag) | 26 #define FLAGS11 Flags(kStroke_Flag | kBig_Flag) |
27 | 27 |
28 class PathBench : public SkBenchmark { | 28 class PathBench : public Benchmark { |
29 SkPaint fPaint; | 29 SkPaint fPaint; |
30 SkString fName; | 30 SkString fName; |
31 Flags fFlags; | 31 Flags fFlags; |
32 public: | 32 public: |
33 PathBench(Flags flags) : fFlags(flags) { | 33 PathBench(Flags flags) : fFlags(flags) { |
34 fPaint.setStyle(flags & kStroke_Flag ? SkPaint::kStroke_Style : | 34 fPaint.setStyle(flags & kStroke_Flag ? SkPaint::kStroke_Style : |
35 SkPaint::kFill_Style); | 35 SkPaint::kFill_Style); |
36 fPaint.setStrokeWidth(SkIntToScalar(5)); | 36 fPaint.setStrokeWidth(SkIntToScalar(5)); |
37 fPaint.setStrokeJoin(SkPaint::kBevel_Join); | 37 fPaint.setStrokeJoin(SkPaint::kBevel_Join); |
38 } | 38 } |
(...skipping 28 matching lines...) Expand all Loading... |
67 count >>= 2; | 67 count >>= 2; |
68 } | 68 } |
69 count >>= (3 * complexity()); | 69 count >>= (3 * complexity()); |
70 | 70 |
71 for (int i = 0; i < count; i++) { | 71 for (int i = 0; i < count; i++) { |
72 canvas->drawPath(path, paint); | 72 canvas->drawPath(path, paint); |
73 } | 73 } |
74 } | 74 } |
75 | 75 |
76 private: | 76 private: |
77 typedef SkBenchmark INHERITED; | 77 typedef Benchmark INHERITED; |
78 }; | 78 }; |
79 | 79 |
80 class TrianglePathBench : public PathBench { | 80 class TrianglePathBench : public PathBench { |
81 public: | 81 public: |
82 TrianglePathBench(Flags flags) : INHERITED(flags) {} | 82 TrianglePathBench(Flags flags) : INHERITED(flags) {} |
83 | 83 |
84 virtual void appendName(SkString* name) SK_OVERRIDE { | 84 virtual void appendName(SkString* name) SK_OVERRIDE { |
85 name->append("triangle"); | 85 name->append("triangle"); |
86 } | 86 } |
87 virtual void makePath(SkPath* path) SK_OVERRIDE { | 87 virtual void makePath(SkPath* path) SK_OVERRIDE { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 path->moveTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480); | 207 path->moveTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480); |
208 for (size_t i = 1; i < 100; i++) { | 208 for (size_t i = 1; i < 100; i++) { |
209 path->lineTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480); | 209 path->lineTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480); |
210 } | 210 } |
211 } | 211 } |
212 virtual int complexity() SK_OVERRIDE { return 2; } | 212 virtual int complexity() SK_OVERRIDE { return 2; } |
213 private: | 213 private: |
214 typedef PathBench INHERITED; | 214 typedef PathBench INHERITED; |
215 }; | 215 }; |
216 | 216 |
217 class RandomPathBench : public SkBenchmark { | 217 class RandomPathBench : public Benchmark { |
218 public: | 218 public: |
219 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { | 219 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { |
220 return backend == kNonRendering_Backend; | 220 return backend == kNonRendering_Backend; |
221 } | 221 } |
222 | 222 |
223 protected: | 223 protected: |
224 void createData(int minVerbs, | 224 void createData(int minVerbs, |
225 int maxVerbs, | 225 int maxVerbs, |
226 bool allowMoves = true, | 226 bool allowMoves = true, |
227 SkRect* bounds = NULL) { | 227 SkRect* bounds = NULL) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 kNumVerbs = 1 << 5, | 305 kNumVerbs = 1 << 5, |
306 kNumPoints = 1 << 5, | 306 kNumPoints = 1 << 5, |
307 }; | 307 }; |
308 SkAutoTArray<int> fVerbCnts; | 308 SkAutoTArray<int> fVerbCnts; |
309 SkAutoTArray<SkPath::Verb> fVerbs; | 309 SkAutoTArray<SkPath::Verb> fVerbs; |
310 SkAutoTArray<SkPoint> fPoints; | 310 SkAutoTArray<SkPoint> fPoints; |
311 int fCurrPath; | 311 int fCurrPath; |
312 int fCurrVerb; | 312 int fCurrVerb; |
313 int fCurrPoint; | 313 int fCurrPoint; |
314 SkRandom fRandom; | 314 SkRandom fRandom; |
315 typedef SkBenchmark INHERITED; | 315 typedef Benchmark INHERITED; |
316 }; | 316 }; |
317 | 317 |
318 class PathCreateBench : public RandomPathBench { | 318 class PathCreateBench : public RandomPathBench { |
319 public: | 319 public: |
320 PathCreateBench() { | 320 PathCreateBench() { |
321 } | 321 } |
322 | 322 |
323 protected: | 323 protected: |
324 virtual const char* onGetName() SK_OVERRIDE { | 324 virtual const char* onGetName() SK_OVERRIDE { |
325 return "path_create"; | 325 return "path_create"; |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 // must be a pow 2 | 560 // must be a pow 2 |
561 kPathCnt = 1 << 5, | 561 kPathCnt = 1 << 5, |
562 }; | 562 }; |
563 SkAutoTArray<SkPath> fPaths0; | 563 SkAutoTArray<SkPath> fPaths0; |
564 SkAutoTArray<SkPath> fPaths1; | 564 SkAutoTArray<SkPath> fPaths1; |
565 SkMatrix fMatrix; | 565 SkMatrix fMatrix; |
566 typedef RandomPathBench INHERITED; | 566 typedef RandomPathBench INHERITED; |
567 }; | 567 }; |
568 | 568 |
569 | 569 |
570 class CirclesBench : public SkBenchmark { | 570 class CirclesBench : public Benchmark { |
571 protected: | 571 protected: |
572 SkString fName; | 572 SkString fName; |
573 Flags fFlags; | 573 Flags fFlags; |
574 | 574 |
575 public: | 575 public: |
576 CirclesBench(Flags flags) : fFlags(flags) { | 576 CirclesBench(Flags flags) : fFlags(flags) { |
577 fName.printf("circles_%s", fFlags & kStroke_Flag ? "stroke" : "fill"); | 577 fName.printf("circles_%s", fFlags & kStroke_Flag ? "stroke" : "fill"); |
578 } | 578 } |
579 | 579 |
580 protected: | 580 protected: |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 temp.arcTo(r, 0, 0, false); | 612 temp.arcTo(r, 0, 0, false); |
613 temp.addOval(r, SkPath::kCCW_Direction); | 613 temp.addOval(r, SkPath::kCCW_Direction); |
614 temp.arcTo(r, 360, 0, true); | 614 temp.arcTo(r, 360, 0, true); |
615 temp.close(); | 615 temp.close(); |
616 | 616 |
617 canvas->drawPath(temp, paint); | 617 canvas->drawPath(temp, paint); |
618 } | 618 } |
619 } | 619 } |
620 | 620 |
621 private: | 621 private: |
622 typedef SkBenchmark INHERITED; | 622 typedef Benchmark INHERITED; |
623 }; | 623 }; |
624 | 624 |
625 | 625 |
626 // Chrome creates its own round rects with each corner possibly being different. | 626 // Chrome creates its own round rects with each corner possibly being different. |
627 // In its "zero radius" incarnation it creates degenerate round rects. | 627 // In its "zero radius" incarnation it creates degenerate round rects. |
628 // Note: PathTest::test_arb_round_rect_is_convex and | 628 // Note: PathTest::test_arb_round_rect_is_convex and |
629 // test_arb_zero_rad_round_rect_is_rect perform almost exactly | 629 // test_arb_zero_rad_round_rect_is_rect perform almost exactly |
630 // the same test (but with no drawing) | 630 // the same test (but with no drawing) |
631 class ArbRoundRectBench : public SkBenchmark { | 631 class ArbRoundRectBench : public Benchmark { |
632 protected: | 632 protected: |
633 SkString fName; | 633 SkString fName; |
634 | 634 |
635 public: | 635 public: |
636 ArbRoundRectBench(bool zeroRad) : fZeroRad(zeroRad) { | 636 ArbRoundRectBench(bool zeroRad) : fZeroRad(zeroRad) { |
637 if (zeroRad) { | 637 if (zeroRad) { |
638 fName.printf("zeroradroundrect"); | 638 fName.printf("zeroradroundrect"); |
639 } else { | 639 } else { |
640 fName.printf("arbroundrect"); | 640 fName.printf("arbroundrect"); |
641 } | 641 } |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15); | 716 make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15); |
717 } | 717 } |
718 | 718 |
719 canvas->drawPath(temp, paint); | 719 canvas->drawPath(temp, paint); |
720 } | 720 } |
721 } | 721 } |
722 | 722 |
723 private: | 723 private: |
724 bool fZeroRad; // should 0 radius rounds rects be tested? | 724 bool fZeroRad; // should 0 radius rounds rects be tested? |
725 | 725 |
726 typedef SkBenchmark INHERITED; | 726 typedef Benchmark INHERITED; |
727 }; | 727 }; |
728 | 728 |
729 class ConservativelyContainsBench : public SkBenchmark { | 729 class ConservativelyContainsBench : public Benchmark { |
730 public: | 730 public: |
731 enum Type { | 731 enum Type { |
732 kRect_Type, | 732 kRect_Type, |
733 kRoundRect_Type, | 733 kRoundRect_Type, |
734 kOval_Type, | 734 kOval_Type, |
735 }; | 735 }; |
736 | 736 |
737 ConservativelyContainsBench(Type type) { | 737 ConservativelyContainsBench(Type type) { |
738 fParity = false; | 738 fParity = false; |
739 fName = "conservatively_contains_"; | 739 fName = "conservatively_contains_"; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 static const SkSize kQueryMin; // minimum query rect size, should be <= kQue
ryMax | 792 static const SkSize kQueryMin; // minimum query rect size, should be <= kQue
ryMax |
793 static const SkSize kQueryMax; // max query rect size, should < kBounds | 793 static const SkSize kQueryMax; // max query rect size, should < kBounds |
794 static const SkRect kBaseRect; // rect that is used to construct the path | 794 static const SkRect kBaseRect; // rect that is used to construct the path |
795 static const SkScalar kRRRadii[2]; // x and y radii for round rect | 795 static const SkScalar kRRRadii[2]; // x and y radii for round rect |
796 | 796 |
797 SkString fName; | 797 SkString fName; |
798 SkPath fPath; | 798 SkPath fPath; |
799 bool fParity; | 799 bool fParity; |
800 SkTDArray<SkRect> fQueryRects; | 800 SkTDArray<SkRect> fQueryRects; |
801 | 801 |
802 typedef SkBenchmark INHERITED; | 802 typedef Benchmark INHERITED; |
803 }; | 803 }; |
804 | 804 |
805 /////////////////////////////////////////////////////////////////////////////// | 805 /////////////////////////////////////////////////////////////////////////////// |
806 | 806 |
807 #include "SkGeometry.h" | 807 #include "SkGeometry.h" |
808 | 808 |
809 class ConicBench_Chop5 : public SkBenchmark { | 809 class ConicBench_Chop5 : public Benchmark { |
810 SkConic fRQ; | 810 SkConic fRQ; |
811 public: | 811 public: |
812 ConicBench_Chop5() { | 812 ConicBench_Chop5() { |
813 fRQ.fPts[0].set(0, 0); | 813 fRQ.fPts[0].set(0, 0); |
814 fRQ.fPts[1].set(100, 0); | 814 fRQ.fPts[1].set(100, 0); |
815 fRQ.fPts[2].set(100, 100); | 815 fRQ.fPts[2].set(100, 100); |
816 fRQ.fW = SkScalarCos(SK_ScalarPI/4); | 816 fRQ.fW = SkScalarCos(SK_ScalarPI/4); |
817 } | 817 } |
818 | 818 |
819 private: | 819 private: |
820 virtual const char* onGetName() SK_OVERRIDE { | 820 virtual const char* onGetName() SK_OVERRIDE { |
821 return "ratquad-chop-0.5"; | 821 return "ratquad-chop-0.5"; |
822 } | 822 } |
823 | 823 |
824 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { | 824 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { |
825 SkConic dst[2]; | 825 SkConic dst[2]; |
826 for (int i = 0; i < loops; ++i) { | 826 for (int i = 0; i < loops; ++i) { |
827 fRQ.chopAt(0.5f, dst); | 827 fRQ.chopAt(0.5f, dst); |
828 } | 828 } |
829 } | 829 } |
830 | 830 |
831 typedef SkBenchmark INHERITED; | 831 typedef Benchmark INHERITED; |
832 }; | 832 }; |
833 | 833 |
834 class ConicBench_ChopHalf : public SkBenchmark { | 834 class ConicBench_ChopHalf : public Benchmark { |
835 SkConic fRQ; | 835 SkConic fRQ; |
836 public: | 836 public: |
837 ConicBench_ChopHalf() { | 837 ConicBench_ChopHalf() { |
838 fRQ.fPts[0].set(0, 0); | 838 fRQ.fPts[0].set(0, 0); |
839 fRQ.fPts[1].set(100, 0); | 839 fRQ.fPts[1].set(100, 0); |
840 fRQ.fPts[2].set(100, 100); | 840 fRQ.fPts[2].set(100, 100); |
841 fRQ.fW = SkScalarCos(SK_ScalarPI/4); | 841 fRQ.fW = SkScalarCos(SK_ScalarPI/4); |
842 } | 842 } |
843 | 843 |
844 private: | 844 private: |
845 virtual const char* onGetName() SK_OVERRIDE { | 845 virtual const char* onGetName() SK_OVERRIDE { |
846 return "ratquad-chop-half"; | 846 return "ratquad-chop-half"; |
847 } | 847 } |
848 | 848 |
849 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { | 849 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { |
850 SkConic dst[2]; | 850 SkConic dst[2]; |
851 for (int i = 0; i < loops; ++i) { | 851 for (int i = 0; i < loops; ++i) { |
852 fRQ.chop(dst); | 852 fRQ.chop(dst); |
853 } | 853 } |
854 } | 854 } |
855 | 855 |
856 typedef SkBenchmark INHERITED; | 856 typedef Benchmark INHERITED; |
857 }; | 857 }; |
858 | 858 |
859 /////////////////////////////////////////////////////////////////////////////// | 859 /////////////////////////////////////////////////////////////////////////////// |
860 | 860 |
861 static void rand_conic(SkConic* conic, SkRandom& rand) { | 861 static void rand_conic(SkConic* conic, SkRandom& rand) { |
862 for (int i = 0; i < 3; ++i) { | 862 for (int i = 0; i < 3; ++i) { |
863 conic->fPts[i].set(rand.nextUScalar1() * 100, rand.nextUScalar1() * 100)
; | 863 conic->fPts[i].set(rand.nextUScalar1() * 100, rand.nextUScalar1() * 100)
; |
864 } | 864 } |
865 if (rand.nextUScalar1() > 0.5f) { | 865 if (rand.nextUScalar1() > 0.5f) { |
866 conic->fW = rand.nextUScalar1(); | 866 conic->fW = rand.nextUScalar1(); |
867 } else { | 867 } else { |
868 conic->fW = 1 + rand.nextUScalar1() * 4; | 868 conic->fW = 1 + rand.nextUScalar1() * 4; |
869 } | 869 } |
870 } | 870 } |
871 | 871 |
872 class ConicBench : public SkBenchmark { | 872 class ConicBench : public Benchmark { |
873 public: | 873 public: |
874 ConicBench() { | 874 ConicBench() { |
875 SkRandom rand; | 875 SkRandom rand; |
876 for (int i = 0; i < CONICS; ++i) { | 876 for (int i = 0; i < CONICS; ++i) { |
877 rand_conic(&fConics[i], rand); | 877 rand_conic(&fConics[i], rand); |
878 } | 878 } |
879 } | 879 } |
880 | 880 |
881 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { | 881 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { |
882 return backend == kNonRendering_Backend; | 882 return backend == kNonRendering_Backend; |
883 } | 883 } |
884 | 884 |
885 protected: | 885 protected: |
886 enum { | 886 enum { |
887 CONICS = 100 | 887 CONICS = 100 |
888 }; | 888 }; |
889 SkConic fConics[CONICS]; | 889 SkConic fConics[CONICS]; |
890 | 890 |
891 private: | 891 private: |
892 typedef SkBenchmark INHERITED; | 892 typedef Benchmark INHERITED; |
893 }; | 893 }; |
894 | 894 |
895 class ConicBench_ComputeError : public ConicBench { | 895 class ConicBench_ComputeError : public ConicBench { |
896 public: | 896 public: |
897 ConicBench_ComputeError() {} | 897 ConicBench_ComputeError() {} |
898 | 898 |
899 protected: | 899 protected: |
900 virtual const char* onGetName() SK_OVERRIDE { | 900 virtual const char* onGetName() SK_OVERRIDE { |
901 return "conic-compute-error"; | 901 return "conic-compute-error"; |
902 } | 902 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1010 DEF_BENCH( return new ArbRoundRectBench(true); ) | 1010 DEF_BENCH( return new ArbRoundRectBench(true); ) |
1011 DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::k
Rect_Type); ) | 1011 DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::k
Rect_Type); ) |
1012 DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::k
RoundRect_Type); ) | 1012 DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::k
RoundRect_Type); ) |
1013 DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::k
Oval_Type); ) | 1013 DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::k
Oval_Type); ) |
1014 | 1014 |
1015 DEF_BENCH( return new ConicBench_Chop5() ) | 1015 DEF_BENCH( return new ConicBench_Chop5() ) |
1016 DEF_BENCH( return new ConicBench_ChopHalf() ) | 1016 DEF_BENCH( return new ConicBench_ChopHalf() ) |
1017 DEF_BENCH( return new ConicBench_ComputeError() ) | 1017 DEF_BENCH( return new ConicBench_ComputeError() ) |
1018 DEF_BENCH( return new ConicBench_asQuadTol() ) | 1018 DEF_BENCH( return new ConicBench_asQuadTol() ) |
1019 DEF_BENCH( return new ConicBench_quadPow2() ) | 1019 DEF_BENCH( return new ConicBench_quadPow2() ) |
OLD | NEW |