1 #include "SkBenchmark.h"
2 #include "SkBitmap.h"
3 #include "SkCanvas.h"
4 #include "SkColorPriv.h"
5 #include "SkGradientShader.h"
6 #include "SkPaint.h"
7 #include "SkShader.h"
8 #include "SkString.h"
9 #include "SkUnitMapper.h"
10
11 struct GradData {
12 int fCount;
13 const SkColor* fColors;
14 const SkScalar* fPos;
15 };
16
17 static const SkColor gColors[] = {
18 SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
19 };
20 static const SkScalar gPos0[] = { 0, SK_Scalar1 };
21 static const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
22 static const SkScalar gPos2[] = {
23 0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1
24 };
25
26 static const GradData gGradData[] = {
27 { 2, gColors, NULL },
28 { 2, gColors, gPos0 },
29 { 2, gColors, gPos1 },
30 { 5, gColors, NULL },
31 { 5, gColors, gPos2 }
32 };
33
MakeLinear(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm,SkUnitMapper * mapper)34 static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
35 SkShader::TileMode tm, SkUnitMapper* mapper) {
36 return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
37 data.fCount, tm, mapper);
38 }
39
MakeRadial(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm,SkUnitMapper * mapper)40 static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
41 SkShader::TileMode tm, SkUnitMapper* mapper) {
42 SkPoint center;
43 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
44 SkScalarAve(pts[0].fY, pts[1].fY));
45 return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
46 data.fPos, data.fCount, tm, mapper);
47 }
48
MakeSweep(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm,SkUnitMapper * mapper)49 static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
50 SkShader::TileMode tm, SkUnitMapper* mapper) {
51 SkPoint center;
52 center.set(SkScalarAve(pts[0].fX, pts[1].fX),
53 SkScalarAve(pts[0].fY, pts[1].fY));
54 return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
55 data.fPos, data.fCount, mapper);
56 }
57
Make2Radial(const SkPoint pts[2],const GradData & data,SkShader::TileMode tm,SkUnitMapper * mapper)58 static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
59 SkShader::TileMode tm, SkUnitMapper* mapper) {
60 SkPoint center0, center1;
61 center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
62 SkScalarAve(pts[0].fY, pts[1].fY));
63 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
64 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
65 return SkGradientShader::CreateTwoPointRadial(
66 center1, (pts[1].fX - pts[0].fX) / 7,
67 center0, (pts[1].fX - pts[0].fX) / 2,
68 data.fColors, data.fPos, data.fCount, tm, mapper);
69 }
70
71 typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
72 SkShader::TileMode tm, SkUnitMapper* mapper);
73
74 static const struct {
75 GradMaker fMaker;
76 const char* fName;
77 int fRepeat;
78 } gGrads[] = {
79 { MakeLinear, "linear", 15 },
80 { MakeRadial, "radial1", 10 },
81 { MakeSweep, "sweep", 1 },
82 { Make2Radial, "radial2", 5 },
83 };
84
85 enum GradType { // these must match the order in gGrads
86 kLinear_GradType,
87 kRadial_GradType,
88 kSweep_GradType,
89 kRadial2_GradType
90 };
91
92 ///////////////////////////////////////////////////////////////////////////////
93
94 class GradientBench : public SkBenchmark {
95 SkString fName;
96 SkShader* fShader;
97 int fCount;
98 enum {
99 W = 400,
100 H = 400,
101 N = 1
102 };
103 public:
GradientBench(void * param,GradType gt)104 GradientBench(void* param, GradType gt) : INHERITED(param) {
105 fName.printf("gradient_%s", gGrads[gt].fName);
106
107 const SkPoint pts[2] = {
108 { 0, 0 },
109 { SkIntToScalar(W), SkIntToScalar(H) }
110 };
111
112 fCount = N * gGrads[gt].fRepeat;
113 fShader = gGrads[gt].fMaker(pts, gGradData[0],
114 SkShader::kClamp_TileMode, NULL);
115 }
116
~GradientBench()117 virtual ~GradientBench() {
118 fShader->unref();
119 }
120
121 protected:
onGetName()122 virtual const char* onGetName() {
123 return fName.c_str();
124 }
125
onDraw(SkCanvas * canvas)126 virtual void onDraw(SkCanvas* canvas) {
127 SkPaint paint;
128 this->setupPaint(&paint);
129
130 paint.setShader(fShader);
131
132 SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
133 for (int i = 0; i < fCount; i++) {
134 canvas->drawRect(r, paint);
135 }
136 }
137
138 private:
139 typedef SkBenchmark INHERITED;
140 };
141
Fact0(void * p)142 static SkBenchmark* Fact0(void* p) { return new GradientBench(p, kLinear_GradType); }
Fact1(void * p)143 static SkBenchmark* Fact1(void* p) { return new GradientBench(p, kRadial_GradType); }
Fact2(void * p)144 static SkBenchmark* Fact2(void* p) { return new GradientBench(p, kSweep_GradType); }
Fact3(void * p)145 static SkBenchmark* Fact3(void* p) { return new GradientBench(p, kRadial2_GradType); }
146
147 static BenchRegistry gReg0(Fact0);
148 static BenchRegistry gReg1(Fact1);
149 static BenchRegistry gReg2(Fact2);
150 static BenchRegistry gReg3(Fact3);
151
152