blob: 16edcc7c17acaaaaed4b7fa41f334e7f2eb54fd7 [file] [log] [blame]
egdaniel@google.coma3088832013-07-17 19:30:41 +00001/*
2 * Copyright 2013 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 */
commit-bot@chromium.org78dd91d2014-01-27 19:52:51 +00007
8#if SK_SUPPORT_GPU
9#include "GrTest.h"
10#include "GrDrawTargetCaps.h"
11#endif
egdaniel@google.coma3088832013-07-17 19:30:41 +000012#include "SkBenchmark.h"
13#include "SkCanvas.h"
14#include "SkPaint.h"
15#include "SkRandom.h"
16#include "SkShader.h"
17#include "SkString.h"
18
19enum Flags {
20 kBig_Flag = 1 << 0,
21 kAA_Flag = 1 << 1
22};
23
24#define FLAGS00 Flags(0)
25#define FLAGS01 Flags(kBig_Flag)
26#define FLAGS10 Flags(kAA_Flag)
27#define FLAGS11 Flags(kBig_Flag | kAA_Flag)
28
29static const int points[] = {
30 10, 10, 15, 5, 20, 20,
31 30, 5, 25, 20, 15, 12,
32 21, 21, 30, 30, 12, 4,
33 32, 28, 20, 18, 12, 10
34};
35
36static const int kMaxPathSize = 10;
37
38class HairlinePathBench : public SkBenchmark {
39public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000040 HairlinePathBench(Flags flags) : fFlags(flags) {
egdaniel@google.coma3088832013-07-17 19:30:41 +000041 fPaint.setStyle(SkPaint::kStroke_Style);
42 fPaint.setStrokeWidth(SkIntToScalar(0));
43 }
44
45 virtual void appendName(SkString*) = 0;
46 virtual void makePath(SkPath*) = 0;
47
48protected:
49 virtual const char* onGetName() SK_OVERRIDE {
50 fName.printf("path_hairline_%s_%s_",
51 fFlags & kBig_Flag ? "big" : "small",
52 fFlags & kAA_Flag ? "AA" : "noAA");
53 this->appendName(&fName);
54 return fName.c_str();
55 }
56
commit-bot@chromium.org33614712013-12-03 18:17:16 +000057 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
egdaniel@google.coma3088832013-07-17 19:30:41 +000058 SkPaint paint(fPaint);
59 this->setupPaint(&paint);
60
61 paint.setAntiAlias(fFlags & kAA_Flag ? true : false);
skia.committer@gmail.comf7d01ce2013-07-18 07:00:56 +000062
egdaniel@google.coma3088832013-07-17 19:30:41 +000063 SkPath path;
64 this->makePath(&path);
65 if (fFlags & kBig_Flag) {
66 SkMatrix m;
67 m.setScale(SkIntToScalar(3), SkIntToScalar(3));
68 path.transform(m);
69 }
70
commit-bot@chromium.org33614712013-12-03 18:17:16 +000071 for (int i = 0; i < loops; i++) {
egdaniel@google.coma3088832013-07-17 19:30:41 +000072 canvas->drawPath(path, paint);
73 }
74 }
75
76private:
77 SkPaint fPaint;
78 SkString fName;
79 Flags fFlags;
egdaniel@google.coma3088832013-07-17 19:30:41 +000080 typedef SkBenchmark INHERITED;
81};
82
83class LinePathBench : public HairlinePathBench {
84public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000085 LinePathBench(Flags flags) : INHERITED(flags) {}
egdaniel@google.coma3088832013-07-17 19:30:41 +000086
87 virtual void appendName(SkString* name) SK_OVERRIDE {
88 name->append("line");
89 }
90 virtual void makePath(SkPath* path) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000091 SkRandom rand;
egdaniel@google.coma3088832013-07-17 19:30:41 +000092 int size = SK_ARRAY_COUNT(points);
93 int hSize = size / 2;
94 for (int i = 0; i < kMaxPathSize; ++i) {
95 int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
96 int yTrans = 0;
97 if (i > kMaxPathSize/2 - 1) {
98 yTrans = 40;
99 }
100 int base1 = 2 * rand.nextULessThan(hSize);
101 int base2 = 2 * rand.nextULessThan(hSize);
102 int base3 = 2 * rand.nextULessThan(hSize);
103 path->moveTo(SkIntToScalar(points[base1] + xTrans),
104 SkIntToScalar(points[base1+1] + yTrans));
105 path->lineTo(SkIntToScalar(points[base2] + xTrans),
106 SkIntToScalar(points[base2+1] + yTrans));
107 path->lineTo(SkIntToScalar(points[base3] + xTrans),
108 SkIntToScalar(points[base3+1] + yTrans));
109 }
110 }
111private:
112 typedef HairlinePathBench INHERITED;
113};
114
115class QuadPathBench : public HairlinePathBench {
116public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000117 QuadPathBench(Flags flags) : INHERITED(flags) {}
egdaniel@google.coma3088832013-07-17 19:30:41 +0000118
119 virtual void appendName(SkString* name) SK_OVERRIDE {
120 name->append("quad");
121 }
122 virtual void makePath(SkPath* path) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000123 SkRandom rand;
egdaniel@google.coma3088832013-07-17 19:30:41 +0000124 int size = SK_ARRAY_COUNT(points);
125 int hSize = size / 2;
126 for (int i = 0; i < kMaxPathSize; ++i) {
127 int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
128 int yTrans = 0;
129 if (i > kMaxPathSize/2 - 1) {
130 yTrans = 40;
131 }
132 int base1 = 2 * rand.nextULessThan(hSize);
133 int base2 = 2 * rand.nextULessThan(hSize);
134 int base3 = 2 * rand.nextULessThan(hSize);
135 path->moveTo(SkIntToScalar(points[base1] + xTrans),
136 SkIntToScalar(points[base1+1] + yTrans));
137 path->quadTo(SkIntToScalar(points[base2] + xTrans),
138 SkIntToScalar(points[base2+1] + yTrans),
139 SkIntToScalar(points[base3] + xTrans),
140 SkIntToScalar(points[base3+1] + yTrans));
141 }
142 }
143private:
144 typedef HairlinePathBench INHERITED;
145};
146
147class ConicPathBench : public HairlinePathBench {
148public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000149 ConicPathBench(Flags flags) : INHERITED(flags) {}
egdaniel@google.coma3088832013-07-17 19:30:41 +0000150
151 virtual void appendName(SkString* name) SK_OVERRIDE {
152 name->append("conic");
153 }
154 virtual void makePath(SkPath* path) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000155 SkRandom rand;
156 SkRandom randWeight;
egdaniel@google.coma3088832013-07-17 19:30:41 +0000157 int size = SK_ARRAY_COUNT(points);
158 int hSize = size / 2;
159 for (int i = 0; i < kMaxPathSize; ++i) {
160 int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
161 int yTrans = 0;
162 if (i > kMaxPathSize/2 - 1) {
163 yTrans = 40;
164 }
165 int base1 = 2 * rand.nextULessThan(hSize);
166 int base2 = 2 * rand.nextULessThan(hSize);
167 int base3 = 2 * rand.nextULessThan(hSize);
168 float weight = randWeight.nextRangeF(0.0f, 2.0f);
169 path->moveTo(SkIntToScalar(points[base1] + xTrans),
170 SkIntToScalar(points[base1+1] + yTrans));
171 path->conicTo(SkIntToScalar(points[base2] + xTrans),
172 SkIntToScalar(points[base2+1] + yTrans),
173 SkIntToScalar(points[base3] + xTrans),
174 SkIntToScalar(points[base3+1] + yTrans),
175 weight);
176 }
177 }
commit-bot@chromium.org78dd91d2014-01-27 19:52:51 +0000178
179 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
180#if SK_SUPPORT_GPU
181 GrContext* context = canvas->getGrContext();
182 // This is a workaround for skbug.com/2078. See also skbug.com/2033.
183 if (NULL != context) {
184 GrTestTarget tt;
185 context->getTestTarget(&tt);
186 if (tt.target()->caps()->pathRenderingSupport()) {
187 return;
188 }
189 }
190#endif
191 INHERITED::onDraw(loops, canvas);
192 }
193
egdaniel@google.coma3088832013-07-17 19:30:41 +0000194private:
195 typedef HairlinePathBench INHERITED;
196};
197
198class CubicPathBench : public HairlinePathBench {
199public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000200 CubicPathBench(Flags flags) : INHERITED(flags) {}
egdaniel@google.coma3088832013-07-17 19:30:41 +0000201
202 virtual void appendName(SkString* name) SK_OVERRIDE {
203 name->append("cubic");
204 }
205 virtual void makePath(SkPath* path) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000206 SkRandom rand;
egdaniel@google.coma3088832013-07-17 19:30:41 +0000207 int size = SK_ARRAY_COUNT(points);
208 int hSize = size / 2;
209 for (int i = 0; i < kMaxPathSize; ++i) {
210 int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
211 int yTrans = 0;
212 if (i > kMaxPathSize/2 - 1) {
213 yTrans = 40;
214 }
215 int base1 = 2 * rand.nextULessThan(hSize);
216 int base2 = 2 * rand.nextULessThan(hSize);
217 int base3 = 2 * rand.nextULessThan(hSize);
218 int base4 = 2 * rand.nextULessThan(hSize);
219 path->moveTo(SkIntToScalar(points[base1] + xTrans),
220 SkIntToScalar(points[base1+1] + yTrans));
221 path->cubicTo(SkIntToScalar(points[base2] + xTrans),
222 SkIntToScalar(points[base2+1] + yTrans),
223 SkIntToScalar(points[base3] + xTrans),
224 SkIntToScalar(points[base3+1] + yTrans),
225 SkIntToScalar(points[base4] + xTrans),
226 SkIntToScalar(points[base4+1] + yTrans));
227 }
228 }
229private:
230 typedef HairlinePathBench INHERITED;
231};
232
233// FLAG00 - no AA, small
234// FLAG01 - no AA, small
235// FLAG10 - AA, big
236// FLAG11 - AA, big
237
mtklein@google.com410e6e82013-09-13 19:52:27 +0000238DEF_BENCH( return new LinePathBench(FLAGS00); )
239DEF_BENCH( return new LinePathBench(FLAGS01); )
240DEF_BENCH( return new LinePathBench(FLAGS10); )
241DEF_BENCH( return new LinePathBench(FLAGS11); )
egdaniel@google.coma3088832013-07-17 19:30:41 +0000242
mtklein@google.com410e6e82013-09-13 19:52:27 +0000243DEF_BENCH( return new QuadPathBench(FLAGS00); )
244DEF_BENCH( return new QuadPathBench(FLAGS01); )
245DEF_BENCH( return new QuadPathBench(FLAGS10); )
246DEF_BENCH( return new QuadPathBench(FLAGS11); )
egdaniel@google.coma3088832013-07-17 19:30:41 +0000247
248// Don't have default path renderer for conics yet on GPU, so must use AA
mtklein@google.com410e6e82013-09-13 19:52:27 +0000249// DEF_BENCH( return new ConicPathBench(FLAGS00); )
250// DEF_BENCH( return new ConicPathBench(FLAGS01); )
251DEF_BENCH( return new ConicPathBench(FLAGS10); )
252DEF_BENCH( return new ConicPathBench(FLAGS11); )
egdaniel@google.coma3088832013-07-17 19:30:41 +0000253
mtklein@google.com410e6e82013-09-13 19:52:27 +0000254DEF_BENCH( return new CubicPathBench(FLAGS00); )
255DEF_BENCH( return new CubicPathBench(FLAGS01); )
256DEF_BENCH( return new CubicPathBench(FLAGS10); )
257DEF_BENCH( return new CubicPathBench(FLAGS11); )