Flutter Engine
The Flutter Engine
IntersectionTreeBench.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 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#include "bench/Benchmark.h"
10#include "src/base/SkMathPriv.h"
11#include "src/base/SkRandom.h"
13#include "tools/ToolUtils.h"
15
16#if defined(SK_ENABLE_SVG)
18#endif
19
20using namespace skia_private;
21
22static DEFINE_string(intersectionTreeFile, "",
23 "svg or skp for the IntersectionTree bench to sniff paths from.");
24
25namespace skgpu::graphite {
26
28protected:
29 const char* onGetName() final { return fName.c_str(); }
30
31 bool isSuitableFor(Backend backend) override {
33 }
34
35 void onDelayedSetup() final {
36 TArray<SkRect> rects;
37 this->gatherRects(&rects);
38 fRectCount = rects.size();
40 for (int i = 0; i < fRectCount; ++i) {
41 fRects[i] = rects[i];
42 }
45 }
46
47 virtual void gatherRects(TArray<SkRect>* rects) = 0;
48
49 void onDraw(int loops, SkCanvas*) final {
50 for (int i = 0; i < loops; ++i) {
51 this->doBench();
52 }
53 }
54
55 void doBench() {
56 Rect* rects = fRects;
57 Rect* collided = fRectBufferA;
58 int rectCount = fRectCount;
59 fNumTrees = 0;
60 while (rectCount > 0) {
61 IntersectionTree intersectionTree;
62 int collidedCount = 0;
63 for (int i = 0; i < rectCount; ++i) {
64 if (!intersectionTree.add(rects[i])) {
65 collided[collidedCount++] = rects[i];
66 }
67 }
68 std::swap(rects, collided);
69 if (collided == fRects) {
70 collided = fRectBufferB;
71 }
72 rectCount = collidedCount;
73 ++fNumTrees;
74 }
75 }
76
83 int fNumTrees = 0;
84};
85
87public:
88 RandomIntersectionBench(int numRandomRects) : fNumRandomRects(numRandomRects) {
89 fName.printf("IntersectionTree_%i", numRandomRects);
90 }
91
92private:
93 void gatherRects(TArray<SkRect>* rects) override {
94 SkRandom rand;
95 for (int i = 0; i < fNumRandomRects; ++i) {
96 rects->push_back(SkRect::MakeXYWH(rand.nextRangeF(0, 2000),
97 rand.nextRangeF(0, 2000),
98 rand.nextRangeF(0, 70),
99 rand.nextRangeF(0, 70)));
100 }
101 }
102
103 const int fNumRandomRects;
104};
105
107public:
109 if (FLAGS_intersectionTreeFile.isEmpty()) {
110 return;
111 }
112 const char* filename = strrchr(FLAGS_intersectionTreeFile[0], '/');
113 if (filename) {
114 ++filename;
115 } else {
116 filename = FLAGS_intersectionTreeFile[0];
117 }
118 fName.printf("IntersectionTree_file_%s", filename);
119 }
120
121private:
122 bool isSuitableFor(Backend backend) final {
123 if (FLAGS_intersectionTreeFile.isEmpty()) {
124 return false;
125 }
127 }
128
129 void gatherRects(TArray<SkRect>* rects) override {
130 if (FLAGS_intersectionTreeFile.isEmpty()) {
131 return;
132 }
133 auto callback = [&](const SkMatrix& matrix,
134 const SkPath& path,
135 const SkPaint& paint) {
136 if (paint.getStyle() == SkPaint::kStroke_Style) {
137 return; // Goes to stroker.
138 }
139 if (path.isConvex()) {
140 return; // Goes to convex renderer.
141 }
142 int numVerbs = path.countVerbs();
143 SkRect drawBounds = matrix.mapRect(path.getBounds());
144 float gpuFragmentWork = drawBounds.height() * drawBounds.width();
145 float cpuTessellationWork = numVerbs * SkNextLog2(numVerbs); // N log N.
146 constexpr static float kCpuWeight = 512;
147 constexpr static float kMinNumPixelsToTriangulate = 256 * 256;
148 if (cpuTessellationWork * kCpuWeight + kMinNumPixelsToTriangulate < gpuFragmentWork) {
149 return; // Goes to inner triangulator.
150 }
151 rects->push_back(drawBounds);
152 };
153 const char* path = FLAGS_intersectionTreeFile[0];
154 if (const char* ext = strrchr(path, '.'); ext && !strcmp(ext, ".svg")) {
155#if defined(SK_ENABLE_SVG)
157#else
158 SK_ABORT("must compile with svg backend to process svgs");
159#endif
160 } else {
162 }
163 SkDebugf(">> Found %i stencil/cover paths in %s <<\n",
164 rects->size(), FLAGS_intersectionTreeFile[0]);
165 }
166
167 void onPerCanvasPostDraw(SkCanvas*) override {
168 if (FLAGS_intersectionTreeFile.isEmpty()) {
169 return;
170 }
171 SkDebugf(">> Reordered %s into %i different stencil/cover draws <<\n",
172 FLAGS_intersectionTreeFile[0], fNumTrees);
173 }
174};
175
176} // namespace skgpu::graphite
177
183DEF_BENCH( return new skgpu::graphite::FileIntersectionBench(); ) // Sniffs --intersectionTreeFile
#define DEF_BENCH(code)
Definition: Benchmark.h:20
const char * backend
static DEFINE_string(intersectionTreeFile, "", "svg or skp for the IntersectionTree bench to sniff paths from.")
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static int SkNextLog2(uint32_t value)
Definition: SkMathPriv.h:238
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
T * makeArray(size_t count)
Definition: SkArenaAlloc.h:181
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
Definition: SkPath.h:59
float nextRangeF(float min, float max)
Definition: SkRandom.h:64
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:534
const char * c_str() const
Definition: SkString.h:133
bool isSuitableFor(Backend backend) override
void onDraw(int loops, SkCanvas *) final
virtual void gatherRects(TArray< SkRect > *rects)=0
int size() const
Definition: SkTArray.h:421
const Paint & paint
Definition: color_source.cc:38
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
void ExtractPathsFromSVG(const char filepath[], std::function< PathSniffCallback >)
void ExtractPathsFromSKP(const char filepath[], std::function< PathSniffCallback > callback)
Definition: ToolUtils.cpp:757
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
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762