Flutter Engine
The Flutter Engine
PathOpsBench.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 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"
14#include "src/base/SkRandom.h"
15
16class PathOpsBench : public Benchmark {
17 SkString fName;
18 SkPath fPath1, fPath2;
19 SkPathOp fOp;
20
21public:
22 PathOpsBench(const char suffix[], SkPathOp op) : fOp(op) {
23 fName.printf("pathops_%s", suffix);
24
25 fPath1.addOval({-10, -20, 10, 20});
26 fPath2.addOval({-20, -10, 20, 10});
27 }
28
29 bool isSuitableFor(Backend backend) override {
31 }
32
33protected:
34 const char* onGetName() override {
35 return fName.c_str();
36 }
37
38 void onDraw(int loops, SkCanvas* canvas) override {
39 for (int i = 0; i < loops; i++) {
40 for (int j = 0; j < 1000; ++j) {
42 Op(fPath1, fPath2, fOp, &result);
43 }
44 }
45 }
46
47private:
48 using INHERITED = Benchmark;
49};
50
52 SkString fName;
53 SkPath fPath;
54
55public:
56 PathOpsSimplifyBench(const char suffix[], const SkPath& path) : fPath(path) {
57 fName.printf("pathops_simplify_%s", suffix);
58 }
59
60 bool isSuitableFor(Backend backend) override {
62 }
63
64protected:
65 const char* onGetName() override {
66 return fName.c_str();
67 }
68
69 void onDraw(int loops, SkCanvas* canvas) override {
70 for (int i = 0; i < loops; i++) {
71 for (int j = 0; j < 100; ++j) {
74 }
75 }
76 }
77
78private:
79 using INHERITED = Benchmark;
80};
81DEF_BENCH( return new PathOpsBench("sect", kIntersect_SkPathOp); )
82DEF_BENCH( return new PathOpsBench("join", kUnion_SkPathOp); )
83
84static SkPath makerects() {
85 SkRandom rand;
87 SkScalar scale = 100;
88 for (int i = 0; i < 20; ++i) {
89 SkScalar x = rand.nextUScalar1() * scale;
90 SkScalar y = rand.nextUScalar1() * scale;
91 path.addRect({x, y, x + scale, y + scale});
92 }
93 return path;
94}
95DEF_BENCH( return new PathOpsSimplifyBench("rects", makerects()); )
96
97#include "include/core/SkPathBuilder.h"
98
99template <size_t N> struct ArrayPath {
100 SkPoint fPts[N];
101 uint8_t fVbs[N];
102 int fPIndex = 0, fVIndex = 0;
103
104 void moveTo(float x, float y) {
105 fVbs[fVIndex++] = (uint8_t)SkPathVerb::kMove;
106 fPts[fPIndex++] = {x, y};
107 }
108 void lineTo(float x, float y) {
109 fVbs[fVIndex++] = (uint8_t)SkPathVerb::kLine;
110 fPts[fPIndex++] = {x, y};
111 }
112 void quadTo(float x, float y, float x1, float y1) {
113 fVbs[fVIndex++] = (uint8_t)SkPathVerb::kQuad;
114 fPts[fPIndex++] = {x, y};
115 fPts[fPIndex++] = {x1, y1};
116 }
117 void cubicTo(float x, float y, float x1, float y1, float x2, float y2) {
118 fVbs[fVIndex++] = (uint8_t)SkPathVerb::kCubic;
119 fPts[fPIndex++] = {x, y};
120 fPts[fPIndex++] = {x1, y1};
121 fPts[fPIndex++] = {x2, y2};
122 }
123 void incReserve(int) {}
124};
125
126template <typename T> void run_builder(T& b, bool useReserve, int N) {
127 if (useReserve) {
128 b.incReserve(N * 12);
129 }
130
131 float x = 0, y = 0;
132 b.moveTo(x, y);
133 for (int i = 1; i < N; ++i) {
134 b.lineTo(x, y);
135 b.quadTo(x, y, x, y);
136 b.cubicTo(x, y, x, y, x, y);
137 }
138}
139
140enum class MakeType {
141 kPath,
142 kSnapshot,
143 kDetach,
144 kArray,
145};
146
148 SkString fName;
149 MakeType fMakeType;
150 bool fUseReserve;
151
152 enum { N = 100 };
153 ArrayPath<N*12> fArrays;
154
155public:
156 PathBuilderBench(MakeType mt, bool reserve) : fMakeType(mt), fUseReserve(reserve) {
157 const char* typenames[] = { "path", "snapshot", "detach", "arrays" };
158
159 fName.printf("makepath_%s_%s", typenames[(int)mt], reserve ? "reserve" : "noreserve");
160 }
161
164 }
165
166protected:
167 const char* onGetName() override {
168 return fName.c_str();
169 }
170
171 void onDelayedSetup() override {
172 run_builder(fArrays, false, N);
173 }
174
176 switch (fMakeType) {
178 case MakeType::kDetach: {
180 run_builder(b, fUseReserve, N);
181 return MakeType::kSnapshot == fMakeType ? b.snapshot() : b.detach();
182 }
183 case MakeType::kPath: {
184 SkPath p;
185 run_builder(p, fUseReserve, N);
186 return p;
187 }
188 case MakeType::kArray: {
189 // ArrayPath<N*12> arrays;
190 // run_builder(arrays, false, N);
191 return SkPath::Make(fArrays.fPts, fArrays.fPIndex,
192 fArrays.fVbs, fArrays.fVIndex,
193 nullptr, 0, SkPathFillType::kWinding);
194 }
195 }
196 return SkPath();
197 }
198
199 void onDraw(int loops, SkCanvas* canvas) override {
200 for (int i = 0; i < loops; i++) {
201 for (int j = 0; j < 100; ++j) {
202 SkPath result = this->build();
203 // force bounds calc as part of the test
204 if (!result.getBounds().isFinite()) {
205 SkDebugf("should never get here!\n");
206 return;
207 }
208 }
209 }
210 }
211
212private:
213 using INHERITED = Benchmark;
214};
215DEF_BENCH( return new PathBuilderBench(MakeType::kPath, false); )
217DEF_BENCH( return new PathBuilderBench(MakeType::kDetach, false); )
218DEF_BENCH( return new PathBuilderBench(MakeType::kPath, true); )
220DEF_BENCH( return new PathBuilderBench(MakeType::kDetach, true); )
221
222DEF_BENCH( return new PathBuilderBench(MakeType::kArray, true); )
SkPoint fPts[2]
SkPath fPath
const char * backend
const char * fName
MakeType
void run_builder(T &b, bool useReserve, int N)
DEF_BENCH(return new PathOpsSimplifyBench("rects", makerects());) template< size_t N > struct ArrayPath
static SkPath makerects()
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
SkPathOp
Definition: SkPathOps.h:22
@ kIntersect_SkPathOp
intersect the two paths
Definition: SkPathOps.h:24
@ kUnion_SkPathOp
union (inclusive-or) the two paths
Definition: SkPathOps.h:25
bool SK_API Simplify(const SkPath &path, SkPath *result)
@ kCubic
SkPath::RawIter returns 4 points.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
#define N
Definition: beziers.cpp:19
PathBuilderBench(MakeType mt, bool reserve)
const char * onGetName() override
void onDelayedSetup() override
void onDraw(int loops, SkCanvas *canvas) override
bool isSuitableFor(Backend backend) override
PathOpsBench(const char suffix[], SkPathOp op)
const char * onGetName() override
bool isSuitableFor(Backend backend) override
void onDraw(int loops, SkCanvas *canvas) override
void onDraw(int loops, SkCanvas *canvas) override
PathOpsSimplifyBench(const char suffix[], const SkPath &path)
const char * onGetName() override
bool isSuitableFor(Backend backend) override
Definition: SkPath.h:59
static SkPath Make(const SkPoint[], int pointCount, const uint8_t[], int verbCount, const SkScalar[], int conicWeightCount, SkPathFillType, bool isVolatile=false)
Definition: SkPath.cpp:3569
const SkRect & getBounds() const
Definition: SkPath.cpp:430
SkPath & addOval(const SkRect &oval, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1106
SkScalar nextUScalar1()
Definition: SkRandom.h:101
float SkScalar
Definition: extension.cpp:12
static bool b
GAsyncResult * result
double y
double x
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
#define T
Definition: precompiler.cc:65
const Scalar scale
bool isFinite() const
Definition: SkRect.h:711