OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "SkBenchmark.h" | 8 #include "SkBenchmark.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkPaint.h" | 10 #include "SkPaint.h" |
11 #include "SkRandom.h" | 11 #include "SkRandom.h" |
| 12 #include "SkShader.h" |
12 #include "SkString.h" | 13 #include "SkString.h" |
13 | 14 |
14 // This bench simulates the calls Skia sees from various HTML5 canvas | 15 // This bench simulates the calls Skia sees from various HTML5 canvas |
15 // game bench marks | 16 // game bench marks |
16 class GameBench : public SkBenchmark { | 17 class GameBench : public SkBenchmark { |
17 public: | 18 public: |
18 enum Type { | 19 enum Type { |
19 kScale_Type, | 20 kScale_Type, |
20 kTranslate_Type, | 21 kTranslate_Type, |
21 kRotate_Type | 22 kRotate_Type |
22 }; | 23 }; |
23 | 24 |
24 enum Clear { | 25 enum Clear { |
25 kFull_Clear, | 26 kFull_Clear, |
26 kPartial_Clear | 27 kPartial_Clear |
27 }; | 28 }; |
28 | 29 |
29 GameBench(void* param, Type type, Clear clear, | 30 GameBench(void* param, Type type, Clear clear, |
30 bool aligned = false, bool useAtlas = false) | 31 bool aligned = false, bool useAtlas = false, |
| 32 bool useDrawVertices = false) |
31 : INHERITED(param) | 33 : INHERITED(param) |
32 , fType(type) | 34 , fType(type) |
33 , fClear(clear) | 35 , fClear(clear) |
34 , fAligned(aligned) | 36 , fAligned(aligned) |
35 , fUseAtlas(useAtlas) | 37 , fUseAtlas(useAtlas) |
| 38 , fUseDrawVertices(useDrawVertices) |
36 , fName("game") | 39 , fName("game") |
37 , fNumSaved(0) | 40 , fNumSaved(0) |
38 , fInitialized(false) { | 41 , fInitialized(false) { |
39 | 42 |
40 switch (fType) { | 43 switch (fType) { |
41 case kScale_Type: | 44 case kScale_Type: |
42 fName.append("_scale"); | 45 fName.append("_scale"); |
43 break; | 46 break; |
44 case kTranslate_Type: | 47 case kTranslate_Type: |
45 fName.append("_trans"); | 48 fName.append("_trans"); |
(...skipping 10 matching lines...) Expand all Loading... |
56 if (kPartial_Clear == clear) { | 59 if (kPartial_Clear == clear) { |
57 fName.append("_partial"); | 60 fName.append("_partial"); |
58 } else { | 61 } else { |
59 fName.append("_full"); | 62 fName.append("_full"); |
60 } | 63 } |
61 | 64 |
62 if (useAtlas) { | 65 if (useAtlas) { |
63 fName.append("_atlas"); | 66 fName.append("_atlas"); |
64 } | 67 } |
65 | 68 |
| 69 if (useDrawVertices) { |
| 70 fName.append("_drawVerts"); |
| 71 } |
| 72 |
66 // It's HTML 5 canvas, so always AA | 73 // It's HTML 5 canvas, so always AA |
67 fName.append("_aa"); | 74 fName.append("_aa"); |
68 } | 75 } |
69 | 76 |
70 protected: | 77 protected: |
71 virtual const char* onGetName() SK_OVERRIDE { | 78 virtual const char* onGetName() SK_OVERRIDE { |
72 return fName.c_str(); | 79 return fName.c_str(); |
73 } | 80 } |
74 | 81 |
75 virtual void onPreDraw() SK_OVERRIDE { | 82 virtual void onPreDraw() SK_OVERRIDE { |
76 if (!fInitialized) { | 83 if (!fInitialized) { |
77 this->makeCheckerboard(); | 84 this->makeCheckerboard(); |
78 this->makeAtlas(); | 85 this->makeAtlas(); |
79 fInitialized = true; | 86 fInitialized = true; |
80 } | 87 } |
81 } | 88 } |
82 | 89 |
83 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 90 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
84 static SkMWCRandom scaleRand; | 91 SkMWCRandom scaleRand; |
85 static SkMWCRandom transRand; | 92 SkMWCRandom transRand; |
86 static SkMWCRandom rotRand; | 93 SkMWCRandom rotRand; |
87 | 94 |
88 int width, height; | 95 int width, height; |
89 if (fUseAtlas) { | 96 if (fUseAtlas) { |
90 width = kAtlasCellWidth; | 97 width = kAtlasCellWidth; |
91 height = kAtlasCellHeight; | 98 height = kAtlasCellHeight; |
92 } else { | 99 } else { |
93 width = kCheckerboardWidth; | 100 width = kCheckerboardWidth; |
94 height = kCheckerboardHeight; | 101 height = kCheckerboardHeight; |
95 } | 102 } |
96 | 103 |
(...skipping 12 matching lines...) Expand all Loading... |
109 maxTransX = SkIntToScalar(size.fWidth - width); | 116 maxTransX = SkIntToScalar(size.fWidth - width); |
110 maxTransY = SkIntToScalar(size.fHeight - height); | 117 maxTransY = SkIntToScalar(size.fHeight - height); |
111 } else { | 118 } else { |
112 SkASSERT(kRotate_Type == fType); | 119 SkASSERT(kRotate_Type == fType); |
113 // Yes, some rotations will be off the top and left sides | 120 // Yes, some rotations will be off the top and left sides |
114 maxTransX = size.fWidth - SK_ScalarSqrt2 * height; | 121 maxTransX = size.fWidth - SK_ScalarSqrt2 * height; |
115 maxTransY = size.fHeight - SK_ScalarSqrt2 * height; | 122 maxTransY = size.fHeight - SK_ScalarSqrt2 * height; |
116 } | 123 } |
117 | 124 |
118 SkMatrix mat; | 125 SkMatrix mat; |
119 SkIRect src = { 0, 0, width, height }; | |
120 SkRect dst = { 0, 0, SkIntToScalar(width), SkIntToScalar(height) }; | 126 SkRect dst = { 0, 0, SkIntToScalar(width), SkIntToScalar(height) }; |
121 SkRect clearRect = { -1.0f, -1.0f, width+1.0f, height+1.0f }; | 127 SkRect clearRect = { -1.0f, -1.0f, width+1.0f, height+1.0f }; |
| 128 SkPoint verts[4] = { // for drawVertices path |
| 129 { 0, 0 }, |
| 130 { 0, SkIntToScalar(height) }, |
| 131 { SkIntToScalar(width), SkIntToScalar(height) }, |
| 132 { SkIntToScalar(width), 0 } |
| 133 }; |
| 134 uint16_t indices[6] = { 0, 1, 2, 0, 2, 3 }; |
122 | 135 |
123 SkPaint p; | 136 SkPaint p; |
124 p.setColor(0xFF000000); | 137 p.setColor(0xFF000000); |
125 p.setFilterBitmap(true); | 138 p.setFilterBitmap(true); |
126 | 139 |
| 140 SkPaint p2; // for drawVertices path |
| 141 p2.setColor(0xFF000000); |
| 142 p2.setFilterBitmap(true); |
| 143 p2.setShader(SkShader::CreateBitmapShader(fAtlas, |
| 144 SkShader::kClamp_TileMode, |
| 145 SkShader::kClamp_TileMode))->u
nref(); |
| 146 |
127 for (int i = 0; i < kNumRects; ++i, ++fNumSaved) { | 147 for (int i = 0; i < kNumRects; ++i, ++fNumSaved) { |
128 | 148 |
129 if (0 == i % kNumBeforeClear) { | 149 if (0 == i % kNumBeforeClear) { |
130 if (kPartial_Clear == fClear) { | 150 if (kPartial_Clear == fClear) { |
131 for (int j = 0; j < fNumSaved; ++j) { | 151 for (int j = 0; j < fNumSaved; ++j) { |
132 canvas->setMatrix(SkMatrix::I()); | 152 canvas->setMatrix(SkMatrix::I()); |
133 mat.setTranslate(fSaved[j][0], fSaved[j][1]); | 153 mat.setTranslate(fSaved[j][0], fSaved[j][1]); |
134 | 154 |
135 if (kScale_Type == fType) { | 155 if (kScale_Type == fType) { |
136 mat.preScale(fSaved[j][2], fSaved[j][2]); | 156 mat.preScale(fSaved[j][2], fSaved[j][2]); |
(...skipping 29 matching lines...) Expand all Loading... |
166 fSaved[fNumSaved][2] = scaleRand.nextRangeScalar(0.5f, 1.5f); | 186 fSaved[fNumSaved][2] = scaleRand.nextRangeScalar(0.5f, 1.5f); |
167 mat.preScale(fSaved[fNumSaved][2], fSaved[fNumSaved][2]); | 187 mat.preScale(fSaved[fNumSaved][2], fSaved[fNumSaved][2]); |
168 } else if (kRotate_Type == fType) { | 188 } else if (kRotate_Type == fType) { |
169 fSaved[fNumSaved][2] = rotRand.nextRangeScalar(0.0f, 360.0f); | 189 fSaved[fNumSaved][2] = rotRand.nextRangeScalar(0.0f, 360.0f); |
170 mat.preRotate(fSaved[fNumSaved][2]); | 190 mat.preRotate(fSaved[fNumSaved][2]); |
171 } | 191 } |
172 | 192 |
173 canvas->concat(mat); | 193 canvas->concat(mat); |
174 if (fUseAtlas) { | 194 if (fUseAtlas) { |
175 static int curCell = 0; | 195 static int curCell = 0; |
176 src = fAtlasRects[curCell % (kNumAtlasedX)][curCell / (kNumAtlas
edX)]; | 196 SkIRect src = fAtlasRects[curCell % (kNumAtlasedX)][curCell / (k
NumAtlasedX)]; |
177 curCell = (curCell + 1) % (kNumAtlasedX*kNumAtlasedY); | 197 curCell = (curCell + 1) % (kNumAtlasedX*kNumAtlasedY); |
178 canvas->drawBitmapRect(fAtlas, &src, dst, &p); | 198 |
| 199 if (fUseDrawVertices) { |
| 200 SkPoint uvs[4] = { |
| 201 { SkIntToScalar(src.fLeft), SkIntToScalar(src.fBottom)
}, |
| 202 { SkIntToScalar(src.fLeft), SkIntToScalar(src.fTop) }, |
| 203 { SkIntToScalar(src.fRight), SkIntToScalar(src.fTop) }, |
| 204 { SkIntToScalar(src.fRight), SkIntToScalar(src.fBottom)
}, |
| 205 }; |
| 206 canvas->drawVertices(SkCanvas::kTriangles_VertexMode, |
| 207 4, verts, uvs, NULL, NULL, |
| 208 indices, 6, p2); |
| 209 } else { |
| 210 canvas->drawBitmapRect(fAtlas, &src, dst, &p); |
| 211 } |
179 } else { | 212 } else { |
180 canvas->drawBitmapRect(fCheckerboard, &src, dst, &p); | 213 canvas->drawBitmapRect(fCheckerboard, NULL, dst, &p); |
181 } | 214 } |
182 } | 215 } |
183 } | 216 } |
184 | 217 |
185 private: | 218 private: |
186 static const int kCheckerboardWidth = 64; | 219 static const int kCheckerboardWidth = 64; |
187 static const int kCheckerboardHeight = 128; | 220 static const int kCheckerboardHeight = 128; |
188 | 221 |
189 static const int kAtlasCellWidth = 48; | 222 static const int kAtlasCellWidth = 48; |
190 static const int kAtlasCellHeight = 36; | 223 static const int kAtlasCellHeight = 36; |
(...skipping 11 matching lines...) Expand all Loading... |
202 #else | 235 #else |
203 static const int kNumRects = 5000; | 236 static const int kNumRects = 5000; |
204 static const int kNumBeforeClear = 300; | 237 static const int kNumBeforeClear = 300; |
205 #endif | 238 #endif |
206 | 239 |
207 | 240 |
208 Type fType; | 241 Type fType; |
209 Clear fClear; | 242 Clear fClear; |
210 bool fAligned; | 243 bool fAligned; |
211 bool fUseAtlas; | 244 bool fUseAtlas; |
| 245 bool fUseDrawVertices; |
212 SkString fName; | 246 SkString fName; |
213 int fNumSaved; // num draws stored in 'fSaved' | 247 int fNumSaved; // num draws stored in 'fSaved' |
214 bool fInitialized; | 248 bool fInitialized; |
215 | 249 |
216 // 0 & 1 are always x & y translate. 2 is either scale or rotate. | 250 // 0 & 1 are always x & y translate. 2 is either scale or rotate. |
217 SkScalar fSaved[kNumBeforeClear][3]; | 251 SkScalar fSaved[kNumBeforeClear][3]; |
218 | 252 |
219 SkBitmap fCheckerboard; | 253 SkBitmap fCheckerboard; |
220 SkBitmap fAtlas; | 254 SkBitmap fAtlas; |
221 SkIRect fAtlasRects[kNumAtlasedX][kNumAtlasedY]; | 255 SkIRect fAtlasRects[kNumAtlasedX][kNumAtlasedY]; |
(...skipping 30 matching lines...) Expand all Loading... |
252 for (int y = 0; y < kNumAtlasedY; ++y) { | 286 for (int y = 0; y < kNumAtlasedY; ++y) { |
253 for (int x = 0; x < kNumAtlasedX; ++x) { | 287 for (int x = 0; x < kNumAtlasedX; ++x) { |
254 colors[x][y] = rand.nextU() | 0xff000000; | 288 colors[x][y] = rand.nextU() | 0xff000000; |
255 fAtlasRects[x][y] = SkIRect::MakeXYWH(kAtlasSpacer + x * (kAtlas
CellWidth + kAtlasSpacer), | 289 fAtlasRects[x][y] = SkIRect::MakeXYWH(kAtlasSpacer + x * (kAtlas
CellWidth + kAtlasSpacer), |
256 kAtlasSpacer + y * (kAtlas
CellHeight + kAtlasSpacer), | 290 kAtlasSpacer + y * (kAtlas
CellHeight + kAtlasSpacer), |
257 kAtlasCellWidth, | 291 kAtlasCellWidth, |
258 kAtlasCellHeight); | 292 kAtlasCellHeight); |
259 } | 293 } |
260 } | 294 } |
261 | 295 |
262 | |
263 fAtlas.setConfig(SkBitmap::kARGB_8888_Config, kTotAtlasWidth, kTotAtlasH
eight); | 296 fAtlas.setConfig(SkBitmap::kARGB_8888_Config, kTotAtlasWidth, kTotAtlasH
eight); |
264 fAtlas.allocPixels(); | 297 fAtlas.allocPixels(); |
265 SkAutoLockPixels lock(fAtlas); | 298 SkAutoLockPixels lock(fAtlas); |
266 | 299 |
267 for (int y = 0; y < kTotAtlasHeight; ++y) { | 300 for (int y = 0; y < kTotAtlasHeight; ++y) { |
268 int colorY = y / (kAtlasCellHeight + kAtlasSpacer); | 301 int colorY = y / (kAtlasCellHeight + kAtlasSpacer); |
269 bool inColorY = (y % (kAtlasCellHeight + kAtlasSpacer)) >= kAtlasSpa
cer; | 302 bool inColorY = (y % (kAtlasCellHeight + kAtlasSpacer)) >= kAtlasSpa
cer; |
270 | 303 |
271 SkPMColor* scanline = fAtlas.getAddr32(0, y); | 304 SkPMColor* scanline = fAtlas.getAddr32(0, y); |
272 | 305 |
(...skipping 30 matching lines...) Expand all Loading... |
303 DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, | 336 DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, |
304 GameBench::kFull_Clear)); ) | 337 GameBench::kFull_Clear)); ) |
305 DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, | 338 DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, |
306 GameBench::kFull_Clear, true)); ) | 339 GameBench::kFull_Clear, true)); ) |
307 DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kRotate_Type, | 340 DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kRotate_Type, |
308 GameBench::kFull_Clear)); ) | 341 GameBench::kFull_Clear)); ) |
309 | 342 |
310 // Atlased | 343 // Atlased |
311 DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, | 344 DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, |
312 GameBench::kFull_Clear, false, true)
); ) | 345 GameBench::kFull_Clear, false, true)
); ) |
| 346 DEF_BENCH( return SkNEW_ARGS(GameBench, (p, GameBench::kTranslate_Type, |
| 347 GameBench::kFull_Clear, false, true,
true)); ) |
OLD | NEW |