Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Side by Side Diff: bench/CodecSubsetBench.cpp

Issue 1160953002: Subset decoding benchmarks (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« bench/CodecSubsetBench.h ('K') | « bench/CodecSubsetBench.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2015 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
8 #include "CodecSubsetBench.h"
9 #include "SkData.h"
10 #include "SkCodec.h"
11 #include "SkImageDecoder.h"
12 #include "SkOSFile.h"
13 #include "SkStream.h"
14
15 /*
16 *
17 * This benchmark is designed to test the performance of subset decoding.
18 *
19 */
20 CodecSubsetBench::CodecSubsetBench(SkString* path,
21 SubsetMode subsetMode,
22 SkColorType colorType,
23 uint32_t subsetWidth,
24 uint32_t subsetHeight,
25 uint32_t offsetLeft,
26 uint32_t offsetTop,
27 uint32_t divisor,
28 bool useCodec)
29 : fSubsetMode(subsetMode)
30 , fColorType(colorType)
31 , fSubsetWidth(subsetWidth)
32 , fSubsetHeight(subsetHeight)
33 , fOffsetLeft(offsetLeft)
34 , fOffsetTop(offsetTop)
35 , fDivisor(divisor)
36 , fUseCodec(useCodec)
37 {
38 // Parse the filename
39 SkString baseName = SkOSPath::Basename(path->c_str());
40
41 // Choose an informative subset mode name
42 SkString modeName;
43 switch(fSubsetMode) {
44 case kSingle_SubsetMode:
45 SkASSERT(0 == divisor);
46 modeName.printf("Single_%dx%d +%d_+%d", fSubsetWidth, fSubsetHeight, fOffsetLeft,
47 fOffsetTop);
48 break;
49 case kDivisor_SubsetMode:
50 SkASSERT(0 == subsetWidth);
51 SkASSERT(0 == subsetHeight);
52 SkASSERT(0 == offsetLeft);
53 SkASSERT(0 == offsetTop);
54 modeName.printf("Divisor_%dx%d", fDivisor, fDivisor);
55 break;
56 case kTranslate_SubsetMode:
57 SkASSERT(0 == divisor);
58 SkASSERT(0 == offsetLeft);
59 SkASSERT(0 == offsetTop);
60 modeName.printf("Size_%dx%d", fSubsetWidth, fSubsetHeight);
61 break;
62 case kScale_SubsetMode:
63 SkASSERT(0 == divisor);
64 SkASSERT(0 == offsetLeft);
65 SkASSERT(0 == offsetTop);
66 modeName.printf("Scale_%dx%d", fSubsetWidth, fSubsetHeight);
67 break;
68 }
69
70 // Choose an informative color name
71 const char* colorName;
72 switch(fColorType) {
scroggo 2015/05/29 15:36:02 What about kIndex8?
msarett 2015/06/01 14:03:25 Agreed!
73 case kN32_SkColorType:
74 colorName = "N32";
75 break;
76 case kRGB_565_SkColorType:
77 colorName = "565";
78 break;
79 case kGray_8_SkColorType:
80 colorName = "Gray8";
81 break;
82 case kAlpha_8_SkColorType:
83 colorName = "Alpha8";
84 break;
85 default:
86 colorName = "Unknown";
87 }
88 fName.printf("%sSubset%s_%s_%s", fUseCodec ? "Codec" : "Image", modeName.c_s tr(),
89 baseName.c_str(), colorName);
90
91 // Perform the decode setup
92 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path->c_str()));
93 fStream.reset(new SkMemoryStream(encoded));
94 }
95
96 const char* CodecSubsetBench::onGetName() {
97 return fName.c_str();
98 }
99
100 bool CodecSubsetBench::isSuitableFor(Backend backend) {
101 return kNonRendering_Backend == backend;
102 }
103
104 void CodecSubsetBench::onDraw(const int n, SkCanvas* canvas) {
105 // Choose a different benchmark depending on the mode
106 switch(fSubsetMode) {
scroggo 2015/05/29 15:36:02 This giant switch statement might argue for using
msarett 2015/06/01 14:03:25 Agreed.
107 case kSingle_SubsetMode:
108 if (fUseCodec) {
109 for (int count = 0; count < n; count++) {
110 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream- >duplicate()));
111 const SkImageInfo info = codec->getInfo();
112 SkAutoTDeleteArray<uint8_t> row(SkNEW_ARRAY(uint8_t, info.mi nRowBytes()));
113 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecod er(info);
114
115 SkBitmap bitmap;
116 if (!bitmap.tryAllocPixels(info.makeWH(fSubsetWidth, fSubset Height))) {
117 SkDebugf("Could not allocate memory. Aborting bench.\n" );
118 return;
119 }
120
121 scanlineDecoder->skipScanlines(fOffsetTop);
122 uint32_t bpp = info.bytesPerPixel();
123 for (uint32_t y = 0; y < fSubsetHeight; y++) {
124 scanlineDecoder->getScanlines(row.get(), 1, 0);
125 memcpy(bitmap.getAddr(0, y), row.get() + fOffsetLeft * b pp,
126 fSubsetWidth * bpp);
127 }
128 }
129 } else {
130 for (int count = 0; count < n; count++) {
131 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factor y(fStream));
132 int width, height;
133 decoder->buildTileIndex(fStream->duplicate(), &width, &heigh t);
scroggo 2015/05/29 15:36:02 Do we need to safely early exit in case buildTileI
msarett 2015/06/01 14:03:24 Let's check that the decode succeeds before creati
134 SkBitmap bitmap;
135 SkIRect rect = SkIRect::MakeXYWH(fOffsetLeft, fOffsetTop, fS ubsetWidth,
136 fSubsetHeight);
137 decoder->decodeSubset(&bitmap, rect, fColorType);
138 }
139 }
140 break;
141 case kDivisor_SubsetMode:
142 if (fUseCodec) {
143 for (int count = 0; count < n; count++) {
144 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream- >duplicate()));
145 const SkImageInfo info = codec->getInfo();
146 SkAutoTDeleteArray<uint8_t> row(SkNEW_ARRAY(uint8_t, info.mi nRowBytes()));
147 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecod er(info);
148
149 uint32_t subsetWidth = info.width() / fDivisor;
scroggo 2015/05/29 15:36:02 These variables could all be const?
msarett 2015/06/01 14:03:25 Done.
150 uint32_t subsetHeight = info.height() / fDivisor;
151 uint32_t maxSubsetWidth = subsetWidth + info.width() % fDivi sor;
152 uint32_t maxSubsetHeight = subsetHeight + info.height() % fD ivisor;
153 SkBitmap bitmap;
154 // Note that we use the same bitmap for all of the subsets.
155 // It might be slightly larger than necessary for some of th e subsets.
156 if (!bitmap.tryAllocPixels(info.makeWH(maxSubsetWidth, maxSu bsetHeight))) {
157 SkDebugf("Could not allocate memory. Aborting bench.\n" );
158 return;
159 }
160
161 for (uint32_t blockX = 0; blockX < fDivisor; blockX++) {
162 for (uint32_t blockY = 0; blockY < fDivisor; blockY++) {
163 scanlineDecoder->skipScanlines(blockY * subsetHeight );
164 uint32_t currSubsetWidth =
165 (blockX == fDivisor - 1) ? maxSubsetWidth : subsetWidth;
166 uint32_t currSubsetHeight =
167 (blockY == fDivisor - 1) ? maxSubsetHeight : subsetHeight;
168 uint32_t bpp = info.bytesPerPixel();
169 for (uint32_t y = 0; y < currSubsetHeight; y++) {
170 scanlineDecoder->getScanlines(row.get(), 1, 0);
171 memcpy(bitmap.getAddr(0, y), row.get() + fOffset Left * bpp,
172 currSubsetWidth * bpp);
173 }
174 }
175 }
176 }
177 } else {
178 for (int count = 0; count < n; count++) {
179 int width, height;
180 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factor y(fStream));
181 decoder->buildTileIndex(fStream->duplicate(), &width, &heigh t);
182
183 uint32_t subsetWidth = width / fDivisor;
184 uint32_t subsetHeight = height / fDivisor;
185 uint32_t maxSubsetWidth = subsetWidth + width % fDivisor;
186 uint32_t maxSubsetHeight = subsetHeight + height % fDivisor;
187 SkBitmap bitmap;
188 // Note that we use the same bitmap for all of the subsets.
189 // It might be slightly larger than necessary for some of th e subsets.
190 if (!bitmap.tryAllocPixels(SkImageInfo::Make(maxSubsetWidth, maxSubsetHeight,
scroggo 2015/05/29 15:36:02 When using SkImageDecoder, you don't need to alloc
msarett 2015/06/01 14:03:24 The reason I allocate here is so that SkImageDecod
scroggo 2015/06/01 17:25:14 Got it. We talked about this in person and you con
msarett 2015/06/01 20:37:01 Done.
191 fColorType, kOpaque_SkAlphaType))) {
192 SkDebugf("Could not allocate memory. Aborting bench.\n" );
193 return;
194 }
195
196 for (uint32_t blockX = 0; blockX < fDivisor; blockX++) {
197 for (uint32_t blockY = 0; blockY < fDivisor; blockY++) {
198 uint32_t currSubsetWidth =
199 (blockX == fDivisor - 1) ? maxSubsetWidth : subsetWidth;
200 uint32_t currSubsetHeight =
201 (blockY == fDivisor - 1) ? maxSubsetHeight : subsetHeight;
202 SkIRect rect = SkIRect::MakeXYWH(blockX * subsetWidt h,
203 blockY * subsetHeight, currSubsetWidth, curr SubsetHeight);
204 decoder->decodeSubset(&bitmap, rect, fColorType);
205 }
206 }
207 }
208 }
209 break;
210 case kTranslate_SubsetMode:
211 if (fUseCodec) {
212 for (int count = 0; count < n; count++) {
213 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream- >duplicate()));
214 const SkImageInfo info = codec->getInfo();
215 SkAutoTDeleteArray<uint8_t> row(SkNEW_ARRAY(uint8_t, info.mi nRowBytes()));
216 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecod er(info);
217
218 SkBitmap bitmap;
219 // Note that we use the same bitmap for all of the subsets.
220 // It might be larger than necessary for the end subsets.
221 if (!bitmap.tryAllocPixels(info.makeWH(fSubsetWidth, fSubset Height))) {
222 SkDebugf("Could not allocate memory. Aborting bench.\n" );
223 return;
224 }
225
226 for (int x = 0; x < info.width(); x += fSubsetWidth) {
227 for (int y = 0; y < info.height(); y += fSubsetHeight) {
228 scanlineDecoder->skipScanlines(y);
229 uint32_t currSubsetWidth = x + (int) fSubsetWidth > info.width() ?
230 info.width() - x : fSubsetWidth;
231 uint32_t currSubsetHeight = y + (int) fSubsetHeight > info.height() ?
232 info.height() - y : fSubsetHeight;
233 uint32_t bpp = info.bytesPerPixel();
234 for (uint32_t y = 0; y < currSubsetHeight; y++) {
235 scanlineDecoder->getScanlines(row.get(), 1, 0);
236 memcpy(bitmap.getAddr(0, y), row.get() + x * bpp ,
237 currSubsetWidth * bpp);
238 }
239 }
240 }
241 }
242 } else {
243 for (int count = 0; count < n; count++) {
244 int width, height;
245 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factor y(fStream));
246 decoder->buildTileIndex(fStream->duplicate(), &width, &heigh t);
247 SkBitmap bitmap;
248 // Note that we use the same bitmap for all of the subsets.
249 // It might be larger than necessary for the end subsets.
250 if (!bitmap.tryAllocPixels(SkImageInfo::Make(fSubsetWidth, f SubsetHeight,
scroggo 2015/05/29 15:36:02 Again, this is not necessary.
msarett 2015/06/01 14:03:25 Acknowledged.
251 fColorType, kOpaque_SkAlphaType))) {
252 SkDebugf("Could not allocate memory. Aborting bench.\n" );
253 return;
254 }
255
256 for (int x = 0; x < width; x += fSubsetWidth) {
257 for (int y = 0; y < height; y += fSubsetHeight) {
258 uint32_t currSubsetWidth = x + (int) fSubsetWidth > width ?
259 width - x : fSubsetWidth;
260 uint32_t currSubsetHeight = y + (int) fSubsetHeight > height ?
261 height - y : fSubsetHeight;
262 SkIRect rect = SkIRect::MakeXYWH(x, y, currSubsetWid th,
263 currSubsetHeight);
264 decoder->decodeSubset(&bitmap, rect, fColorType);
265 }
266 }
267 }
268 }
269 break;
270 case kScale_SubsetMode:
271 if (fUseCodec) {
272 for (int count = 0; count < n; count++) {
273 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(fStream- >duplicate()));
274 const SkImageInfo info = codec->getInfo();
275 SkAutoTDeleteArray<uint8_t> row(SkNEW_ARRAY(uint8_t, info.mi nRowBytes()));
276 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecod er(info);
277
278 int centerX = info.width() / 2;
279 int centerY = info.height() / 2;
280 int w = fSubsetWidth;
281 int h = fSubsetHeight;
282 do {
283 int subsetStartX = SkTMax(0, centerX - w / 2);
284 int subsetStartY = SkTMax(0, centerY - h / 2);
285 int subsetWidth = SkTMin(w, info.width() - subsetStartX) ;
286 int subsetHeight = SkTMin(h, info.height() - subsetStart Y);
287 // Note that if we subseted and scaled in a single step, we could use the
scroggo 2015/05/29 15:36:02 subsetted? (Technically not a verb, but it seems l
msarett 2015/06/01 14:03:25 Done.
288 // same bitmap - as is often done in actual use cases.
289 SkBitmap bitmap;
290 if (!bitmap.tryAllocPixels(info.makeWH(subsetWidth, subs etHeight))) {
291 SkDebugf("Could not allocate memory. Aborting bench .\n");
292 return;
293 }
294
295 uint32_t bpp = info.bytesPerPixel();
296 scanlineDecoder->skipScanlines(subsetStartY);
297 for (int y = 0; y < subsetHeight; y++) {
298 scanlineDecoder->getScanlines(row.get(), 1, 0);
299 memcpy(bitmap.getAddr(0, y), row.get() + subsetStart X * bpp,
300 subsetWidth * bpp);
301 }
302 w <<= 1;
303 h <<= 1;
304 } while (w < 2 * info.width() || h < 2 * info.height());
305 }
306 } else {
307 for (int count = 0; count < n; count++) {
308 int width, height;
309 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factor y(fStream));
310 decoder->buildTileIndex(fStream->duplicate(), &width, &heigh t);
311
312 int centerX = width / 2;
313 int centerY = height / 2;
314 int w = fSubsetWidth;
315 int h = fSubsetHeight;
316 do {
317 int subsetStartX = SkTMax(0, centerX - w / 2);
318 int subsetStartY = SkTMax(0, centerY - h / 2);
319 int subsetWidth = SkTMin(w, width - subsetStartX);
320 int subsetHeight = SkTMin(h, height - subsetStartY);
321 // Note that if we subseted and scaled in a single step, we could use the
322 // same bitmap - as is often done in actual use cases.
323 SkBitmap bitmap;
324 if (!bitmap.tryAllocPixels(SkImageInfo::Make(subsetWidth , subsetHeight,
scroggo 2015/05/29 15:36:03 Again, not needed. There are some cases where a bi
msarett 2015/06/01 14:03:24 Agreed that this allocation is unnecessary here.
325 fColorType, kOpaque_SkAlphaType))) {
326 SkDebugf("Could not allocate memory. Aborting bench .\n");
327 return;
328 }
329
330 SkIRect rect = SkIRect::MakeXYWH(subsetStartX, subsetSta rtY, subsetWidth,
331 subsetHeight);
332 decoder->decodeSubset(&bitmap, rect, fColorType);
333 w <<= 1;
334 h <<= 1;
335 } while (w < 2 * width || h < 2 * height);
336 }
337 }
338 break;
339 }
340 }
OLDNEW
« bench/CodecSubsetBench.h ('K') | « bench/CodecSubsetBench.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698