blob: 7681d90084ae589ad3fceacf1a2820ec88780b54 [file] [log] [blame]
Chris Dalton7f0b8972020-04-23 15:52:24 -06001/*
2 * Copyright 2020 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
8#include "bench/Benchmark.h"
Robert Phillipsf0288102020-07-06 13:45:34 -04009#include "include/gpu/GrDirectContext.h"
Chris Daltonf6bf5162020-05-13 19:18:46 -060010#include "src/core/SkPathPriv.h"
Chris Dalton8447f132021-05-21 15:54:23 -060011#include "src/core/SkRectPriv.h"
Adlai Hollera0693042020-10-14 11:23:11 -040012#include "src/gpu/GrDirectContextPriv.h"
Michael Ludwig4e9d5e22021-05-11 10:00:12 -040013#include "src/gpu/geometry/GrWangsFormula.h"
Chris Dalton90ad0fe2020-11-09 14:13:39 -070014#include "src/gpu/mock/GrMockOpTarget.h"
Chris Daltonb5391d92020-05-24 14:55:54 -060015#include "src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h"
Chris Daltond9bdc322021-06-01 19:22:05 -060016#include "src/gpu/tessellate/GrPathCurveTessellator.h"
Chris Daltond9bdc322021-06-01 19:22:05 -060017#include "src/gpu/tessellate/GrPathWedgeTessellator.h"
Chris Dalton82007f52021-04-20 00:45:50 -060018#include "src/gpu/tessellate/GrStrokeFixedCountTessellator.h"
Chris Dalton22241002021-02-04 09:47:40 -070019#include "src/gpu/tessellate/GrStrokeHardwareTessellator.h"
Chris Daltonf5132a02020-04-27 23:40:03 -060020#include "tools/ToolUtils.h"
Chris Daltonc2a17462020-12-09 16:46:22 -070021#include <vector>
Chris Dalton7f0b8972020-04-23 15:52:24 -060022
Chris Dalton3b412782021-06-01 13:40:03 -060023using ShaderFlags = GrStrokeTessellationShader::ShaderFlags;
Chris Dalton42582fc2021-02-18 11:29:49 -070024
Chris Dalton7f0b8972020-04-23 15:52:24 -060025// This is the number of cubics in desk_chalkboard.skp. (There are no quadratics in the chalkboard.)
26constexpr static int kNumCubicsInChalkboard = 47182;
27
Chris Dalton90ad0fe2020-11-09 14:13:39 -070028static sk_sp<GrDirectContext> make_mock_context() {
29 GrMockOptions mockOptions;
30 mockOptions.fDrawInstancedSupport = true;
31 mockOptions.fMaxTessellationSegments = 64;
32 mockOptions.fMapBufferFlags = GrCaps::kCanMap_MapFlag;
33 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_8].fRenderability =
34 GrMockOptions::ConfigOptions::Renderability::kMSAA;
35 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_8].fTexturable = true;
36 mockOptions.fIntegerSupport = true;
37
38 GrContextOptions ctxOptions;
39 ctxOptions.fGpuPathRenderers = GpuPathRenderers::kTessellation;
Chris Dalton4ac9aad2021-02-24 17:41:44 -070040 ctxOptions.fEnableExperimentalHardwareTessellation = true;
Chris Dalton90ad0fe2020-11-09 14:13:39 -070041
42 return GrDirectContext::MakeMock(&mockOptions, ctxOptions);
43}
44
Chris Dalton8447f132021-05-21 15:54:23 -060045static SkPath make_cubic_path(int maxPow2) {
Chris Dalton7f0b8972020-04-23 15:52:24 -060046 SkRandom rand;
47 SkPath path;
48 for (int i = 0; i < kNumCubicsInChalkboard/2; ++i) {
Chris Dalton8447f132021-05-21 15:54:23 -060049 float x = std::ldexp(rand.nextF(), (i % maxPow2)) / 1e3f;
Chris Dalton7f0b8972020-04-23 15:52:24 -060050 path.cubicTo(111.625f*x, 308.188f*x, 764.62f*x, -435.688f*x, 742.63f*x, 85.187f*x);
51 path.cubicTo(764.62f*x, -435.688f*x, 111.625f*x, 308.188f*x, 0, 0);
52 }
53 return path;
54}
55
Tyler Denniston04f471a2021-02-04 13:07:03 -050056static SkPath make_conic_path() {
57 SkRandom rand;
58 SkPath path;
59 for (int i = 0; i < kNumCubicsInChalkboard / 40; ++i) {
60 for (int j = -10; j <= 10; j++) {
61 const float x = std::ldexp(rand.nextF(), (i % 18)) / 1e3f;
62 const float w = std::ldexp(1 + rand.nextF(), j);
63 path.conicTo(111.625f * x, 308.188f * x, 764.62f * x, -435.688f * x, w);
64 }
65 }
66 return path;
67}
68
Robert Phillips62bd6332021-08-26 09:56:55 -040069// This serves as a base class for benchmarking individual methods on PathTessellateOp.
Chris Daltond7177432021-01-15 13:12:50 -070070class PathTessellateBenchmark : public Benchmark {
Chris Dalton7f0b8972020-04-23 15:52:24 -060071public:
Chris Daltond7177432021-01-15 13:12:50 -070072 PathTessellateBenchmark(const char* subName, const SkPath& p, const SkMatrix& m)
73 : fPath(p), fMatrix(m) {
Chris Dalton7f0b8972020-04-23 15:52:24 -060074 fName.printf("tessellate_%s", subName);
75 }
76
77 const char* onGetName() override { return fName.c_str(); }
78 bool isSuitableFor(Backend backend) final { return backend == kNonRendering_Backend; }
79
Chris Daltond7177432021-01-15 13:12:50 -070080protected:
Chris Dalton0e543092020-11-03 14:09:16 -070081 void onDelayedSetup() override {
Chris Dalton90ad0fe2020-11-09 14:13:39 -070082 fTarget = std::make_unique<GrMockOpTarget>(make_mock_context());
Chris Dalton0e543092020-11-03 14:09:16 -070083 }
84
Chris Dalton7f0b8972020-04-23 15:52:24 -060085 void onDraw(int loops, SkCanvas*) final {
Chris Dalton0e543092020-11-03 14:09:16 -070086 if (!fTarget->mockContext()) {
Chris Dalton1443c9d2020-05-27 09:43:34 -060087 SkDebugf("ERROR: could not create mock context.");
88 return;
89 }
Chris Dalton7f0b8972020-04-23 15:52:24 -060090 for (int i = 0; i < loops; ++i) {
Chris Daltond7177432021-01-15 13:12:50 -070091 this->runBench();
Chris Dalton0e543092020-11-03 14:09:16 -070092 fTarget->resetAllocator();
Chris Dalton7f0b8972020-04-23 15:52:24 -060093 }
94 }
95
Chris Daltond7177432021-01-15 13:12:50 -070096 virtual void runBench() = 0;
Chris Dalton7f0b8972020-04-23 15:52:24 -060097
Chris Dalton7f0b8972020-04-23 15:52:24 -060098 SkString fName;
Chris Daltond7177432021-01-15 13:12:50 -070099 std::unique_ptr<GrMockOpTarget> fTarget;
100 const SkPath fPath;
Chris Daltone1314a32021-01-29 13:22:33 -0700101 const SkMatrix fMatrix;
Chris Dalton7f0b8972020-04-23 15:52:24 -0600102};
103
Chris Daltond7177432021-01-15 13:12:50 -0700104#define DEF_PATH_TESS_BENCH(NAME, PATH, MATRIX) \
105 class PathTessellateBenchmark_##NAME : public PathTessellateBenchmark { \
Chris Daltonb5391d92020-05-24 14:55:54 -0600106 public: \
Chris Daltond7177432021-01-15 13:12:50 -0700107 PathTessellateBenchmark_##NAME() : PathTessellateBenchmark(#NAME, (PATH), (MATRIX)) {} \
108 void runBench() override; \
Chris Daltonb5391d92020-05-24 14:55:54 -0600109 }; \
Chris Daltond7177432021-01-15 13:12:50 -0700110 DEF_BENCH( return new PathTessellateBenchmark_##NAME(); ); \
111 void PathTessellateBenchmark_##NAME::runBench()
Chris Dalton7f0b8972020-04-23 15:52:24 -0600112
Chris Dalton69669812021-07-27 10:00:12 -0600113static const SkMatrix gAlmostIdentity = SkMatrix::MakeAll(
114 1.0001f, 0.0001f, 0.0001f,
115 -.0001f, 0.9999f, -.0001f,
116 0, 0, 1);
117
118DEF_PATH_TESS_BENCH(GrPathCurveTessellator, make_cubic_path(8), SkMatrix::I()) {
Chris Dalton569c01b2021-05-25 10:11:46 -0600119 SkArenaAlloc arena(1024);
Chris Dalton198ac152021-06-09 13:49:43 -0600120 GrPipeline noVaryingsPipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
121 GrSwizzle::RGBA());
Chris Daltond9bdc322021-06-01 19:22:05 -0600122 auto tess = GrPathCurveTessellator::Make(&arena, fMatrix, SK_PMColor4fTRANSPARENT,
Chris Dalton73915112021-06-09 16:28:11 -0600123 GrPathCurveTessellator::DrawInnerFan::kNo,
Chris Dalton26666bd2021-06-08 16:25:46 -0600124 fTarget->caps().minPathVerbsForHwTessellation(),
Chris Dalton198ac152021-06-09 13:49:43 -0600125 noVaryingsPipeline, fTarget->caps());
Chris Dalton17eaf622021-07-28 09:43:52 -0600126 tess->prepare(fTarget.get(), SkRectPriv::MakeLargest(), {gAlmostIdentity, fPath},
127 fPath.countVerbs());
Chris Daltonb5391d92020-05-24 14:55:54 -0600128}
Chris Dalton7f0b8972020-04-23 15:52:24 -0600129
Chris Dalton8447f132021-05-21 15:54:23 -0600130DEF_PATH_TESS_BENCH(GrPathWedgeTessellator, make_cubic_path(8), SkMatrix::I()) {
Chris Dalton569c01b2021-05-25 10:11:46 -0600131 SkArenaAlloc arena(1024);
Chris Dalton198ac152021-06-09 13:49:43 -0600132 GrPipeline noVaryingsPipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
133 GrSwizzle::RGBA());
Chris Daltond2b8ba32021-06-09 00:12:59 -0600134 auto tess = GrPathWedgeTessellator::Make(&arena, fMatrix, SK_PMColor4fTRANSPARENT,
135 fTarget->caps().minPathVerbsForHwTessellation(),
Chris Dalton198ac152021-06-09 13:49:43 -0600136 noVaryingsPipeline, fTarget->caps());
Chris Dalton17eaf622021-07-28 09:43:52 -0600137 tess->prepare(fTarget.get(), SkRectPriv::MakeLargest(), {gAlmostIdentity, fPath},
138 fPath.countVerbs());
Chris Daltonb5391d92020-05-24 14:55:54 -0600139}
Chris Daltonf6bf5162020-05-13 19:18:46 -0600140
Chris Daltonb5391d92020-05-24 14:55:54 -0600141static void benchmark_wangs_formula_cubic_log2(const SkMatrix& matrix, const SkPath& path) {
142 int sum = 0;
143 GrVectorXform xform(matrix);
144 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
145 if (verb == SkPathVerb::kCubic) {
146 sum += GrWangsFormula::cubic_log2(4, pts, xform);
Chris Daltonf6bf5162020-05-13 19:18:46 -0600147 }
148 }
Chris Daltonb5391d92020-05-24 14:55:54 -0600149 // Don't let the compiler optimize away GrWangsFormula::cubic_log2.
150 if (sum <= 0) {
151 SK_ABORT("sum should be > 0.");
152 }
153}
Chris Daltonf6bf5162020-05-13 19:18:46 -0600154
Chris Dalton8447f132021-05-21 15:54:23 -0600155DEF_PATH_TESS_BENCH(wangs_formula_cubic_log2, make_cubic_path(18), SkMatrix::I()) {
Chris Daltond7177432021-01-15 13:12:50 -0700156 benchmark_wangs_formula_cubic_log2(fMatrix, fPath);
Chris Daltonb5391d92020-05-24 14:55:54 -0600157}
158
Chris Dalton8447f132021-05-21 15:54:23 -0600159DEF_PATH_TESS_BENCH(wangs_formula_cubic_log2_scale, make_cubic_path(18),
Chris Daltond7177432021-01-15 13:12:50 -0700160 SkMatrix::Scale(1.1f, 0.9f)) {
161 benchmark_wangs_formula_cubic_log2(fMatrix, fPath);
Chris Daltonb5391d92020-05-24 14:55:54 -0600162}
163
Chris Dalton8447f132021-05-21 15:54:23 -0600164DEF_PATH_TESS_BENCH(wangs_formula_cubic_log2_affine, make_cubic_path(18),
Chris Daltond7177432021-01-15 13:12:50 -0700165 SkMatrix::MakeAll(.9f,0.9f,0, 1.1f,1.1f,0, 0,0,1)) {
166 benchmark_wangs_formula_cubic_log2(fMatrix, fPath);
Chris Daltonb5391d92020-05-24 14:55:54 -0600167}
168
Tyler Denniston04f471a2021-02-04 13:07:03 -0500169static void benchmark_wangs_formula_conic(const SkMatrix& matrix, const SkPath& path) {
Tyler Denniston04f471a2021-02-04 13:07:03 -0500170 int sum = 0;
171 GrVectorXform xform(matrix);
172 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
173 if (verb == SkPathVerb::kConic) {
Chris Daltone6f45312021-06-02 12:00:01 -0600174 sum += GrWangsFormula::conic(4, pts, *w, xform);
Tyler Denniston04f471a2021-02-04 13:07:03 -0500175 }
176 }
177 // Don't let the compiler optimize away GrWangsFormula::conic.
178 if (sum <= 0) {
179 SK_ABORT("sum should be > 0.");
180 }
181}
182
183static void benchmark_wangs_formula_conic_log2(const SkMatrix& matrix, const SkPath& path) {
Tyler Denniston04f471a2021-02-04 13:07:03 -0500184 int sum = 0;
185 GrVectorXform xform(matrix);
186 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
187 if (verb == SkPathVerb::kConic) {
Chris Daltone6f45312021-06-02 12:00:01 -0600188 sum += GrWangsFormula::conic_log2(4, pts, *w, xform);
Tyler Denniston04f471a2021-02-04 13:07:03 -0500189 }
190 }
191 // Don't let the compiler optimize away GrWangsFormula::conic.
192 if (sum <= 0) {
193 SK_ABORT("sum should be > 0.");
194 }
195}
196
197DEF_PATH_TESS_BENCH(wangs_formula_conic, make_conic_path(), SkMatrix::I()) {
198 benchmark_wangs_formula_conic(fMatrix, fPath);
199}
200
201DEF_PATH_TESS_BENCH(wangs_formula_conic_log2, make_conic_path(), SkMatrix::I()) {
202 benchmark_wangs_formula_conic_log2(fMatrix, fPath);
203}
204
Chris Daltone2067642020-09-23 11:07:20 -0600205DEF_PATH_TESS_BENCH(middle_out_triangulation,
206 ToolUtils::make_star(SkRect::MakeWH(500, 500), kNumCubicsInChalkboard),
Chris Daltond7177432021-01-15 13:12:50 -0700207 SkMatrix::I()) {
Chris Dalton8ed7a8d2021-03-31 10:40:29 -0600208 sk_sp<const GrBuffer> buffer;
Chris Daltonb5391d92020-05-24 14:55:54 -0600209 int baseVertex;
Chris Dalton8731a712021-05-14 14:48:54 -0600210 GrVertexWriter vertexWriter = static_cast<SkPoint*>(fTarget->makeVertexSpace(
Chris Dalton8ed7a8d2021-03-31 10:40:29 -0600211 sizeof(SkPoint), kNumCubicsInChalkboard, &buffer, &baseVertex));
Chris Dalton40c906f2021-07-26 11:27:05 -0600212 int numTrianglesWritten;
Chris Dalton69669812021-07-27 10:00:12 -0600213 GrMiddleOutPolygonTriangulator::WritePathInnerFan(std::move(vertexWriter), 0, 0,
214 gAlmostIdentity, fPath, &numTrianglesWritten);
Chris Daltonb5391d92020-05-24 14:55:54 -0600215}
Chris Daltone2067642020-09-23 11:07:20 -0600216
Chris Dalton981e4a72021-02-22 12:13:49 -0700217using PathStrokeList = GrStrokeTessellator::PathStrokeList;
Chris Dalton13adb4a2021-05-26 10:21:56 -0600218using MakeTessellatorFn = std::unique_ptr<GrStrokeTessellator>(*)(ShaderFlags, const GrShaderCaps&,
219 const SkMatrix&, PathStrokeList*,
Chris Dalton0638df12021-05-14 15:57:39 -0600220 std::array<float, 2>, const
221 SkRect&);
Chris Dalton82007f52021-04-20 00:45:50 -0600222
Chris Dalton0638df12021-05-14 15:57:39 -0600223static std::unique_ptr<GrStrokeTessellator> make_hw_tessellator(
Chris Dalton13adb4a2021-05-26 10:21:56 -0600224 ShaderFlags shaderFlags, const GrShaderCaps& shaderCaps, const SkMatrix& viewMatrix,
225 PathStrokeList* pathStrokeList, std::array<float, 2> matrixMinMaxScales,
226 const SkRect& strokeCullBounds) {
Chris Dalton69043032021-07-01 11:17:53 -0600227 return std::make_unique<GrStrokeHardwareTessellator>(shaderCaps, shaderFlags, viewMatrix,
Chris Dalton13adb4a2021-05-26 10:21:56 -0600228 pathStrokeList, matrixMinMaxScales,
229 strokeCullBounds);
Chris Dalton82007f52021-04-20 00:45:50 -0600230}
231
232static std::unique_ptr<GrStrokeTessellator> make_fixed_count_tessellator(
Chris Daltonbb995e62021-07-01 10:58:55 -0600233 ShaderFlags shaderFlags, const GrShaderCaps& shaderCaps, const SkMatrix& viewMatrix,
Chris Dalton13adb4a2021-05-26 10:21:56 -0600234 PathStrokeList* pathStrokeList, std::array<float, 2> matrixMinMaxScales,
235 const SkRect& strokeCullBounds) {
Chris Dalton69043032021-07-01 11:17:53 -0600236 return std::make_unique<GrStrokeFixedCountTessellator>(shaderCaps, shaderFlags, viewMatrix,
237 pathStrokeList, matrixMinMaxScales,
238 strokeCullBounds);
Chris Dalton82007f52021-04-20 00:45:50 -0600239}
240
Chris Dalton981e4a72021-02-22 12:13:49 -0700241using MakePathStrokesFn = std::vector<PathStrokeList>(*)();
242
243static std::vector<PathStrokeList> make_simple_cubic_path() {
244 auto path = SkPath().moveTo(0, 0);
245 for (int i = 0; i < kNumCubicsInChalkboard/2; ++i) {
246 path.cubicTo(100, 0, 50, 100, 100, 100);
247 path.cubicTo(0, -100, 200, 100, 0, 0);
248 }
249 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
250 stroke.setStrokeStyle(8);
251 stroke.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kMiter_Join, 4);
252 return {{path, stroke, SK_PMColor4fWHITE}};
253}
254
255// Generates a list of paths that resemble the MotionMark benchmark.
256static std::vector<PathStrokeList> make_motionmark_paths() {
257 std::vector<PathStrokeList> pathStrokes;
258 SkRandom rand;
259 for (int i = 0; i < 8702; ++i) {
260 // The number of paths with a given number of verbs in the MotionMark bench gets cut in half
261 // every time the number of verbs increases by 1.
262 int numVerbs = 28 - SkNextLog2(rand.nextRangeU(0, (1 << 27) - 1));
263 SkPath path;
264 for (int j = 0; j < numVerbs; ++j) {
265 switch (rand.nextU() & 3) {
266 case 0:
267 case 1:
268 path.lineTo(rand.nextRangeF(0, 150), rand.nextRangeF(0, 150));
269 break;
270 case 2:
271 if (rand.nextULessThan(10) == 0) {
272 // Cusp.
273 auto [x, y] = (path.isEmpty())
274 ? SkPoint{0,0}
275 : SkPathPriv::PointData(path)[path.countPoints() - 1];
276 path.quadTo(x + rand.nextRangeF(0, 150), y, x - rand.nextRangeF(0, 150), y);
277 } else {
278 path.quadTo(rand.nextRangeF(0, 150), rand.nextRangeF(0, 150),
279 rand.nextRangeF(0, 150), rand.nextRangeF(0, 150));
280 }
281 break;
282 case 3:
283 if (rand.nextULessThan(10) == 0) {
284 // Cusp.
285 float y = (path.isEmpty())
286 ? 0 : SkPathPriv::PointData(path)[path.countPoints() - 1].fY;
287 path.cubicTo(rand.nextRangeF(0, 150), y, rand.nextRangeF(0, 150), y,
288 rand.nextRangeF(0, 150), y);
289 } else {
290 path.cubicTo(rand.nextRangeF(0, 150), rand.nextRangeF(0, 150),
291 rand.nextRangeF(0, 150), rand.nextRangeF(0, 150),
292 rand.nextRangeF(0, 150), rand.nextRangeF(0, 150));
293 }
294 break;
295 }
296 }
297 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
298 // The number of paths with a given stroke width in the MotionMark bench gets cut in half
299 // every time the stroke width increases by 1.
300 float strokeWidth = 21 - log2f(rand.nextRangeF(0, 1 << 20));
301 stroke.setStrokeStyle(strokeWidth);
302 stroke.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kBevel_Join, 0);
303 pathStrokes.emplace_back(path, stroke, SK_PMColor4fWHITE);
304 }
305 return pathStrokes;
306}
307
Chris Dalton82007f52021-04-20 00:45:50 -0600308class TessPrepareBench : public Benchmark {
Chris Dalton2882e702020-11-02 12:43:06 -0700309public:
Chris Dalton82007f52021-04-20 00:45:50 -0600310 TessPrepareBench(MakePathStrokesFn makePathStrokesFn, MakeTessellatorFn makeTessellatorFn,
311 ShaderFlags shaderFlags, float matrixScale, const char* suffix)
312 : fMakePathStrokesFn(makePathStrokesFn)
313 , fMakeTessellatorFn(makeTessellatorFn)
Chris Daltonbb33be22021-02-24 16:30:34 -0700314 , fShaderFlags(shaderFlags)
Chris Dalton981e4a72021-02-22 12:13:49 -0700315 , fMatrixScale(matrixScale) {
Chris Dalton82007f52021-04-20 00:45:50 -0600316 fName.printf("tessellate_%s", suffix);
Chris Dalton2882e702020-11-02 12:43:06 -0700317 }
318
319private:
320 const char* onGetName() override { return fName.c_str(); }
Chris Daltone2067642020-09-23 11:07:20 -0600321 bool isSuitableFor(Backend backend) final { return backend == kNonRendering_Backend; }
322
323 void onDelayedSetup() override {
Chris Dalton90ad0fe2020-11-09 14:13:39 -0700324 fTarget = std::make_unique<GrMockOpTarget>(make_mock_context());
Chris Dalton0e543092020-11-03 14:09:16 -0700325 if (!fTarget->mockContext()) {
Chris Daltone2067642020-09-23 11:07:20 -0600326 SkDebugf("ERROR: could not create mock context.");
327 return;
328 }
Chris Dalton981e4a72021-02-22 12:13:49 -0700329
330 fPathStrokes = fMakePathStrokesFn();
331 for (size_t i = 0; i < fPathStrokes.size(); ++i) {
332 if (i + 1 < fPathStrokes.size()) {
333 fPathStrokes[i].fNext = &fPathStrokes[i + 1];
334 }
335 fTotalVerbCount += fPathStrokes[i].fPath.countVerbs();
Chris Daltone2067642020-09-23 11:07:20 -0600336 }
Chris Dalton82007f52021-04-20 00:45:50 -0600337
Chris Dalton13adb4a2021-05-26 10:21:56 -0600338 fTessellator = fMakeTessellatorFn(fShaderFlags, *fTarget->caps().shaderCaps(),
339 SkMatrix::Scale(fMatrixScale, fMatrixScale),
Chris Dalton0638df12021-05-14 15:57:39 -0600340 fPathStrokes.data(), {fMatrixScale, fMatrixScale},
Chris Dalton8447f132021-05-21 15:54:23 -0600341 SkRectPriv::MakeLargest());
Chris Daltone2067642020-09-23 11:07:20 -0600342 }
343
Chris Dalton981e4a72021-02-22 12:13:49 -0700344 void onDraw(int loops, SkCanvas*) final {
Chris Dalton981e4a72021-02-22 12:13:49 -0700345 for (int i = 0; i < loops; ++i) {
Chris Dalton82007f52021-04-20 00:45:50 -0600346 fTessellator->prepare(fTarget.get(), fTotalVerbCount);
Chris Dalton981e4a72021-02-22 12:13:49 -0700347 fTarget->resetAllocator();
348 }
349 }
350
Chris Dalton2882e702020-11-02 12:43:06 -0700351 SkString fName;
Chris Dalton981e4a72021-02-22 12:13:49 -0700352 MakePathStrokesFn fMakePathStrokesFn;
Chris Dalton82007f52021-04-20 00:45:50 -0600353 MakeTessellatorFn fMakeTessellatorFn;
Chris Daltonbb33be22021-02-24 16:30:34 -0700354 const ShaderFlags fShaderFlags;
Chris Dalton981e4a72021-02-22 12:13:49 -0700355 float fMatrixScale;
Chris Dalton90ad0fe2020-11-09 14:13:39 -0700356 std::unique_ptr<GrMockOpTarget> fTarget;
Chris Dalton981e4a72021-02-22 12:13:49 -0700357 std::vector<PathStrokeList> fPathStrokes;
Chris Dalton82007f52021-04-20 00:45:50 -0600358 std::unique_ptr<GrStrokeTessellator> fTessellator;
Chris Dalton981e4a72021-02-22 12:13:49 -0700359 SkArenaAlloc fPersistentArena{1024};
360 int fTotalVerbCount = 0;
Chris Daltone2067642020-09-23 11:07:20 -0600361};
362
Chris Dalton82007f52021-04-20 00:45:50 -0600363DEF_BENCH(return new TessPrepareBench(
364 make_simple_cubic_path, make_hw_tessellator, ShaderFlags::kNone, 1,
365 "GrStrokeHardwareTessellator");
Chris Daltonbb33be22021-02-24 16:30:34 -0700366)
367
Chris Dalton82007f52021-04-20 00:45:50 -0600368DEF_BENCH(return new TessPrepareBench(
369 make_simple_cubic_path, make_hw_tessellator, ShaderFlags::kNone, 5,
370 "GrStrokeHardwareTessellator_one_chop");
Chris Daltonbb33be22021-02-24 16:30:34 -0700371)
372
Chris Dalton82007f52021-04-20 00:45:50 -0600373DEF_BENCH(return new TessPrepareBench(
374 make_motionmark_paths, make_hw_tessellator, ShaderFlags::kDynamicStroke, 1,
375 "GrStrokeHardwareTessellator_motionmark");
376)
377
378DEF_BENCH(return new TessPrepareBench(
379 make_simple_cubic_path, make_fixed_count_tessellator, ShaderFlags::kNone, 1,
380 "GrStrokeFixedCountTessellator");
381)
382
383DEF_BENCH(return new TessPrepareBench(
384 make_simple_cubic_path, make_fixed_count_tessellator, ShaderFlags::kNone, 5,
385 "GrStrokeFixedCountTessellator_one_chop");
386)
387
388DEF_BENCH(return new TessPrepareBench(
389 make_motionmark_paths, make_fixed_count_tessellator, ShaderFlags::kDynamicStroke, 1,
390 "GrStrokeFixedCountTessellator_motionmark");
Chris Daltonbb33be22021-02-24 16:30:34 -0700391)