xref: /aosp_15_r20/external/skia/bench/GradientBench.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2011 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker #include "bench/Benchmark.h"
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorPriv.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkGradientShader.h"
15*c8dee2aaSAndroid Build Coastguard Worker 
16*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
17*c8dee2aaSAndroid Build Coastguard Worker 
18*c8dee2aaSAndroid Build Coastguard Worker struct GradData {
19*c8dee2aaSAndroid Build Coastguard Worker     int             fCount;
20*c8dee2aaSAndroid Build Coastguard Worker     const SkColor*  fColors;
21*c8dee2aaSAndroid Build Coastguard Worker     const SkScalar* fPos;
22*c8dee2aaSAndroid Build Coastguard Worker     const char*     fName;
23*c8dee2aaSAndroid Build Coastguard Worker };
24*c8dee2aaSAndroid Build Coastguard Worker 
25*c8dee2aaSAndroid Build Coastguard Worker static const SkColor gColors[] = {
26*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
27*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
28*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
29*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
30*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
31*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
32*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
33*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
34*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK,
35*c8dee2aaSAndroid Build Coastguard Worker     SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK, // 10 lines, 50 colors
36*c8dee2aaSAndroid Build Coastguard Worker };
37*c8dee2aaSAndroid Build Coastguard Worker 
38*c8dee2aaSAndroid Build Coastguard Worker static const SkColor gShallowColors[] = { 0xFF555555, 0xFF444444 };
39*c8dee2aaSAndroid Build Coastguard Worker static const SkScalar gPos[] = {0.25f, 0.75f};
40*c8dee2aaSAndroid Build Coastguard Worker 
41*c8dee2aaSAndroid Build Coastguard Worker // We have several special-cases depending on the number (and spacing) of colors, so
42*c8dee2aaSAndroid Build Coastguard Worker // try to exercise those here.
43*c8dee2aaSAndroid Build Coastguard Worker static const GradData gGradData[] = {
44*c8dee2aaSAndroid Build Coastguard Worker     { 2, gColors, nullptr, "" },
45*c8dee2aaSAndroid Build Coastguard Worker     { 50, gColors, nullptr, "_hicolor" }, // many color gradient
46*c8dee2aaSAndroid Build Coastguard Worker     { 3, gColors, nullptr, "_3color" },
47*c8dee2aaSAndroid Build Coastguard Worker     { 2, gShallowColors, nullptr, "_shallow" },
48*c8dee2aaSAndroid Build Coastguard Worker     { 2, gColors, gPos, "_pos" },
49*c8dee2aaSAndroid Build Coastguard Worker };
50*c8dee2aaSAndroid Build Coastguard Worker 
51*c8dee2aaSAndroid Build Coastguard Worker /// Ignores scale
MakeLinear(const SkPoint pts[2],const GradData & data,SkTileMode tm,float scale)52*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data,
53*c8dee2aaSAndroid Build Coastguard Worker                                   SkTileMode tm, float scale) {
54*c8dee2aaSAndroid Build Coastguard Worker     return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm);
55*c8dee2aaSAndroid Build Coastguard Worker }
56*c8dee2aaSAndroid Build Coastguard Worker 
MakeRadial(const SkPoint pts[2],const GradData & data,SkTileMode tm,float scale)57*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data,
58*c8dee2aaSAndroid Build Coastguard Worker                                   SkTileMode tm, float scale) {
59*c8dee2aaSAndroid Build Coastguard Worker     SkPoint center;
60*c8dee2aaSAndroid Build Coastguard Worker     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
61*c8dee2aaSAndroid Build Coastguard Worker                SkScalarAve(pts[0].fY, pts[1].fY));
62*c8dee2aaSAndroid Build Coastguard Worker     return SkGradientShader::MakeRadial(center, center.fX * scale, data.fColors,
63*c8dee2aaSAndroid Build Coastguard Worker                                         data.fPos, data.fCount, tm);
64*c8dee2aaSAndroid Build Coastguard Worker }
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker /// Ignores scale
MakeSweep(const SkPoint pts[2],const GradData & data,SkTileMode tm,float scale)67*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data,
68*c8dee2aaSAndroid Build Coastguard Worker                                  SkTileMode tm, float scale) {
69*c8dee2aaSAndroid Build Coastguard Worker     SkPoint center;
70*c8dee2aaSAndroid Build Coastguard Worker     center.set(SkScalarAve(pts[0].fX, pts[1].fX),
71*c8dee2aaSAndroid Build Coastguard Worker                SkScalarAve(pts[0].fY, pts[1].fY));
72*c8dee2aaSAndroid Build Coastguard Worker     return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount);
73*c8dee2aaSAndroid Build Coastguard Worker }
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker /// Ignores scale
MakeConical(const SkPoint pts[2],const GradData & data,SkTileMode tm,float scale)76*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> MakeConical(const SkPoint pts[2], const GradData& data,
77*c8dee2aaSAndroid Build Coastguard Worker                                    SkTileMode tm, float scale) {
78*c8dee2aaSAndroid Build Coastguard Worker     SkPoint center0, center1;
79*c8dee2aaSAndroid Build Coastguard Worker     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
80*c8dee2aaSAndroid Build Coastguard Worker                 SkScalarAve(pts[0].fY, pts[1].fY));
81*c8dee2aaSAndroid Build Coastguard Worker     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
82*c8dee2aaSAndroid Build Coastguard Worker                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
83*c8dee2aaSAndroid Build Coastguard Worker     return SkGradientShader::MakeTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7,
84*c8dee2aaSAndroid Build Coastguard Worker                                                  center0, (pts[1].fX - pts[0].fX) / 2,
85*c8dee2aaSAndroid Build Coastguard Worker                                                  data.fColors, data.fPos, data.fCount, tm);
86*c8dee2aaSAndroid Build Coastguard Worker }
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker /// Ignores scale
MakeConicalZeroRad(const SkPoint pts[2],const GradData & data,SkTileMode tm,float scale)89*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> MakeConicalZeroRad(const SkPoint pts[2], const GradData& data,
90*c8dee2aaSAndroid Build Coastguard Worker                                           SkTileMode tm, float scale) {
91*c8dee2aaSAndroid Build Coastguard Worker     SkPoint center0, center1;
92*c8dee2aaSAndroid Build Coastguard Worker     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
93*c8dee2aaSAndroid Build Coastguard Worker                 SkScalarAve(pts[0].fY, pts[1].fY));
94*c8dee2aaSAndroid Build Coastguard Worker     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
95*c8dee2aaSAndroid Build Coastguard Worker                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
96*c8dee2aaSAndroid Build Coastguard Worker     return SkGradientShader::MakeTwoPointConical(center1, 0.0,
97*c8dee2aaSAndroid Build Coastguard Worker                                                  center0, (pts[1].fX - pts[0].fX) / 2,
98*c8dee2aaSAndroid Build Coastguard Worker                                                  data.fColors, data.fPos, data.fCount, tm);
99*c8dee2aaSAndroid Build Coastguard Worker }
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker /// Ignores scale
MakeConicalOutside(const SkPoint pts[2],const GradData & data,SkTileMode tm,float scale)102*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> MakeConicalOutside(const SkPoint pts[2], const GradData& data,
103*c8dee2aaSAndroid Build Coastguard Worker                                           SkTileMode tm, float scale) {
104*c8dee2aaSAndroid Build Coastguard Worker     SkPoint center0, center1;
105*c8dee2aaSAndroid Build Coastguard Worker     SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
106*c8dee2aaSAndroid Build Coastguard Worker     SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
107*c8dee2aaSAndroid Build Coastguard Worker     center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
108*c8dee2aaSAndroid Build Coastguard Worker     center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
109*c8dee2aaSAndroid Build Coastguard Worker     return SkGradientShader::MakeTwoPointConical(center0, radius0,
110*c8dee2aaSAndroid Build Coastguard Worker                                                  center1, radius1,
111*c8dee2aaSAndroid Build Coastguard Worker                                                  data.fColors, data.fPos,
112*c8dee2aaSAndroid Build Coastguard Worker                                                  data.fCount, tm);
113*c8dee2aaSAndroid Build Coastguard Worker }
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker /// Ignores scale
MakeConicalOutsideZeroRad(const SkPoint pts[2],const GradData & data,SkTileMode tm,float scale)116*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> MakeConicalOutsideZeroRad(const SkPoint pts[2], const GradData& data,
117*c8dee2aaSAndroid Build Coastguard Worker                                                  SkTileMode tm, float scale) {
118*c8dee2aaSAndroid Build Coastguard Worker     SkPoint center0, center1;
119*c8dee2aaSAndroid Build Coastguard Worker     SkScalar radius0 = (pts[1].fX - pts[0].fX) / 10;
120*c8dee2aaSAndroid Build Coastguard Worker     SkScalar radius1 = (pts[1].fX - pts[0].fX) / 3;
121*c8dee2aaSAndroid Build Coastguard Worker     center0.set(pts[0].fX + radius0, pts[0].fY + radius0);
122*c8dee2aaSAndroid Build Coastguard Worker     center1.set(pts[1].fX - radius1, pts[1].fY - radius1);
123*c8dee2aaSAndroid Build Coastguard Worker     return SkGradientShader::MakeTwoPointConical(center0, 0.0,
124*c8dee2aaSAndroid Build Coastguard Worker                                                  center1, radius1,
125*c8dee2aaSAndroid Build Coastguard Worker                                                  data.fColors, data.fPos,
126*c8dee2aaSAndroid Build Coastguard Worker                                                  data.fCount, tm);
127*c8dee2aaSAndroid Build Coastguard Worker }
128*c8dee2aaSAndroid Build Coastguard Worker 
129*c8dee2aaSAndroid Build Coastguard Worker typedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData& data,
130*c8dee2aaSAndroid Build Coastguard Worker                                      SkTileMode tm, float scale);
131*c8dee2aaSAndroid Build Coastguard Worker 
132*c8dee2aaSAndroid Build Coastguard Worker static const struct {
133*c8dee2aaSAndroid Build Coastguard Worker     GradMaker   fMaker;
134*c8dee2aaSAndroid Build Coastguard Worker     const char* fName;
135*c8dee2aaSAndroid Build Coastguard Worker } gGrads[] = {
136*c8dee2aaSAndroid Build Coastguard Worker     { MakeLinear,                 "linear"  },
137*c8dee2aaSAndroid Build Coastguard Worker     { MakeRadial,                 "radial1" },
138*c8dee2aaSAndroid Build Coastguard Worker     { MakeSweep,                  "sweep"   },
139*c8dee2aaSAndroid Build Coastguard Worker     { MakeConical,                "conical" },
140*c8dee2aaSAndroid Build Coastguard Worker     { MakeConicalZeroRad,         "conicalZero" },
141*c8dee2aaSAndroid Build Coastguard Worker     { MakeConicalOutside,         "conicalOut" },
142*c8dee2aaSAndroid Build Coastguard Worker     { MakeConicalOutsideZeroRad,  "conicalOutZero" },
143*c8dee2aaSAndroid Build Coastguard Worker };
144*c8dee2aaSAndroid Build Coastguard Worker 
145*c8dee2aaSAndroid Build Coastguard Worker enum GradType { // these must match the order in gGrads
146*c8dee2aaSAndroid Build Coastguard Worker     kLinear_GradType,
147*c8dee2aaSAndroid Build Coastguard Worker     kRadial_GradType,
148*c8dee2aaSAndroid Build Coastguard Worker     kSweep_GradType,
149*c8dee2aaSAndroid Build Coastguard Worker     kConical_GradType,
150*c8dee2aaSAndroid Build Coastguard Worker     kConicalZero_GradType,
151*c8dee2aaSAndroid Build Coastguard Worker     kConicalOut_GradType,
152*c8dee2aaSAndroid Build Coastguard Worker     kConicalOutZero_GradType
153*c8dee2aaSAndroid Build Coastguard Worker };
154*c8dee2aaSAndroid Build Coastguard Worker 
155*c8dee2aaSAndroid Build Coastguard Worker enum GeomType {
156*c8dee2aaSAndroid Build Coastguard Worker     kRect_GeomType,
157*c8dee2aaSAndroid Build Coastguard Worker     kOval_GeomType
158*c8dee2aaSAndroid Build Coastguard Worker };
159*c8dee2aaSAndroid Build Coastguard Worker 
geomtypename(GeomType gt)160*c8dee2aaSAndroid Build Coastguard Worker static const char* geomtypename(GeomType gt) {
161*c8dee2aaSAndroid Build Coastguard Worker     switch (gt) {
162*c8dee2aaSAndroid Build Coastguard Worker         case kRect_GeomType:
163*c8dee2aaSAndroid Build Coastguard Worker             return "rectangle";
164*c8dee2aaSAndroid Build Coastguard Worker         case kOval_GeomType:
165*c8dee2aaSAndroid Build Coastguard Worker             return "oval";
166*c8dee2aaSAndroid Build Coastguard Worker         default:
167*c8dee2aaSAndroid Build Coastguard Worker             SkDEBUGFAIL("unknown geometry type");
168*c8dee2aaSAndroid Build Coastguard Worker             return "error";
169*c8dee2aaSAndroid Build Coastguard Worker     }
170*c8dee2aaSAndroid Build Coastguard Worker }
171*c8dee2aaSAndroid Build Coastguard Worker 
172*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
173*c8dee2aaSAndroid Build Coastguard Worker 
174*c8dee2aaSAndroid Build Coastguard Worker class GradientBench : public Benchmark {
175*c8dee2aaSAndroid Build Coastguard Worker public:
GradientBench(GradType gradType,GradData data=gGradData[0],SkTileMode tm=SkTileMode::kClamp,GeomType geomType=kRect_GeomType,float scale=1.0f)176*c8dee2aaSAndroid Build Coastguard Worker     GradientBench(GradType gradType,
177*c8dee2aaSAndroid Build Coastguard Worker                   GradData data = gGradData[0],
178*c8dee2aaSAndroid Build Coastguard Worker                   SkTileMode tm = SkTileMode::kClamp,
179*c8dee2aaSAndroid Build Coastguard Worker                   GeomType geomType = kRect_GeomType,
180*c8dee2aaSAndroid Build Coastguard Worker                   float scale = 1.0f)
181*c8dee2aaSAndroid Build Coastguard Worker         : fGeomType(geomType) {
182*c8dee2aaSAndroid Build Coastguard Worker 
183*c8dee2aaSAndroid Build Coastguard Worker         fName.printf("gradient_%s_%s", gGrads[gradType].fName,
184*c8dee2aaSAndroid Build Coastguard Worker                      ToolUtils::tilemode_name(tm));
185*c8dee2aaSAndroid Build Coastguard Worker         if (geomType != kRect_GeomType) {
186*c8dee2aaSAndroid Build Coastguard Worker             fName.appendf("_%s", geomtypename(geomType));
187*c8dee2aaSAndroid Build Coastguard Worker         }
188*c8dee2aaSAndroid Build Coastguard Worker 
189*c8dee2aaSAndroid Build Coastguard Worker         if (scale != 1.f) {
190*c8dee2aaSAndroid Build Coastguard Worker             fName.appendf("_scale_%g", scale);
191*c8dee2aaSAndroid Build Coastguard Worker         }
192*c8dee2aaSAndroid Build Coastguard Worker 
193*c8dee2aaSAndroid Build Coastguard Worker         fName.append(data.fName);
194*c8dee2aaSAndroid Build Coastguard Worker 
195*c8dee2aaSAndroid Build Coastguard Worker         this->setupPaint(&fPaint);
196*c8dee2aaSAndroid Build Coastguard Worker         fPaint.setShader(MakeShader(gradType, data, tm, scale));
197*c8dee2aaSAndroid Build Coastguard Worker     }
198*c8dee2aaSAndroid Build Coastguard Worker 
GradientBench(GradType gradType,GradData data,bool dither)199*c8dee2aaSAndroid Build Coastguard Worker     GradientBench(GradType gradType, GradData data, bool dither)
200*c8dee2aaSAndroid Build Coastguard Worker         : fGeomType(kRect_GeomType) {
201*c8dee2aaSAndroid Build Coastguard Worker 
202*c8dee2aaSAndroid Build Coastguard Worker         const char *tmname = ToolUtils::tilemode_name(SkTileMode::kClamp);
203*c8dee2aaSAndroid Build Coastguard Worker         fName.printf("gradient_%s_%s", gGrads[gradType].fName, tmname);
204*c8dee2aaSAndroid Build Coastguard Worker         fName.append(data.fName);
205*c8dee2aaSAndroid Build Coastguard Worker 
206*c8dee2aaSAndroid Build Coastguard Worker         if (dither) {
207*c8dee2aaSAndroid Build Coastguard Worker             fName.appendf("_dither");
208*c8dee2aaSAndroid Build Coastguard Worker         }
209*c8dee2aaSAndroid Build Coastguard Worker 
210*c8dee2aaSAndroid Build Coastguard Worker         this->setupPaint(&fPaint);
211*c8dee2aaSAndroid Build Coastguard Worker         fPaint.setShader(MakeShader(gradType, data, SkTileMode::kClamp, 1.0f));
212*c8dee2aaSAndroid Build Coastguard Worker         fPaint.setDither(dither);
213*c8dee2aaSAndroid Build Coastguard Worker     }
214*c8dee2aaSAndroid Build Coastguard Worker 
215*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()216*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
217*c8dee2aaSAndroid Build Coastguard Worker         return fName.c_str();
218*c8dee2aaSAndroid Build Coastguard Worker     }
219*c8dee2aaSAndroid Build Coastguard Worker 
onGetSize()220*c8dee2aaSAndroid Build Coastguard Worker     SkISize onGetSize() override {
221*c8dee2aaSAndroid Build Coastguard Worker         return SkISize::Make(kSize, kSize);
222*c8dee2aaSAndroid Build Coastguard Worker     }
223*c8dee2aaSAndroid Build Coastguard Worker 
onDraw(int loops,SkCanvas * canvas)224*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas* canvas) override {
225*c8dee2aaSAndroid Build Coastguard Worker         const SkRect r = SkRect::MakeIWH(kSize, kSize);
226*c8dee2aaSAndroid Build Coastguard Worker 
227*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < loops; i++) {
228*c8dee2aaSAndroid Build Coastguard Worker             switch (fGeomType) {
229*c8dee2aaSAndroid Build Coastguard Worker                case kRect_GeomType:
230*c8dee2aaSAndroid Build Coastguard Worker                    canvas->drawRect(r, fPaint);
231*c8dee2aaSAndroid Build Coastguard Worker                    break;
232*c8dee2aaSAndroid Build Coastguard Worker                case kOval_GeomType:
233*c8dee2aaSAndroid Build Coastguard Worker                    canvas->drawOval(r, fPaint);
234*c8dee2aaSAndroid Build Coastguard Worker                    break;
235*c8dee2aaSAndroid Build Coastguard Worker             }
236*c8dee2aaSAndroid Build Coastguard Worker         }
237*c8dee2aaSAndroid Build Coastguard Worker     }
238*c8dee2aaSAndroid Build Coastguard Worker 
239*c8dee2aaSAndroid Build Coastguard Worker private:
240*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
241*c8dee2aaSAndroid Build Coastguard Worker 
MakeShader(GradType gradType,GradData data,SkTileMode tm,float scale)242*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkShader> MakeShader(GradType gradType, GradData data,
243*c8dee2aaSAndroid Build Coastguard Worker                                SkTileMode tm, float scale) {
244*c8dee2aaSAndroid Build Coastguard Worker         const SkPoint pts[2] = {
245*c8dee2aaSAndroid Build Coastguard Worker             { 0, 0 },
246*c8dee2aaSAndroid Build Coastguard Worker             { SkIntToScalar(kSize), SkIntToScalar(kSize) }
247*c8dee2aaSAndroid Build Coastguard Worker         };
248*c8dee2aaSAndroid Build Coastguard Worker 
249*c8dee2aaSAndroid Build Coastguard Worker         return gGrads[gradType].fMaker(pts, data, tm, scale);
250*c8dee2aaSAndroid Build Coastguard Worker     }
251*c8dee2aaSAndroid Build Coastguard Worker 
252*c8dee2aaSAndroid Build Coastguard Worker     static const int kSize = 400;
253*c8dee2aaSAndroid Build Coastguard Worker 
254*c8dee2aaSAndroid Build Coastguard Worker     SkString       fName;
255*c8dee2aaSAndroid Build Coastguard Worker     SkPaint        fPaint;
256*c8dee2aaSAndroid Build Coastguard Worker     const GeomType fGeomType;
257*c8dee2aaSAndroid Build Coastguard Worker };
258*c8dee2aaSAndroid Build Coastguard Worker 
259*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0]); )
260*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1]); )
261*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2]); )
262*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[4]); )
263*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkTileMode::kRepeat); )
264*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkTileMode::kRepeat); )
265*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkTileMode::kRepeat); )
266*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[0], SkTileMode::kMirror); )
267*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[1], SkTileMode::kMirror); )
268*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[2], SkTileMode::kMirror); )
269*c8dee2aaSAndroid Build Coastguard Worker 
270*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0]); )
271*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[1]); )
272*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[2]); )
273*c8dee2aaSAndroid Build Coastguard Worker // Draw a radial gradient of radius 1/2 on a rectangle; half the lines should
274*c8dee2aaSAndroid Build Coastguard Worker // be completely pinned, the other half should pe partially pinned
275*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkTileMode::kClamp, kRect_GeomType, 0.5f); )
276*c8dee2aaSAndroid Build Coastguard Worker 
277*c8dee2aaSAndroid Build Coastguard Worker // Draw a radial gradient on a circle of equal size; all the lines should
278*c8dee2aaSAndroid Build Coastguard Worker // hit the unpinned fast path (so long as GradientBench.W == H)
279*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkTileMode::kClamp, kOval_GeomType); )
280*c8dee2aaSAndroid Build Coastguard Worker 
281*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkTileMode::kMirror); )
282*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkTileMode::kRepeat); )
283*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kSweep_GradType); )
284*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[1]); )
285*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[2]); )
286*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConical_GradType); )
287*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConical_GradType, gGradData[1]); )
288*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConical_GradType, gGradData[2]); )
289*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConicalZero_GradType); )
290*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConicalZero_GradType, gGradData[1]); )
291*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConicalZero_GradType, gGradData[2]); )
292*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConicalOut_GradType); )
293*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConicalOut_GradType, gGradData[1]); )
294*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConicalOut_GradType, gGradData[2]); )
295*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConicalOutZero_GradType); )
296*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConicalOutZero_GradType, gGradData[1]); )
297*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConicalOutZero_GradType, gGradData[2]); )
298*c8dee2aaSAndroid Build Coastguard Worker 
299*c8dee2aaSAndroid Build Coastguard Worker // Dithering
300*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[3], true); )
301*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kLinear_GradType, gGradData[3], false); )
302*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[3], true); )
303*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[3], false); )
304*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[3], true); )
305*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[3], false); )
306*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConical_GradType, gGradData[3], true); )
307*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new GradientBench(kConical_GradType, gGradData[3], false); )
308*c8dee2aaSAndroid Build Coastguard Worker 
309*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
310*c8dee2aaSAndroid Build Coastguard Worker 
311*c8dee2aaSAndroid Build Coastguard Worker class Gradient2Bench : public Benchmark {
312*c8dee2aaSAndroid Build Coastguard Worker     SkString fName;
313*c8dee2aaSAndroid Build Coastguard Worker     bool     fHasAlpha;
314*c8dee2aaSAndroid Build Coastguard Worker 
315*c8dee2aaSAndroid Build Coastguard Worker public:
Gradient2Bench(bool hasAlpha)316*c8dee2aaSAndroid Build Coastguard Worker     Gradient2Bench(bool hasAlpha)  {
317*c8dee2aaSAndroid Build Coastguard Worker         fName.printf("gradient_create_%s", hasAlpha ? "alpha" : "opaque");
318*c8dee2aaSAndroid Build Coastguard Worker         fHasAlpha = hasAlpha;
319*c8dee2aaSAndroid Build Coastguard Worker     }
320*c8dee2aaSAndroid Build Coastguard Worker 
321*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()322*c8dee2aaSAndroid Build Coastguard Worker     const char* onGetName() override {
323*c8dee2aaSAndroid Build Coastguard Worker         return fName.c_str();
324*c8dee2aaSAndroid Build Coastguard Worker     }
325*c8dee2aaSAndroid Build Coastguard Worker 
onDraw(int loops,SkCanvas * canvas)326*c8dee2aaSAndroid Build Coastguard Worker     void onDraw(int loops, SkCanvas* canvas) override {
327*c8dee2aaSAndroid Build Coastguard Worker         SkPaint paint;
328*c8dee2aaSAndroid Build Coastguard Worker         this->setupPaint(&paint);
329*c8dee2aaSAndroid Build Coastguard Worker 
330*c8dee2aaSAndroid Build Coastguard Worker         const SkRect r = { 0, 0, SkIntToScalar(4), SkIntToScalar(4) };
331*c8dee2aaSAndroid Build Coastguard Worker         const SkPoint pts[] = {
332*c8dee2aaSAndroid Build Coastguard Worker             { 0, 0 },
333*c8dee2aaSAndroid Build Coastguard Worker             { SkIntToScalar(100), SkIntToScalar(100) },
334*c8dee2aaSAndroid Build Coastguard Worker         };
335*c8dee2aaSAndroid Build Coastguard Worker 
336*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < loops; i++) {
337*c8dee2aaSAndroid Build Coastguard Worker             const int gray = i % 256;
338*c8dee2aaSAndroid Build Coastguard Worker             const int alpha = fHasAlpha ? gray : 0xFF;
339*c8dee2aaSAndroid Build Coastguard Worker             SkColor colors[] = {
340*c8dee2aaSAndroid Build Coastguard Worker                 SK_ColorBLACK,
341*c8dee2aaSAndroid Build Coastguard Worker                 SkColorSetARGB(alpha, gray, gray, gray),
342*c8dee2aaSAndroid Build Coastguard Worker                 SK_ColorWHITE };
343*c8dee2aaSAndroid Build Coastguard Worker             paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr,
344*c8dee2aaSAndroid Build Coastguard Worker                                                          std::size(colors),
345*c8dee2aaSAndroid Build Coastguard Worker                                                          SkTileMode::kClamp));
346*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawRect(r, paint);
347*c8dee2aaSAndroid Build Coastguard Worker         }
348*c8dee2aaSAndroid Build Coastguard Worker     }
349*c8dee2aaSAndroid Build Coastguard Worker 
350*c8dee2aaSAndroid Build Coastguard Worker private:
351*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = Benchmark;
352*c8dee2aaSAndroid Build Coastguard Worker };
353*c8dee2aaSAndroid Build Coastguard Worker 
354*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new Gradient2Bench(false); )
355*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new Gradient2Bench(true); )
356