OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "Benchmark.h" | 8 #include "Benchmark.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
11 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
12 #include "SkGradientShader.h" | 12 #include "SkGradientShader.h" |
| 13 #include "SkLinearGradient.h" |
13 #include "SkPaint.h" | 14 #include "SkPaint.h" |
14 #include "SkShader.h" | 15 #include "SkShader.h" |
15 #include "SkString.h" | 16 #include "SkString.h" |
16 | 17 |
17 struct GradData { | 18 struct GradData { |
18 int fCount; | 19 int fCount; |
19 const SkColor* fColors; | 20 const SkColor* fColors; |
20 const SkScalar* fPos; | 21 const SkScalar* fPos; |
21 const char* fName; | 22 const char* fName; |
22 }; | 23 }; |
(...skipping 17 matching lines...) Expand all Loading... |
40 // try to exercise those here. | 41 // try to exercise those here. |
41 static const GradData gGradData[] = { | 42 static const GradData gGradData[] = { |
42 { 2, gColors, nullptr, "" }, | 43 { 2, gColors, nullptr, "" }, |
43 { 50, gColors, nullptr, "_hicolor" }, // many color gradient | 44 { 50, gColors, nullptr, "_hicolor" }, // many color gradient |
44 { 3, gColors, nullptr, "_3color" }, | 45 { 3, gColors, nullptr, "_3color" }, |
45 { 2, gShallowColors, nullptr, "_shallow" }, | 46 { 2, gShallowColors, nullptr, "_shallow" }, |
46 }; | 47 }; |
47 | 48 |
48 /// Ignores scale | 49 /// Ignores scale |
49 static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, | 50 static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data, |
50 SkShader::TileMode tm, float scale) { | 51 SkShader::TileMode tm, float scale, bool force4f) { |
51 return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, data.fCo
unt, tm); | 52 const uint32_t flags = force4f ? SkLinearGradient::kForce4fContext_PrivateFl
ag : 0; |
| 53 return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos, |
| 54 data.fCount, tm, flags, nullptr); |
52 } | 55 } |
53 | 56 |
54 static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, | 57 static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data, |
55 SkShader::TileMode tm, float scale) { | 58 SkShader::TileMode tm, float scale, bool force4f) { |
56 SkPoint center; | 59 SkPoint center; |
57 center.set(SkScalarAve(pts[0].fX, pts[1].fX), | 60 center.set(SkScalarAve(pts[0].fX, pts[1].fX), |
58 SkScalarAve(pts[0].fY, pts[1].fY)); | 61 SkScalarAve(pts[0].fY, pts[1].fY)); |
59 return SkGradientShader::CreateRadial(center, center.fX * scale, | 62 return SkGradientShader::CreateRadial(center, center.fX * scale, |
60 data.fColors, | 63 data.fColors, |
61 data.fPos, data.fCount, tm); | 64 data.fPos, data.fCount, tm); |
62 } | 65 } |
63 | 66 |
64 /// Ignores scale | 67 /// Ignores scale |
65 static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, | 68 static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data, |
66 SkShader::TileMode tm, float scale) { | 69 SkShader::TileMode tm, float scale, bool force4f) { |
67 SkPoint center; | 70 SkPoint center; |
68 center.set(SkScalarAve(pts[0].fX, pts[1].fX), | 71 center.set(SkScalarAve(pts[0].fX, pts[1].fX), |
69 SkScalarAve(pts[0].fY, pts[1].fY)); | 72 SkScalarAve(pts[0].fY, pts[1].fY)); |
70 return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, | 73 return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors, |
71 data.fPos, data.fCount); | 74 data.fPos, data.fCount); |
72 } | 75 } |
73 | 76 |
74 /// Ignores scale | 77 /// Ignores scale |
75 static SkShader* MakeConical(const SkPoint pts[2], const GradData& data, | 78 static SkShader* MakeConical(const SkPoint pts[2], const GradData& data, |
76 SkShader::TileMode tm, float scale) { | 79 SkShader::TileMode tm, float scale, bool force4f) { |
77 SkPoint center0, center1; | 80 SkPoint center0, center1; |
78 center0.set(SkScalarAve(pts[0].fX, pts[1].fX), | 81 center0.set(SkScalarAve(pts[0].fX, pts[1].fX), |
79 SkScalarAve(pts[0].fY, pts[1].fY)); | 82 SkScalarAve(pts[0].fY, pts[1].fY)); |
80 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), | 83 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), |
81 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); | 84 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); |
82 return SkGradientShader::CreateTwoPointConical(center1, (pts[1].fX - pts[0].
fX) / 7, | 85 return SkGradientShader::CreateTwoPointConical(center1, (pts[1].fX - pts[0].
fX) / 7, |
83 center0, (pts[1].fX - pts[0].
fX) / 2, | 86 center0, (pts[1].fX - pts[0].
fX) / 2, |
84 data.fColors, data.fPos, data
.fCount, tm); | 87 data.fColors, data.fPos, data
.fCount, tm); |
85 } | 88 } |
86 | 89 |
87 /// Ignores scale | 90 /// Ignores scale |
88 static SkShader* MakeConicalZeroRad(const SkPoint pts[2], const GradData& data, | 91 static SkShader* MakeConicalZeroRad(const SkPoint pts[2], const GradData& data, |
89 SkShader::TileMode tm, float scale) { | 92 SkShader::TileMode tm, float scale, bool for
ce4f) { |
90 SkPoint center0, center1; | 93 SkPoint center0, center1; |
91 center0.set(SkScalarAve(pts[0].fX, pts[1].fX), | 94 center0.set(SkScalarAve(pts[0].fX, pts[1].fX), |
92 SkScalarAve(pts[0].fY, pts[1].fY)); | 95 SkScalarAve(pts[0].fY, pts[1].fY)); |
93 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), | 96 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), |
94 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); | 97 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); |
95 return SkGradientShader::CreateTwoPointConical(center1, 0.0, | 98 return SkGradientShader::CreateTwoPointConical(center1, 0.0, |
96 center0, (pts[1].fX - pts[0].
fX) / 2, | 99 center0, (pts[1].fX - pts[0].
fX) / 2, |
97 data.fColors, data.fPos, data
.fCount, tm); | 100 data.fColors, data.fPos, data
.fCount, tm); |
98 } | 101 } |
99 | 102 |
100 /// Ignores scale | 103 /// Ignores scale |
101 static SkShader* MakeConicalOutside(const SkPoint pts[2], const GradData& data, | 104 static SkShader* MakeConicalOutside(const SkPoint pts[2], const GradData& data, |
102 SkShader::TileMode tm, float scale) { | 105 SkShader::TileMode tm, float scale, bool for
ce4f) { |
103 SkPoint center0, center1; | 106 SkPoint center0, center1; |
104 SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10; | 107 SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10; |
105 SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3; | 108 SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3; |
106 center0.set(pts[0].fX + radius0, pts[0].fY + radius0); | 109 center0.set(pts[0].fX + radius0, pts[0].fY + radius0); |
107 center1.set(pts[1].fX - radius1, pts[1].fY - radius1); | 110 center1.set(pts[1].fX - radius1, pts[1].fY - radius1); |
108 return SkGradientShader::CreateTwoPointConical(center0, radius0, | 111 return SkGradientShader::CreateTwoPointConical(center0, radius0, |
109 center1, radius1, | 112 center1, radius1, |
110 data.fColors, data.fPos, | 113 data.fColors, data.fPos, |
111 data.fCount, tm); | 114 data.fCount, tm); |
112 } | 115 } |
113 | 116 |
114 /// Ignores scale | 117 /// Ignores scale |
115 static SkShader* MakeConicalOutsideZeroRad(const SkPoint pts[2], const GradData&
data, | 118 static SkShader* MakeConicalOutsideZeroRad(const SkPoint pts[2], const GradData&
data, |
116 SkShader::TileMode tm, float scale) { | 119 SkShader::TileMode tm, float scale, b
ool force4f) { |
117 SkPoint center0, center1; | 120 SkPoint center0, center1; |
118 SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10; | 121 SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10; |
119 SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3; | 122 SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3; |
120 center0.set(pts[0].fX + radius0, pts[0].fY + radius0); | 123 center0.set(pts[0].fX + radius0, pts[0].fY + radius0); |
121 center1.set(pts[1].fX - radius1, pts[1].fY - radius1); | 124 center1.set(pts[1].fX - radius1, pts[1].fY - radius1); |
122 return SkGradientShader::CreateTwoPointConical(center0, 0.0, | 125 return SkGradientShader::CreateTwoPointConical(center0, 0.0, |
123 center1, radius1, | 126 center1, radius1, |
124 data.fColors, data.fPos, | 127 data.fColors, data.fPos, |
125 data.fCount, tm); | 128 data.fCount, tm); |
126 } | 129 } |
127 | 130 |
128 typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, | 131 typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data, |
129 SkShader::TileMode tm, float scale); | 132 SkShader::TileMode tm, float scale, bool force4f)
; |
130 | 133 |
131 static const struct { | 134 static const struct { |
132 GradMaker fMaker; | 135 GradMaker fMaker; |
133 const char* fName; | 136 const char* fName; |
134 } gGrads[] = { | 137 } gGrads[] = { |
135 { MakeLinear, "linear" }, | 138 { MakeLinear, "linear" }, |
136 { MakeRadial, "radial1" }, | 139 { MakeRadial, "radial1" }, |
137 { MakeSweep, "sweep" }, | 140 { MakeSweep, "sweep" }, |
138 { MakeConical, "conical" }, | 141 { MakeConical, "conical" }, |
139 { MakeConicalZeroRad, "conicalZero" }, | 142 { MakeConicalZeroRad, "conicalZero" }, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 return "oval"; | 181 return "oval"; |
179 default: | 182 default: |
180 SkDEBUGFAIL("unknown geometry type"); | 183 SkDEBUGFAIL("unknown geometry type"); |
181 return "error"; | 184 return "error"; |
182 } | 185 } |
183 } | 186 } |
184 | 187 |
185 /////////////////////////////////////////////////////////////////////////////// | 188 /////////////////////////////////////////////////////////////////////////////// |
186 | 189 |
187 class GradientBench : public Benchmark { | 190 class GradientBench : public Benchmark { |
188 SkString fName; | |
189 SkShader* fShader; | |
190 bool fDither; | |
191 enum { | |
192 W = 400, | |
193 H = 400, | |
194 }; | |
195 public: | 191 public: |
196 SkShader* makeShader(GradType gradType, GradData data, SkShader::TileMode tm
, float scale) { | |
197 const SkPoint pts[2] = { | |
198 { 0, 0 }, | |
199 { SkIntToScalar(W), SkIntToScalar(H) } | |
200 }; | |
201 | |
202 return gGrads[gradType].fMaker(pts, data, tm, scale); | |
203 } | |
204 | |
205 GradientBench(GradType gradType, | 192 GradientBench(GradType gradType, |
206 GradData data = gGradData[0], | 193 GradData data = gGradData[0], |
207 SkShader::TileMode tm = SkShader::kClamp_TileMode, | 194 SkShader::TileMode tm = SkShader::kClamp_TileMode, |
208 GeomType geomType = kRect_GeomType, | 195 GeomType geomType = kRect_GeomType, |
209 float scale = 1.0f) { | 196 float scale = 1.0f, |
| 197 bool force4f = false) |
| 198 : fGeomType(geomType) { |
| 199 |
210 fName.printf("gradient_%s_%s", gGrads[gradType].fName, | 200 fName.printf("gradient_%s_%s", gGrads[gradType].fName, |
211 tilemodename(tm)); | 201 tilemodename(tm)); |
212 if (geomType != kRect_GeomType) { | 202 if (geomType != kRect_GeomType) { |
213 fName.append("_"); | 203 fName.appendf("_%s", geomtypename(geomType)); |
214 fName.append(geomtypename(geomType)); | |
215 } | 204 } |
216 | 205 |
217 if (scale != 1.f) { | 206 if (scale != 1.f) { |
218 fName.appendf("_scale_%g", scale); | 207 fName.appendf("_scale_%g", scale); |
219 } | 208 } |
220 | 209 |
221 fName.append(data.fName); | 210 fName.append(data.fName); |
222 | 211 |
223 fDither = false; | 212 if (force4f) { |
224 fShader = this->makeShader(gradType, data, tm, scale); | 213 fName.append("_4f"); |
225 fGeomType = geomType; | 214 } |
| 215 |
| 216 SkAutoTUnref<SkShader> shader(MakeShader(gradType, data, tm, scale, forc
e4f)); |
| 217 this->setupPaint(&fPaint); |
| 218 fPaint.setShader(shader); |
226 } | 219 } |
227 | 220 |
228 GradientBench(GradType gradType, GradData data, bool dither) { | 221 GradientBench(GradType gradType, GradData data, bool dither, bool force4f =
false) |
| 222 : fGeomType(kRect_GeomType) { |
| 223 |
229 const char *tmname = tilemodename(SkShader::kClamp_TileMode); | 224 const char *tmname = tilemodename(SkShader::kClamp_TileMode); |
230 fName.printf("gradient_%s_%s", gGrads[gradType].fName, tmname); | 225 fName.printf("gradient_%s_%s", gGrads[gradType].fName, tmname); |
231 fName.append(data.fName); | 226 fName.append(data.fName); |
232 | 227 |
233 fDither = dither; | |
234 if (dither) { | 228 if (dither) { |
235 fName.appendf("_dither"); | 229 fName.appendf("_dither"); |
236 } | 230 } |
237 | 231 |
238 fShader = this->makeShader(gradType, data, SkShader::kClamp_TileMode, 1.
0f); | 232 SkAutoTUnref<SkShader> shader( |
239 fGeomType = kRect_GeomType; | 233 MakeShader(gradType, data, SkShader::kClamp_TileMode, 1.0f, force4f)
); |
240 } | 234 this->setupPaint(&fPaint); |
241 | 235 fPaint.setShader(shader); |
242 virtual ~GradientBench() { | 236 fPaint.setDither(dither); |
243 fShader->unref(); | |
244 } | 237 } |
245 | 238 |
246 protected: | 239 protected: |
247 virtual const char* onGetName() { | 240 const char* onGetName() override { |
248 return fName.c_str(); | 241 return fName.c_str(); |
249 } | 242 } |
250 | 243 |
251 virtual void onDraw(int loops, SkCanvas* canvas) { | 244 SkIPoint onGetSize() override { |
252 SkPaint paint; | 245 return SkIPoint::Make(kSize, kSize); |
253 this->setupPaint(&paint); | 246 } |
254 | 247 |
255 paint.setShader(fShader); | 248 void onDraw(int loops, SkCanvas* canvas) override { |
256 if (fDither) { | 249 const SkRect r = SkRect::MakeIWH(kSize, kSize); |
257 paint.setDither(true); | |
258 } | |
259 | 250 |
260 SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) }; | |
261 for (int i = 0; i < loops; i++) { | 251 for (int i = 0; i < loops; i++) { |
262 switch (fGeomType) { | 252 switch (fGeomType) { |
263 case kRect_GeomType: | 253 case kRect_GeomType: |
264 canvas->drawRect(r, paint); | 254 canvas->drawRect(r, fPaint); |
265 break; | 255 break; |
266 case kOval_GeomType: | 256 case kOval_GeomType: |
267 canvas->drawOval(r, paint); | 257 canvas->drawOval(r, fPaint); |
268 break; | 258 break; |
269 } | 259 } |
270 } | 260 } |
271 } | 261 } |
272 | 262 |
273 private: | 263 private: |
274 typedef Benchmark INHERITED; | 264 typedef Benchmark INHERITED; |
275 | 265 |
276 GeomType fGeomType; | 266 SkShader* MakeShader(GradType gradType, GradData data, |
| 267 SkShader::TileMode tm, float scale, bool force4f) { |
| 268 const SkPoint pts[2] = { |
| 269 { 0, 0 }, |
| 270 { SkIntToScalar(kSize), SkIntToScalar(kSize) } |
| 271 }; |
| 272 |
| 273 return gGrads[gradType].fMaker(pts, data, tm, scale, force4f); |
| 274 } |
| 275 |
| 276 static const int kSize = 400; |
| 277 |
| 278 SkString fName; |
| 279 SkPaint fPaint; |
| 280 const GeomType fGeomType; |
277 }; | 281 }; |
278 | 282 |
279 DEF_BENCH( return new GradientBench(kLinear_GradType); ) | 283 // 4f |
| 284 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kC
lamp_TileMode, |
| 285 kRect_GeomType, 1, true); ) |
| 286 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kC
lamp_TileMode, |
| 287 kRect_GeomType, 1, true); ) |
| 288 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kC
lamp_TileMode, |
| 289 kRect_GeomType, 1, true); ) |
| 290 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kR
epeat_TileMode, |
| 291 kRect_GeomType, 1, true); ) |
| 292 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kR
epeat_TileMode, |
| 293 kRect_GeomType, 1, true); ) |
| 294 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kR
epeat_TileMode, |
| 295 kRect_GeomType, 1, true); ) |
| 296 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kM
irror_TileMode, |
| 297 kRect_GeomType, 1, true); ) |
| 298 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kM
irror_TileMode, |
| 299 kRect_GeomType, 1, true); ) |
| 300 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kM
irror_TileMode, |
| 301 kRect_GeomType, 1, true); ) |
| 302 |
| 303 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0]); ) |
280 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1]); ) | 304 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1]); ) |
281 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2]); ) | 305 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2]); ) |
| 306 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kR
epeat_TileMode); ) |
| 307 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kR
epeat_TileMode); ) |
| 308 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kR
epeat_TileMode); ) |
282 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kM
irror_TileMode); ) | 309 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkShader::kM
irror_TileMode); ) |
| 310 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkShader::kM
irror_TileMode); ) |
| 311 DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkShader::kM
irror_TileMode); ) |
283 | 312 |
284 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0]); ) | 313 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0]); ) |
285 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[1]); ) | 314 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[1]); ) |
286 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[2]); ) | 315 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[2]); ) |
287 // Draw a radial gradient of radius 1/2 on a rectangle; half the lines should | 316 // Draw a radial gradient of radius 1/2 on a rectangle; half the lines should |
288 // be completely pinned, the other half should pe partially pinned | 317 // be completely pinned, the other half should pe partially pinned |
289 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kC
lamp_TileMode, kRect_GeomType, 0.5f); ) | 318 DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kC
lamp_TileMode, kRect_GeomType, 0.5f); ) |
290 | 319 |
291 // Draw a radial gradient on a circle of equal size; all the lines should | 320 // Draw a radial gradient on a circle of equal size; all the lines should |
292 // hit the unpinned fast path (so long as GradientBench.W == H) | 321 // hit the unpinned fast path (so long as GradientBench.W == H) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 canvas->drawRect(r, paint); | 390 canvas->drawRect(r, paint); |
362 } | 391 } |
363 } | 392 } |
364 | 393 |
365 private: | 394 private: |
366 typedef Benchmark INHERITED; | 395 typedef Benchmark INHERITED; |
367 }; | 396 }; |
368 | 397 |
369 DEF_BENCH( return new Gradient2Bench(false); ) | 398 DEF_BENCH( return new Gradient2Bench(false); ) |
370 DEF_BENCH( return new Gradient2Bench(true); ) | 399 DEF_BENCH( return new Gradient2Bench(true); ) |
OLD | NEW |