blob: 7b413c4677d3ba64d5f95331db3b65c69edc5a29 [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
tfarinaf168b862014-06-19 12:32:29 -07008#include "Benchmark.h"
egdaniel@google.coma3088832013-07-17 19:30:41 +00009#include "SkCanvas.h"
10#include "SkPaint.h"
11#include "SkRandom.h"
12#include "SkShader.h"
13#include "SkString.h"
14
commit-bot@chromium.orgd58c9c82014-02-19 19:30:42 +000015#if SK_SUPPORT_GPU
commit-bot@chromium.orgd58c9c82014-02-19 19:30:42 +000016#include "GrDrawTargetCaps.h"
tfarinaf168b862014-06-19 12:32:29 -070017#include "GrTest.h"
commit-bot@chromium.orgd58c9c82014-02-19 19:30:42 +000018#endif
19
egdaniel@google.coma3088832013-07-17 19:30:41 +000020enum Flags {
21 kBig_Flag = 1 << 0,
22 kAA_Flag = 1 << 1
23};
24
25#define FLAGS00 Flags(0)
26#define FLAGS01 Flags(kBig_Flag)
27#define FLAGS10 Flags(kAA_Flag)
28#define FLAGS11 Flags(kBig_Flag | kAA_Flag)
29
30static const int points[] = {
31 10, 10, 15, 5, 20, 20,
32 30, 5, 25, 20, 15, 12,
33 21, 21, 30, 30, 12, 4,
34 32, 28, 20, 18, 12, 10
35};
36
37static const int kMaxPathSize = 10;
38
tfarinaf168b862014-06-19 12:32:29 -070039class HairlinePathBench : public Benchmark {
egdaniel@google.coma3088832013-07-17 19:30:41 +000040public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000041 HairlinePathBench(Flags flags) : fFlags(flags) {
egdaniel@google.coma3088832013-07-17 19:30:41 +000042 fPaint.setStyle(SkPaint::kStroke_Style);
43 fPaint.setStrokeWidth(SkIntToScalar(0));
44 }
45
46 virtual void appendName(SkString*) = 0;
47 virtual void makePath(SkPath*) = 0;
48
49protected:
50 virtual const char* onGetName() SK_OVERRIDE {
51 fName.printf("path_hairline_%s_%s_",
52 fFlags & kBig_Flag ? "big" : "small",
53 fFlags & kAA_Flag ? "AA" : "noAA");
54 this->appendName(&fName);
55 return fName.c_str();
56 }
57
commit-bot@chromium.org33614712013-12-03 18:17:16 +000058 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
egdaniel@google.coma3088832013-07-17 19:30:41 +000059 SkPaint paint(fPaint);
60 this->setupPaint(&paint);
61
62 paint.setAntiAlias(fFlags & kAA_Flag ? true : false);
skia.committer@gmail.comf7d01ce2013-07-18 07:00:56 +000063
egdaniel@google.coma3088832013-07-17 19:30:41 +000064 SkPath path;
65 this->makePath(&path);
66 if (fFlags & kBig_Flag) {
67 SkMatrix m;
68 m.setScale(SkIntToScalar(3), SkIntToScalar(3));
69 path.transform(m);
70 }
71
commit-bot@chromium.org33614712013-12-03 18:17:16 +000072 for (int i = 0; i < loops; i++) {
egdaniel@google.coma3088832013-07-17 19:30:41 +000073 canvas->drawPath(path, paint);
74 }
75 }
76
77private:
78 SkPaint fPaint;
79 SkString fName;
80 Flags fFlags;
tfarinaf168b862014-06-19 12:32:29 -070081 typedef Benchmark INHERITED;
egdaniel@google.coma3088832013-07-17 19:30:41 +000082};
83
84class LinePathBench : public HairlinePathBench {
85public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000086 LinePathBench(Flags flags) : INHERITED(flags) {}
egdaniel@google.coma3088832013-07-17 19:30:41 +000087
88 virtual void appendName(SkString* name) SK_OVERRIDE {
89 name->append("line");
90 }
91 virtual void makePath(SkPath* path) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +000092 SkRandom rand;
egdaniel@google.coma3088832013-07-17 19:30:41 +000093 int size = SK_ARRAY_COUNT(points);
94 int hSize = size / 2;
95 for (int i = 0; i < kMaxPathSize; ++i) {
96 int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
97 int yTrans = 0;
98 if (i > kMaxPathSize/2 - 1) {
99 yTrans = 40;
100 }
101 int base1 = 2 * rand.nextULessThan(hSize);
102 int base2 = 2 * rand.nextULessThan(hSize);
103 int base3 = 2 * rand.nextULessThan(hSize);
104 path->moveTo(SkIntToScalar(points[base1] + xTrans),
105 SkIntToScalar(points[base1+1] + yTrans));
106 path->lineTo(SkIntToScalar(points[base2] + xTrans),
107 SkIntToScalar(points[base2+1] + yTrans));
108 path->lineTo(SkIntToScalar(points[base3] + xTrans),
109 SkIntToScalar(points[base3+1] + yTrans));
110 }
111 }
112private:
113 typedef HairlinePathBench INHERITED;
114};
115
116class QuadPathBench : public HairlinePathBench {
117public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000118 QuadPathBench(Flags flags) : INHERITED(flags) {}
egdaniel@google.coma3088832013-07-17 19:30:41 +0000119
120 virtual void appendName(SkString* name) SK_OVERRIDE {
121 name->append("quad");
122 }
123 virtual void makePath(SkPath* path) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000124 SkRandom rand;
egdaniel@google.coma3088832013-07-17 19:30:41 +0000125 int size = SK_ARRAY_COUNT(points);
126 int hSize = size / 2;
127 for (int i = 0; i < kMaxPathSize; ++i) {
128 int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
129 int yTrans = 0;
130 if (i > kMaxPathSize/2 - 1) {
131 yTrans = 40;
132 }
133 int base1 = 2 * rand.nextULessThan(hSize);
134 int base2 = 2 * rand.nextULessThan(hSize);
135 int base3 = 2 * rand.nextULessThan(hSize);
136 path->moveTo(SkIntToScalar(points[base1] + xTrans),
137 SkIntToScalar(points[base1+1] + yTrans));
138 path->quadTo(SkIntToScalar(points[base2] + xTrans),
139 SkIntToScalar(points[base2+1] + yTrans),
140 SkIntToScalar(points[base3] + xTrans),
141 SkIntToScalar(points[base3+1] + yTrans));
142 }
143 }
144private:
145 typedef HairlinePathBench INHERITED;
146};
147
148class ConicPathBench : public HairlinePathBench {
149public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000150 ConicPathBench(Flags flags) : INHERITED(flags) {}
egdaniel@google.coma3088832013-07-17 19:30:41 +0000151
152 virtual void appendName(SkString* name) SK_OVERRIDE {
153 name->append("conic");
154 }
155 virtual void makePath(SkPath* path) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000156 SkRandom rand;
157 SkRandom randWeight;
egdaniel@google.coma3088832013-07-17 19:30:41 +0000158 int size = SK_ARRAY_COUNT(points);
159 int hSize = size / 2;
160 for (int i = 0; i < kMaxPathSize; ++i) {
161 int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
162 int yTrans = 0;
163 if (i > kMaxPathSize/2 - 1) {
164 yTrans = 40;
165 }
166 int base1 = 2 * rand.nextULessThan(hSize);
167 int base2 = 2 * rand.nextULessThan(hSize);
168 int base3 = 2 * rand.nextULessThan(hSize);
169 float weight = randWeight.nextRangeF(0.0f, 2.0f);
170 path->moveTo(SkIntToScalar(points[base1] + xTrans),
171 SkIntToScalar(points[base1+1] + yTrans));
172 path->conicTo(SkIntToScalar(points[base2] + xTrans),
173 SkIntToScalar(points[base2+1] + yTrans),
174 SkIntToScalar(points[base3] + xTrans),
175 SkIntToScalar(points[base3+1] + yTrans),
176 weight);
177 }
178 }
commit-bot@chromium.org78dd91d2014-01-27 19:52:51 +0000179
180 virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
181#if SK_SUPPORT_GPU
182 GrContext* context = canvas->getGrContext();
183 // This is a workaround for skbug.com/2078. See also skbug.com/2033.
bsalomon49f085d2014-09-05 13:34:00 -0700184 if (context) {
commit-bot@chromium.org78dd91d2014-01-27 19:52:51 +0000185 GrTestTarget tt;
186 context->getTestTarget(&tt);
187 if (tt.target()->caps()->pathRenderingSupport()) {
188 return;
189 }
190 }
191#endif
192 INHERITED::onDraw(loops, canvas);
193 }
194
egdaniel@google.coma3088832013-07-17 19:30:41 +0000195private:
196 typedef HairlinePathBench INHERITED;
197};
198
199class CubicPathBench : public HairlinePathBench {
200public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000201 CubicPathBench(Flags flags) : INHERITED(flags) {}
egdaniel@google.coma3088832013-07-17 19:30:41 +0000202
203 virtual void appendName(SkString* name) SK_OVERRIDE {
204 name->append("cubic");
205 }
206 virtual void makePath(SkPath* path) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000207 SkRandom rand;
egdaniel@google.coma3088832013-07-17 19:30:41 +0000208 int size = SK_ARRAY_COUNT(points);
209 int hSize = size / 2;
210 for (int i = 0; i < kMaxPathSize; ++i) {
211 int xTrans = 10 + 40 * (i%(kMaxPathSize/2));
212 int yTrans = 0;
213 if (i > kMaxPathSize/2 - 1) {
214 yTrans = 40;
215 }
216 int base1 = 2 * rand.nextULessThan(hSize);
217 int base2 = 2 * rand.nextULessThan(hSize);
218 int base3 = 2 * rand.nextULessThan(hSize);
219 int base4 = 2 * rand.nextULessThan(hSize);
220 path->moveTo(SkIntToScalar(points[base1] + xTrans),
221 SkIntToScalar(points[base1+1] + yTrans));
222 path->cubicTo(SkIntToScalar(points[base2] + xTrans),
223 SkIntToScalar(points[base2+1] + yTrans),
224 SkIntToScalar(points[base3] + xTrans),
225 SkIntToScalar(points[base3+1] + yTrans),
226 SkIntToScalar(points[base4] + xTrans),
227 SkIntToScalar(points[base4+1] + yTrans));
228 }
229 }
230private:
231 typedef HairlinePathBench INHERITED;
232};
233
234// FLAG00 - no AA, small
235// FLAG01 - no AA, small
236// FLAG10 - AA, big
237// FLAG11 - AA, big
238
mtklein@google.com410e6e82013-09-13 19:52:27 +0000239DEF_BENCH( return new LinePathBench(FLAGS00); )
240DEF_BENCH( return new LinePathBench(FLAGS01); )
241DEF_BENCH( return new LinePathBench(FLAGS10); )
242DEF_BENCH( return new LinePathBench(FLAGS11); )
egdaniel@google.coma3088832013-07-17 19:30:41 +0000243
mtklein@google.com410e6e82013-09-13 19:52:27 +0000244DEF_BENCH( return new QuadPathBench(FLAGS00); )
245DEF_BENCH( return new QuadPathBench(FLAGS01); )
246DEF_BENCH( return new QuadPathBench(FLAGS10); )
247DEF_BENCH( return new QuadPathBench(FLAGS11); )
egdaniel@google.coma3088832013-07-17 19:30:41 +0000248
249// Don't have default path renderer for conics yet on GPU, so must use AA
mtklein@google.com410e6e82013-09-13 19:52:27 +0000250// DEF_BENCH( return new ConicPathBench(FLAGS00); )
251// DEF_BENCH( return new ConicPathBench(FLAGS01); )
252DEF_BENCH( return new ConicPathBench(FLAGS10); )
253DEF_BENCH( return new ConicPathBench(FLAGS11); )
egdaniel@google.coma3088832013-07-17 19:30:41 +0000254
mtklein@google.com410e6e82013-09-13 19:52:27 +0000255DEF_BENCH( return new CubicPathBench(FLAGS00); )
256DEF_BENCH( return new CubicPathBench(FLAGS01); )
257DEF_BENCH( return new CubicPathBench(FLAGS10); )
258DEF_BENCH( return new CubicPathBench(FLAGS11); )