OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2012 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 #include "Benchmark.h" | |
8 #include "SkCanvas.h" | |
9 #include "SkColor.h" | |
10 #include "SkPaint.h" | |
11 #include "SkPicture.h" | |
12 #include "SkPictureRecorder.h" | |
13 #include "SkPoint.h" | |
14 #include "SkRandom.h" | |
15 #include "SkRect.h" | |
16 #include "SkString.h" | |
17 | |
18 class PictureRecordBench : public Benchmark { | |
19 public: | |
20 PictureRecordBench(const char name[]) { | |
21 fName.printf("picture_record_%s", name); | |
22 } | |
23 | |
24 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE { | |
25 return backend == kNonRendering_Backend; | |
26 } | |
27 | |
28 enum { | |
29 PICTURE_WIDTH = 1000, | |
30 PICTURE_HEIGHT = 4000, | |
31 }; | |
32 protected: | |
33 virtual const char* onGetName() SK_OVERRIDE { | |
34 return fName.c_str(); | |
35 } | |
36 private: | |
37 SkString fName; | |
38 typedef Benchmark INHERITED; | |
39 }; | |
40 | |
41 | |
42 static const int kMaxLoopsPerCanvas = 10000; | |
43 | |
44 /* | |
45 * An SkPicture has internal dictionaries to store bitmaps, matrices, paints, | |
46 * and regions. This bench populates those dictionaries to test the speed of | |
47 * reading and writing to those particular dictionary data structures. | |
48 */ | |
49 class DictionaryRecordBench : public PictureRecordBench { | |
50 public: | |
51 DictionaryRecordBench() : INHERITED("dictionaries") {} | |
52 | |
53 protected: | |
54 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { | |
55 SkPictureRecorder recorder; | |
56 SkCanvas* canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT
); | |
57 | |
58 const SkPoint translateDelta = getTranslateDelta(loops); | |
59 | |
60 for (int i = 0; i < loops; i++) { | |
61 if (0 == i % kMaxLoopsPerCanvas) { | |
62 SkAutoTUnref<SkPicture> picture(recorder.endRecording()); | |
63 canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT); | |
64 } | |
65 | |
66 SkColor color = SK_ColorYELLOW + (i % 255); | |
67 SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT
); | |
68 | |
69 canvas->save(); | |
70 | |
71 // set the clip to the given region | |
72 SkRegion region; | |
73 region.setRect(rect); | |
74 canvas->clipRegion(region); | |
75 | |
76 // fill the clip with a color | |
77 SkPaint paint; | |
78 paint.setColor(color); | |
79 canvas->drawPaint(paint); | |
80 | |
81 // set a matrix on the canvas | |
82 SkMatrix matrix; | |
83 matrix.setRotate(SkIntToScalar(i % 360)); | |
84 canvas->setMatrix(matrix); | |
85 | |
86 // create a simple bitmap | |
87 SkBitmap bitmap; | |
88 bitmap.allocPixels(SkImageInfo::Make(10, 10, | |
89 kRGB_565_SkColorType, kOpaque_S
kAlphaType)); | |
90 | |
91 // draw a single color into the bitmap | |
92 SkCanvas bitmapCanvas(bitmap); | |
93 bitmapCanvas.drawColor(SkColorSetA(color, i % 255)); | |
94 | |
95 // draw the bitmap onto the canvas | |
96 canvas->drawBitmapMatrix(bitmap, matrix); | |
97 | |
98 canvas->restore(); | |
99 canvas->translate(translateDelta.fX, translateDelta.fY); | |
100 } | |
101 SkAutoTUnref<SkPicture> cleanup(recorder.endRecording()); | |
102 } | |
103 | |
104 SkPoint getTranslateDelta(int M) { | |
105 SkIPoint canvasSize = onGetSize(); | |
106 return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/M), | |
107 SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/M)); | |
108 } | |
109 private: | |
110 typedef PictureRecordBench INHERITED; | |
111 }; | |
112 | |
113 /* | |
114 * Populates the SkPaint dictionary with a large number of unique paint | |
115 * objects that differ only by color | |
116 */ | |
117 class UniquePaintDictionaryRecordBench : public PictureRecordBench { | |
118 public: | |
119 UniquePaintDictionaryRecordBench() : INHERITED("unique_paint_dictionary") {
} | |
120 | |
121 protected: | |
122 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { | |
123 SkRandom rand; | |
124 SkPaint paint; | |
125 SkPictureRecorder recorder; | |
126 SkCanvas* canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT
); | |
127 for (int i = 0; i < loops; i++) { | |
128 if (0 == i % kMaxLoopsPerCanvas) { | |
129 SkAutoTUnref<SkPicture> picture(recorder.endRecording()); | |
130 canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT); | |
131 } | |
132 paint.setColor(rand.nextU()); | |
133 canvas->drawPaint(paint); | |
134 } | |
135 SkAutoTUnref<SkPicture> cleanup(recorder.endRecording()); | |
136 } | |
137 | |
138 private: | |
139 typedef PictureRecordBench INHERITED; | |
140 }; | |
141 | |
142 /* | |
143 * Populates the SkPaint dictionary with a number of unique paint | |
144 * objects that get reused repeatedly. | |
145 * | |
146 * Re-creating the paint objects in the inner loop slows the benchmark down 10%
. | |
147 * Using setColor(i % objCount) instead of a random color creates a very high r
ate | |
148 * of hash conflicts, slowing us down 12%. | |
149 */ | |
150 class RecurringPaintDictionaryRecordBench : public PictureRecordBench { | |
151 public: | |
152 RecurringPaintDictionaryRecordBench() : INHERITED("recurring_paint_dictionar
y") { | |
153 SkRandom rand; | |
154 for (int i = 0; i < ObjCount; i++) { | |
155 fPaint[i].setColor(rand.nextU()); | |
156 } | |
157 } | |
158 | |
159 enum { | |
160 ObjCount = 100, // number of unique paint objects | |
161 }; | |
162 protected: | |
163 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE { | |
164 SkPictureRecorder recorder; | |
165 SkCanvas* canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT
, NULL, 0); | |
166 for (int i = 0; i < loops; i++) { | |
167 canvas->drawPaint(fPaint[i % ObjCount]); | |
168 } | |
169 } | |
170 | |
171 private: | |
172 SkPaint fPaint [ObjCount]; | |
173 typedef PictureRecordBench INHERITED; | |
174 }; | |
175 | |
176 /////////////////////////////////////////////////////////////////////////////// | |
177 | |
178 DEF_BENCH( return new DictionaryRecordBench(); ) | |
179 DEF_BENCH( return new UniquePaintDictionaryRecordBench(); ) | |
180 DEF_BENCH( return new RecurringPaintDictionaryRecordBench(); ) | |
OLD | NEW |