Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GradientBench.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 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#include "bench/Benchmark.h"
15
16#include "tools/ToolUtils.h"
17
18struct GradData {
19 int fCount;
21 const SkScalar* fPos;
22 const char* fName;
23};
24
37
38static const SkColor gShallowColors[] = { 0xFF555555, 0xFF444444 };
39static const SkScalar gPos[] = {0.25f, 0.75f};
40
41// We have several special-cases depending on the number (and spacing) of colors, so
42// try to exercise those here.
43static const GradData gGradData[] = {
44 { 2, gColors, nullptr, "" },
45 { 50, gColors, nullptr, "_hicolor" }, // many color gradient
46 { 3, gColors, nullptr, "_3color" },
47 { 2, gShallowColors, nullptr, "_shallow" },
48 { 2, gColors, gPos, "_pos" },
49};
50
51/// Ignores scale
52static sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data,
53 SkTileMode tm, float scale) {
54 return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm);
55}
56
57static sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data,
58 SkTileMode tm, float scale) {
60 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
61 SkScalarAve(pts[0].fY, pts[1].fY));
62 return SkGradientShader::MakeRadial(center, center.fX * scale, data.fColors,
63 data.fPos, data.fCount, tm);
64}
65
66/// Ignores scale
67static sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data,
68 SkTileMode tm, float scale) {
70 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
71 SkScalarAve(pts[0].fY, pts[1].fY));
72 return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
73}
74
75/// Ignores scale
76static sk_sp<SkShader> MakeConical(const SkPoint pts[2], const GradData& data,
77 SkTileMode tm, float scale) {
78 SkPoint center0, center1;
79 center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
80 SkScalarAve(pts[0].fY, pts[1].fY));
81 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
82 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
83 return SkGradientShader::MakeTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7,
84 center0, (pts[1].fX - pts[0].fX) / 2,
85 data.fColors, data.fPos, data.fCount, tm);
86}
87
88/// Ignores scale
89static sk_sp<SkShader> MakeConicalZeroRad(const SkPoint pts[2], const GradData& data,
90 SkTileMode tm, float scale) {
91 SkPoint center0, center1;
92 center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
93 SkScalarAve(pts[0].fY, pts[1].fY));
94 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
95 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
96 return SkGradientShader::MakeTwoPointConical(center1, 0.0,
97 center0, (pts[1].fX - pts[0].fX) / 2,
98 data.fColors, data.fPos, data.fCount, tm);
99}
100
101/// Ignores scale
102static sk_sp<SkShader> MakeConicalOutside(const SkPoint pts[2], const GradData& data,
103 SkTileMode tm, float scale) {
104 SkPoint center0, center1;
105 SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
106 SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
107 center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
108 center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
109 return SkGradientShader::MakeTwoPointConical(center0, radius0,
110 center1, radius1,
111 data.fColors, data.fPos,
112 data.fCount, tm);
113}
114
115/// Ignores scale
117 SkTileMode tm, float scale) {
118 SkPoint center0, center1;
119 SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
120 SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
121 center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
122 center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
123 return SkGradientShader::MakeTwoPointConical(center0, 0.0,
124 center1, radius1,
125 data.fColors, data.fPos,
126 data.fCount, tm);
127}
128
129typedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data,
130 SkTileMode tm, float scale);
131
132static const struct {
134 const char* fName;
135} gGrads[] = {
136 { MakeLinear, "linear" },
137 { MakeRadial, "radial1" },
138 { MakeSweep, "sweep" },
139 { MakeConical, "conical" },
140 { MakeConicalZeroRad, "conicalZero" },
141 { MakeConicalOutside, "conicalOut" },
142 { MakeConicalOutsideZeroRad, "conicalOutZero" },
144
154
159
160static const char* geomtypename(GeomType gt) {
161 switch (gt) {
162 case kRect_GeomType:
163 return "rectangle";
164 case kOval_GeomType:
165 return "oval";
166 default:
167 SkDEBUGFAIL("unknown geometry type");
168 return "error";
169 }
170}
171
172///////////////////////////////////////////////////////////////////////////////
173
174class GradientBench : public Benchmark {
175public:
177 GradData data = gGradData[0],
179 GeomType geomType = kRect_GeomType,
180 float scale = 1.0f)
181 : fGeomType(geomType) {
182
183 fName.printf("gradient_%s_%s", gGrads[gradType].fName,
185 if (geomType != kRect_GeomType) {
186 fName.appendf("_%s", geomtypename(geomType));
187 }
188
189 if (scale != 1.f) {
190 fName.appendf("_scale_%g", scale);
191 }
192
193 fName.append(data.fName);
194
195 this->setupPaint(&fPaint);
196 fPaint.setShader(MakeShader(gradType, data, tm, scale));
197 }
198
199 GradientBench(GradType gradType, GradData data, bool dither)
200 : fGeomType(kRect_GeomType) {
201
202 const char *tmname = ToolUtils::tilemode_name(SkTileMode::kClamp);
203 fName.printf("gradient_%s_%s", gGrads[gradType].fName, tmname);
204 fName.append(data.fName);
205
206 if (dither) {
207 fName.appendf("_dither");
208 }
209
210 this->setupPaint(&fPaint);
211 fPaint.setShader(MakeShader(gradType, data, SkTileMode::kClamp, 1.0f));
212 fPaint.setDither(dither);
213 }
214
215protected:
216 const char* onGetName() override {
217 return fName.c_str();
218 }
219
220 SkISize onGetSize() override {
221 return SkISize::Make(kSize, kSize);
222 }
223
224 void onDraw(int loops, SkCanvas* canvas) override {
225 const SkRect r = SkRect::MakeIWH(kSize, kSize);
226
227 for (int i = 0; i < loops; i++) {
228 switch (fGeomType) {
229 case kRect_GeomType:
230 canvas->drawRect(r, fPaint);
231 break;
232 case kOval_GeomType:
233 canvas->drawOval(r, fPaint);
234 break;
235 }
236 }
237 }
238
239private:
240 using INHERITED = Benchmark;
241
242 sk_sp<SkShader> MakeShader(GradType gradType, GradData data,
243 SkTileMode tm, float scale) {
244 const SkPoint pts[2] = {
245 { 0, 0 },
246 { SkIntToScalar(kSize), SkIntToScalar(kSize) }
247 };
248
249 return gGrads[gradType].fMaker(pts, data, tm, scale);
250 }
251
252 static const int kSize = 400;
253
254 SkString fName;
255 SkPaint fPaint;
256 const GeomType fGeomType;
257};
258
269
273// Draw a radial gradient of radius 1/2 on a rectangle; half the lines should
274// be completely pinned, the other half should pe partially pinned
276
277// Draw a radial gradient on a circle of equal size; all the lines should
278// hit the unpinned fast path (so long as GradientBench.W == H)
280
298
299// Dithering
300DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[3], true); )
301DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[3], false); )
302DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[3], true); )
303DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[3], false); )
304DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[3], true); )
305DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[3], false); )
306DEF_BENCH( return new GradientBench(kConical_GradType, gGradData[3], true); )
307DEF_BENCH( return new GradientBench(kConical_GradType, gGradData[3], false); )
308
309///////////////////////////////////////////////////////////////////////////////
310
311class Gradient2Bench : public Benchmark {
313 bool fHasAlpha;
314
315public:
316 Gradient2Bench(bool hasAlpha) {
317 fName.printf("gradient_create_%s", hasAlpha ? "alpha" : "opaque");
318 fHasAlpha = hasAlpha;
319 }
320
321protected:
322 const char* onGetName() override {
323 return fName.c_str();
324 }
325
326 void onDraw(int loops, SkCanvas* canvas) override {
328 this->setupPaint(&paint);
329
330 const SkRect r = { 0, 0, SkIntToScalar(4), SkIntToScalar(4) };
331 const SkPoint pts[] = {
332 { 0, 0 },
333 { SkIntToScalar(100), SkIntToScalar(100) },
334 };
335
336 for (int i = 0; i < loops; i++) {
337 const int gray = i % 256;
338 const int alpha = fHasAlpha ? gray : 0xFF;
339 SkColor colors[] = {
341 SkColorSetARGB(alpha, gray, gray, gray),
343 paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr,
344 std::size(colors),
346 canvas->drawRect(r, paint);
347 }
348 }
349
350private:
351 using INHERITED = Benchmark;
352};
353
354DEF_BENCH( return new Gradient2Bench(false); )
355DEF_BENCH( return new Gradient2Bench(true); )
#define DEF_BENCH(code)
Definition Benchmark.h:20
const char * fName
static sk_sp< SkShader > MakeConical(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)
Ignores scale.
static const GradData gGradData[]
static const char * geomtypename(GeomType gt)
@ kOval_GeomType
@ kRect_GeomType
static sk_sp< SkShader > MakeSweep(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)
Ignores scale.
static const SkColor gShallowColors[]
static sk_sp< SkShader > MakeConicalZeroRad(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)
Ignores scale.
GradMaker fMaker
@ kSweep_GradType
@ kConical_GradType
@ kConicalZero_GradType
@ kRadial_GradType
@ kConicalOutZero_GradType
@ kLinear_GradType
@ kConicalOut_GradType
sk_sp< SkShader >(* GradMaker)(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)
const char * fName
static const struct @225 gGrads[]
static sk_sp< SkShader > MakeConicalOutside(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)
Ignores scale.
static const SkScalar gPos[]
static const SkColor gColors[]
static sk_sp< SkShader > MakeConicalOutsideZeroRad(const SkPoint pts[2], const GradData &data, SkTileMode tm, float scale)
Ignores scale.
#define SkDEBUGFAIL(message)
Definition SkAssert.h:118
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition SkColor.h:49
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
constexpr SkColor SK_ColorWHITE
Definition SkColor.h:122
#define INHERITED(method,...)
#define SkScalarAve(a, b)
Definition SkScalar.h:74
#define SkIntToScalar(x)
Definition SkScalar.h:57
static SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t)
Definition SkScalar.h:131
SkTileMode
Definition SkTileMode.h:13
static SkScalar center(float pos0, float pos1)
static sk_sp< SkShader > MakeRadial()
virtual void setupPaint(SkPaint *paint)
Definition Benchmark.cpp:55
Gradient2Bench(bool hasAlpha)
const char * onGetName() override
void onDraw(int loops, SkCanvas *canvas) override
GradientBench(GradType gradType, GradData data, bool dither)
SkISize onGetSize() override
GradientBench(GradType gradType, GradData data=gGradData[0], SkTileMode tm=SkTileMode::kClamp, GeomType geomType=kRect_GeomType, float scale=1.0f)
const char * onGetName() override
void onDraw(int loops, SkCanvas *canvas) override
void drawRect(const SkRect &rect, const SkPaint &paint)
void drawOval(const SkRect &oval, const SkPaint &paint)
static sk_sp< SkShader > MakeTwoPointConical(const SkPoint &start, SkScalar startRadius, const SkPoint &end, SkScalar endRadius, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
static sk_sp< SkShader > MakeSweep(SkScalar cx, SkScalar cy, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, SkScalar startAngle, SkScalar endAngle, uint32_t flags, const SkMatrix *localMatrix)
static sk_sp< SkShader > MakeRadial(const SkPoint &center, SkScalar radius, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
void setDither(bool dither)
Definition SkPaint.h:182
void setShader(sk_sp< SkShader > shader)
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition SkString.cpp:534
const char * c_str() const
Definition SkString.h:133
const Paint & paint
static sk_sp< SkShader > MakeLinear()
float SkScalar
Definition extension.cpp:12
const char * tilemode_name(SkTileMode mode)
const Scalar scale
const char * fName
const SkColor * fColors
const SkScalar * fPos
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
float fX
x-axis value
void set(float x, float y)
static SkRect MakeIWH(int w, int h)
Definition SkRect.h:623