1 /*
2 * Copyright 2016 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 <memory>
9 #include "Benchmark.h"
10
11 #include "SkArenaAlloc.h"
12 #include "SkBitmapProcShader.h"
13 #include "SkColor.h"
14 #include "SkArenaAlloc.h"
15 #include "SkImage.h"
16 #include "SkLinearBitmapPipeline.h"
17 #include "SkPM4f.h"
18 #include "SkShader.h"
19
20 struct CommonBitmapFPBenchmark : public Benchmark {
CommonBitmapFPBenchmarkCommonBitmapFPBenchmark21 CommonBitmapFPBenchmark(
22 SkISize srcSize,
23 bool isSRGB,
24 SkMatrix m,
25 bool useBilerp,
26 SkShader::TileMode xTile,
27 SkShader::TileMode yTile)
28 : fIsSRGB(isSRGB)
29 , fM{m}
30 , fUseBilerp{useBilerp}
31 , fXTile{xTile}
32 , fYTile{yTile} {
33 fSrcSize = srcSize;
34 }
35
tileNameCommonBitmapFPBenchmark36 static SkString tileName(const char* pre, SkShader::TileMode mode) {
37 SkString name{pre};
38 switch (mode) {
39 case SkShader::kClamp_TileMode:
40 name.append("Clamp");
41 return name;
42 case SkShader::kRepeat_TileMode:
43 name.append("Repeat");
44 return name;
45 case SkShader::kMirror_TileMode:
46 name.append("Mirror");
47 return name;
48 default:
49 name.append("Unknown");
50 return name;
51 }
52 }
53
onGetNameCommonBitmapFPBenchmark54 const char* onGetName() override {
55 fName.set("SkBitmapFP");
56 if (fM.getType() & SkMatrix::kPerspective_Mask) {
57 fName.append("Perspective");
58 } else if (fM.getType() & SkMatrix::kAffine_Mask) {
59 fName.append("Affine");
60 } else if (fM.getType() & SkMatrix::kScale_Mask) {
61 fName.append("Scale");
62 } else if (fM.getType() & SkMatrix::kTranslate_Mask) {
63 fName.append("Translate");
64 } else {
65 fName.append("Identity");
66 }
67
68 fName.append(tileName("X", fXTile));
69 fName.append(tileName("Y", fYTile));
70
71 if (fUseBilerp) {
72 fName.append("Filter");
73 } else {
74 fName.append("Nearest");
75 }
76
77 fName.appendf("%s", BaseName().c_str());
78
79 return fName.c_str();
80 }
81
onPreDrawCommonBitmapFPBenchmark82 void onPreDraw(SkCanvas*) override {
83 int width = fSrcSize.fWidth;
84 int height = fSrcSize.fHeight;
85 fBitmap.reset(new uint32_t[width * height]);
86 for (int y = 0; y < height; y++) {
87 for (int x = 0; x < width; x++) {
88 fBitmap[y * width + x] = (y << 8) + x + (128<<24);
89 }
90 }
91
92 bool trash = fM.invert(&fInvert);
93 sk_ignore_unused_variable(trash);
94
95 fInfo = SkImageInfo::MakeN32Premul(width, height, fIsSRGB ?
96 SkColorSpace::MakeSRGB() : nullptr);
97 }
98
isSuitableForCommonBitmapFPBenchmark99 bool isSuitableFor(Backend backend) override {
100 return backend == kNonRendering_Backend;
101 }
102
103 virtual SkString BaseName() = 0;
104
105 SkString fName;
106 SkISize fSrcSize;
107 bool fIsSRGB;
108 SkMatrix fM;
109 SkMatrix fInvert;
110 bool fUseBilerp;
111 SkShader::TileMode fXTile;
112 SkShader::TileMode fYTile;
113 SkImageInfo fInfo;
114 std::unique_ptr<uint32_t[]> fBitmap;
115 };
116
117 struct SkBitmapFPGeneral final : public CommonBitmapFPBenchmark {
SkBitmapFPGeneralSkBitmapFPGeneral118 SkBitmapFPGeneral(
119 SkISize srcSize,
120 bool isSRGB,
121 SkMatrix m,
122 bool useBilerp,
123 SkShader::TileMode xTile,
124 SkShader::TileMode yTile)
125 : CommonBitmapFPBenchmark(srcSize, isSRGB, m, useBilerp, xTile, yTile) { }
126
BaseNameSkBitmapFPGeneral127 SkString BaseName() override {
128 SkString name;
129 if (fInfo.gammaCloseToSRGB()) {
130 name.set("sRGB");
131 } else {
132 name.set("Linr");
133 }
134 return name;
135 }
136
onDrawSkBitmapFPGeneral137 void onDraw(int loops, SkCanvas*) override {
138 int width = fSrcSize.fWidth;
139 int height = fSrcSize.fHeight;
140
141 SkAutoTMalloc<SkPM4f> FPbuffer(width*height);
142
143 SkFilterQuality filterQuality;
144 if (fUseBilerp) {
145 filterQuality = SkFilterQuality::kLow_SkFilterQuality;
146 } else {
147 filterQuality = SkFilterQuality::kNone_SkFilterQuality;
148 }
149
150 SkPixmap srcPixmap{fInfo, fBitmap.get(), static_cast<size_t>(4 * width)};
151
152
153 char storage[600];
154 SkArenaAlloc allocator{storage, sizeof(storage), 512};
155 SkLinearBitmapPipeline pipeline{
156 fInvert, filterQuality, fXTile, fYTile, SK_ColorBLACK, srcPixmap, &allocator};
157
158 int count = 100;
159
160 for (int n = 0; n < 1000*loops; n++) {
161 pipeline.shadeSpan4f(3, 6, FPbuffer, count);
162 }
163 }
164 };
165
166 struct SkBitmapFPOrigShader : public CommonBitmapFPBenchmark {
SkBitmapFPOrigShaderSkBitmapFPOrigShader167 SkBitmapFPOrigShader(
168 SkISize srcSize,
169 bool isSRGB,
170 SkMatrix m,
171 bool useBilerp,
172 SkShader::TileMode xTile,
173 SkShader::TileMode yTile)
174 : CommonBitmapFPBenchmark(srcSize, isSRGB, m, useBilerp, xTile, yTile) { }
175
BaseNameSkBitmapFPOrigShader176 SkString BaseName() override {
177 SkString name{"Orig"};
178 return name;
179 }
180
onPreDrawSkBitmapFPOrigShader181 void onPreDraw(SkCanvas* c) override {
182 CommonBitmapFPBenchmark::onPreDraw(c);
183
184 fImage = SkImage::MakeRasterCopy(
185 SkPixmap(fInfo, fBitmap.get(), sizeof(SkPMColor) * fSrcSize.fWidth));
186 fPaint.setShader(fImage->makeShader(fXTile, fYTile));
187 if (fUseBilerp) {
188 fPaint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
189 } else {
190 fPaint.setFilterQuality(SkFilterQuality::kNone_SkFilterQuality);
191 }
192 }
193
onPostDrawSkBitmapFPOrigShader194 void onPostDraw(SkCanvas*) override {
195
196 }
197
onDrawSkBitmapFPOrigShader198 void onDraw(int loops, SkCanvas*) override {
199 int width = fSrcSize.fWidth;
200 int height = fSrcSize.fHeight;
201
202 SkAutoTMalloc<SkPMColor> buffer4b(width*height);
203
204 SkArenaAlloc alloc{0};
205 const SkShader::ContextRec rec(fPaint, fM, nullptr,
206 SkShader::ContextRec::kPMColor_DstType,
207 nullptr);
208 SkShader::Context* ctx = fPaint.getShader()->makeContext(rec, &alloc);
209
210 int count = 100;
211
212 for (int n = 0; n < 1000*loops; n++) {
213 ctx->shadeSpan(3, 6, buffer4b, count);
214 }
215 }
216 SkPaint fPaint;
217 sk_sp<SkImage> fImage;
218 };
219
220 const bool gSRGB = true;
221 const bool gLinearRGB = false;
222 static SkISize srcSize = SkISize::Make(120, 100);
223 static SkMatrix mI = SkMatrix::I();
224 DEF_BENCH(return new SkBitmapFPGeneral(
225 srcSize, gSRGB, mI, false,
226 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
227
228 DEF_BENCH(return new SkBitmapFPGeneral(
229 srcSize, gLinearRGB, mI, false,
230 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
231
232 DEF_BENCH(return new SkBitmapFPOrigShader(
233 srcSize, gLinearRGB, mI, false,
234 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
235
236 DEF_BENCH(return new SkBitmapFPGeneral(
237 srcSize, gSRGB, mI, true,
238 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
239
240 DEF_BENCH(return new SkBitmapFPGeneral(
241 srcSize, gLinearRGB, mI, true,
242 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
243
244 DEF_BENCH(return new SkBitmapFPOrigShader(
245 srcSize, gLinearRGB, mI, true,
246 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
247
248 static SkMatrix mS = SkMatrix::MakeScale(2.7f, 2.7f);
249 DEF_BENCH(return new SkBitmapFPGeneral(
250 srcSize, gSRGB, mS, false,
251 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
252
DEF_BENCH(return new SkBitmapFPGeneral (srcSize,gLinearRGB,mS,false,SkShader::kClamp_TileMode,SkShader::kClamp_TileMode);)253 DEF_BENCH(return new SkBitmapFPGeneral(
254 srcSize, gLinearRGB, mS, false,
255 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
256
257 DEF_BENCH(return new SkBitmapFPOrigShader(
258 srcSize, gLinearRGB, mS, false,
259 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
260
261 DEF_BENCH(return new SkBitmapFPGeneral(
262 srcSize, gSRGB, mS, true,
263 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
264
265 DEF_BENCH(return new SkBitmapFPGeneral(
266 srcSize, gLinearRGB, mS, true,
267 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
268
269 DEF_BENCH(return new SkBitmapFPOrigShader(
270 srcSize, gLinearRGB, mS, true,
271 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
272
273 // Repeat
274 DEF_BENCH(return new SkBitmapFPGeneral(
275 srcSize, gSRGB, mS, false,
276 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
277
278 DEF_BENCH(return new SkBitmapFPGeneral(
279 srcSize, gLinearRGB, mS, false,
280 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
281
282 DEF_BENCH(return new SkBitmapFPOrigShader(
283 srcSize, gLinearRGB, mS, false,
284 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
285
286 DEF_BENCH(return new SkBitmapFPGeneral(
287 srcSize, gSRGB, mS, true,
288 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
289
290 DEF_BENCH(return new SkBitmapFPGeneral(
291 srcSize, gLinearRGB, mS, true,
292 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
293
294 DEF_BENCH(return new SkBitmapFPOrigShader(
295 srcSize, gLinearRGB, mS, true,
296 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
297
298 static SkMatrix rotate(SkScalar r) {
299 SkMatrix m;
300 m.setRotate(30);
301 return m;
302 }
303
304 static SkMatrix mR = rotate(30);
305 DEF_BENCH(return new SkBitmapFPGeneral(
306 srcSize, gSRGB, mR, false,
307 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
308
309 DEF_BENCH(return new SkBitmapFPGeneral(
310 srcSize, gLinearRGB, mR, false,
311 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
312
313 DEF_BENCH(return new SkBitmapFPOrigShader(
314 srcSize, gLinearRGB, mR, false,
315 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
316
317 DEF_BENCH(return new SkBitmapFPGeneral(
318 srcSize, gSRGB, mR, true,
319 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
320
321 DEF_BENCH(return new SkBitmapFPGeneral(
322 srcSize, gLinearRGB, mR, true,
323 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
324
325 DEF_BENCH(return new SkBitmapFPOrigShader(
326 srcSize, gLinearRGB, mR, true,
327 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
328
329 // Repeat
330 DEF_BENCH(return new SkBitmapFPGeneral(
331 srcSize, gSRGB, mR, false,
332 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
333
334 DEF_BENCH(return new SkBitmapFPGeneral(
335 srcSize, gLinearRGB, mR, false,
336 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
337
338 DEF_BENCH(return new SkBitmapFPOrigShader(
339 srcSize, gLinearRGB, mR, false,
340 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
341
342 DEF_BENCH(return new SkBitmapFPGeneral(
343 srcSize, gSRGB, mR, true,
344 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
345
346 DEF_BENCH(return new SkBitmapFPGeneral(
347 srcSize, gLinearRGB, mR, true,
348 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
349
350 DEF_BENCH(return new SkBitmapFPOrigShader(
351 srcSize, gLinearRGB, mR, true,
352 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
353