blob: 8c44fa85110051a9f0e70c183b5d73c9c63e987e [file] [log] [blame]
herbfeec8782016-02-17 10:00:07 -08001/*
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 "SkColor.h"
10#include "SkLinearBitmapPipeline.h"
reeddd9ffea2016-02-18 12:39:14 -080011#include "SkPM4f.h"
herbfeec8782016-02-17 10:00:07 -080012#include "Benchmark.h"
13#include "SkShader.h"
14#include "SkImage.h"
15
16struct CommonBitmapFPBenchmark : public Benchmark {
17 CommonBitmapFPBenchmark(
18 SkISize srcSize,
19 SkColorProfileType colorProfile,
20 SkMatrix m,
21 bool useBilerp,
22 SkShader::TileMode xTile,
23 SkShader::TileMode yTile)
24 : fColorProfile(colorProfile)
25 , fM{m}
26 , fUseBilerp{useBilerp}
27 , fXTile{xTile}
28 , fYTile{yTile} {
29 fSrcSize = srcSize;
30 }
31
32 static SkString tileName(const char* pre, SkShader::TileMode mode) {
33 SkString name{pre};
34 switch (mode) {
35 case SkShader::kClamp_TileMode:
36 name.append("Clamp");
37 return name;
38 case SkShader::kRepeat_TileMode:
39 name.append("Repeat");
40 return name;
41 case SkShader::kMirror_TileMode:
42 name.append("Mirror");
43 return name;
44 default:
45 name.append("Unknown");
46 return name;
47 }
48 }
49
50 const char* onGetName() override {
herb134ad3e2016-02-17 11:57:24 -080051 fName.set("SkBitmapFP");
herbfeec8782016-02-17 10:00:07 -080052 if (fM.getType() & SkMatrix::kPerspective_Mask) {
herb134ad3e2016-02-17 11:57:24 -080053 fName.append("Perspective");
herbfeec8782016-02-17 10:00:07 -080054 } else if (fM.getType() & SkMatrix::kAffine_Mask) {
herb134ad3e2016-02-17 11:57:24 -080055 fName.append("Affine");
herbfeec8782016-02-17 10:00:07 -080056 } else if (fM.getType() & SkMatrix::kScale_Mask) {
herb134ad3e2016-02-17 11:57:24 -080057 fName.append("Scale");
herbfeec8782016-02-17 10:00:07 -080058 } else if (fM.getType() & SkMatrix::kTranslate_Mask) {
herb134ad3e2016-02-17 11:57:24 -080059 fName.append("Translate");
herbfeec8782016-02-17 10:00:07 -080060 } else {
herb134ad3e2016-02-17 11:57:24 -080061 fName.append("Identity");
herbfeec8782016-02-17 10:00:07 -080062 }
63
herb134ad3e2016-02-17 11:57:24 -080064 fName.append(tileName("X", fXTile));
65 fName.append(tileName("Y", fYTile));
herbfeec8782016-02-17 10:00:07 -080066
67 if (fUseBilerp) {
herb134ad3e2016-02-17 11:57:24 -080068 fName.append("Filter");
herbfeec8782016-02-17 10:00:07 -080069 } else {
herb134ad3e2016-02-17 11:57:24 -080070 fName.append("Nearest");
herbfeec8782016-02-17 10:00:07 -080071 }
72
herb134ad3e2016-02-17 11:57:24 -080073 fName.appendf("%s", BaseName().c_str());
herbfeec8782016-02-17 10:00:07 -080074
herb134ad3e2016-02-17 11:57:24 -080075 return fName.c_str();
herbfeec8782016-02-17 10:00:07 -080076 }
77
78 void onPreDraw(SkCanvas*) override {
79 int width = fSrcSize.fWidth;
80 int height = fSrcSize.fHeight;
81 fBitmap.reset(new uint32_t[width * height]);
82 for (int y = 0; y < height; y++) {
83 for (int x = 0; x < width; x++) {
84 fBitmap[y * width + x] = (y << 8) + x + (128<<24);
85 }
86 }
87
88 bool trash = fM.invert(&fInvert);
89 sk_ignore_unused_variable(trash);
90
91 fInfo = SkImageInfo::MakeN32Premul(width, height, fColorProfile);
92 }
93
94 bool isSuitableFor(Backend backend) override {
95 return backend == kNonRendering_Backend;
96 }
97
98 virtual SkString BaseName() = 0;
99
herb134ad3e2016-02-17 11:57:24 -0800100 SkString fName;
herbfeec8782016-02-17 10:00:07 -0800101 SkISize fSrcSize;
102 SkColorProfileType fColorProfile;
103 SkMatrix fM;
104 SkMatrix fInvert;
105 bool fUseBilerp;
106 SkShader::TileMode fXTile;
107 SkShader::TileMode fYTile;
108 SkImageInfo fInfo;
109 std::unique_ptr<uint32_t[]> fBitmap;
110};
111
112struct SkBitmapFPGeneral final : public CommonBitmapFPBenchmark {
113 SkBitmapFPGeneral(
114 SkISize srcSize,
115 SkColorProfileType colorProfile,
116 SkMatrix m,
117 bool useBilerp,
118 SkShader::TileMode xTile,
119 SkShader::TileMode yTile)
120 : CommonBitmapFPBenchmark(srcSize, colorProfile, m, useBilerp, xTile, yTile) { }
herb134ad3e2016-02-17 11:57:24 -0800121
herbfeec8782016-02-17 10:00:07 -0800122 SkString BaseName() override {
123 SkString name;
124 if (fInfo.isSRGB()) {
125 name.set("sRGB");
126 } else {
127 name.set("Linr");
128 }
129 return name;
130 }
131
132 void onDraw(int loops, SkCanvas*) override {
133 int width = fSrcSize.fWidth;
134 int height = fSrcSize.fHeight;
135
mtkleinb65fcd42016-02-17 13:50:46 -0800136 SkAutoTMalloc<SkPM4f> FPbuffer(width*height);
herbfeec8782016-02-17 10:00:07 -0800137
herbc5eddd72016-02-17 19:50:05 -0800138 SkFilterQuality filterQuality;
139 if (fUseBilerp) {
140 filterQuality = SkFilterQuality::kLow_SkFilterQuality;
141 } else {
142 filterQuality = SkFilterQuality::kNone_SkFilterQuality;
143 }
144
herbed545042016-02-18 13:55:02 -0800145 SkPixmap srcPixmap{fInfo, fBitmap.get(), static_cast<size_t>(4 * width)};
146
herbc5eddd72016-02-17 19:50:05 -0800147 SkLinearBitmapPipeline pipeline{
herbed545042016-02-18 13:55:02 -0800148 fInvert, filterQuality, fXTile, fYTile, srcPixmap};
herbfeec8782016-02-17 10:00:07 -0800149
150 int count = 100;
151
152 for (int n = 0; n < 1000*loops; n++) {
153 pipeline.shadeSpan4f(3, 6, FPbuffer, count);
154 }
herbfeec8782016-02-17 10:00:07 -0800155 }
156};
157
158struct SkBitmapFPOrigShader : public CommonBitmapFPBenchmark {
159 SkBitmapFPOrigShader(
160 SkISize srcSize,
161 SkColorProfileType colorProfile,
162 SkMatrix m,
163 bool useBilerp,
164 SkShader::TileMode xTile,
165 SkShader::TileMode yTile)
166 : CommonBitmapFPBenchmark(srcSize, colorProfile, m, useBilerp, xTile, yTile) { }
herb134ad3e2016-02-17 11:57:24 -0800167
herbfeec8782016-02-17 10:00:07 -0800168 SkString BaseName() override {
169 SkString name{"Orig"};
170 return name;
171 }
172
173 void onPreDraw(SkCanvas* c) override {
174 CommonBitmapFPBenchmark::onPreDraw(c);
175
176 SkImage* image = SkImage::NewRasterCopy(
177 fInfo, fBitmap.get(), sizeof(SkPMColor) * fSrcSize.fWidth);
178 fImage.reset(image);
179 SkShader* shader = fImage->newShader(fXTile, fYTile);
180 if (fUseBilerp) {
181 fPaint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
182 } else {
183 fPaint.setFilterQuality(SkFilterQuality::kNone_SkFilterQuality);
184 }
185 fPaint.setShader(shader)->unref();
herbfeec8782016-02-17 10:00:07 -0800186 }
187
188 void onPostDraw(SkCanvas*) override {
189
190 }
191
192 void onDraw(int loops, SkCanvas*) override {
193 int width = fSrcSize.fWidth;
194 int height = fSrcSize.fHeight;
195
mtkleinb65fcd42016-02-17 13:50:46 -0800196 SkAutoTMalloc<SkPMColor> buffer4b(width*height);
herbfeec8782016-02-17 10:00:07 -0800197
198 uint32_t storage[200];
fmalitad0c4e092016-02-22 17:19:04 -0800199 const SkShader::ContextRec rec(fPaint, fM, nullptr,
200 SkShader::ContextRec::kPMColor_DstType);
fmalita8d9f2e42016-02-22 10:39:41 -0800201 SkASSERT(fPaint.getShader()->contextSize(rec) <= sizeof(storage));
202 SkShader::Context* ctx = fPaint.getShader()->createContext(rec, storage);
herbfeec8782016-02-17 10:00:07 -0800203
204 int count = 100;
205
206 for (int n = 0; n < 1000*loops; n++) {
207 ctx->shadeSpan(3, 6, buffer4b, count);
208 }
209
210 ctx->~Context();
herbfeec8782016-02-17 10:00:07 -0800211 }
212 SkPaint fPaint;
213 SkAutoTUnref<SkImage> fImage;
214};
215
216static SkISize srcSize = SkISize::Make(120, 100);
217static SkMatrix mI = SkMatrix::I();
218DEF_BENCH(return new SkBitmapFPGeneral(
219 srcSize, kSRGB_SkColorProfileType, mI, false,
220 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
221
222DEF_BENCH(return new SkBitmapFPGeneral(
223 srcSize, kLinear_SkColorProfileType, mI, false,
224 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
225
226DEF_BENCH(return new SkBitmapFPOrigShader(
227 srcSize, kLinear_SkColorProfileType, mI, false,
228 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
229
230DEF_BENCH(return new SkBitmapFPGeneral(
231 srcSize, kSRGB_SkColorProfileType, mI, true,
232 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
233
234DEF_BENCH(return new SkBitmapFPGeneral(
235 srcSize, kLinear_SkColorProfileType, mI, true,
236 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
237
238DEF_BENCH(return new SkBitmapFPOrigShader(
239 srcSize, kLinear_SkColorProfileType, mI, true,
240 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
241
242static SkMatrix mS = SkMatrix::MakeScale(2.7f, 2.7f);
243DEF_BENCH(return new SkBitmapFPGeneral(
244 srcSize, kSRGB_SkColorProfileType, mS, false,
245 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
246
247DEF_BENCH(return new SkBitmapFPGeneral(
248 srcSize, kLinear_SkColorProfileType, mS, false,
249 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
250
251DEF_BENCH(return new SkBitmapFPOrigShader(
252 srcSize, kLinear_SkColorProfileType, mS, false,
253 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
254
255DEF_BENCH(return new SkBitmapFPGeneral(
256 srcSize, kSRGB_SkColorProfileType, mS, true,
257 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
258
259DEF_BENCH(return new SkBitmapFPGeneral(
260 srcSize, kLinear_SkColorProfileType, mS, true,
261 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
262
263DEF_BENCH(return new SkBitmapFPOrigShader(
264 srcSize, kLinear_SkColorProfileType, mS, true,
265 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
266
267static SkMatrix rotate(SkScalar r) {
268 SkMatrix m;
269 m.setRotate(30);
270 return m;
271}
272
273static SkMatrix mR = rotate(30);
274DEF_BENCH(return new SkBitmapFPGeneral(
275 srcSize, kSRGB_SkColorProfileType, mR, false,
276 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
277
278DEF_BENCH(return new SkBitmapFPGeneral(
279 srcSize, kLinear_SkColorProfileType, mR, false,
280 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
281
282DEF_BENCH(return new SkBitmapFPOrigShader(
283 srcSize, kLinear_SkColorProfileType, mR, false,
284 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
285
286DEF_BENCH(return new SkBitmapFPGeneral(
287 srcSize, kSRGB_SkColorProfileType, mR, true,
288 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
289
290DEF_BENCH(return new SkBitmapFPGeneral(
291 srcSize, kLinear_SkColorProfileType, mR, true,
292 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
293
294DEF_BENCH(return new SkBitmapFPOrigShader(
295 srcSize, kLinear_SkColorProfileType, mR, true,
296 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)
297