Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
BoundsManagerBench.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
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"
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(boundsManagerFile, "",
23 "svg or skp for the BoundsManager bench to sniff paths from.");
24
25#define PRINT_DRAWSET_COUNT 0 // set to 1 to display number of CompressedPaintersOrder groups
26
27namespace skgpu::graphite {
28
30public:
31 BoundsManagerBench(std::unique_ptr<BoundsManager> manager) : fManager(std::move(manager)) {}
32
33protected:
34 virtual void gatherRects(TArray<SkRect>* rects) = 0;
35
36 bool isSuitableFor(Backend backend) override {
38 }
39
40 const char* onGetName() final { return fName.c_str(); }
41
42 void onDelayedSetup() final {
43 TArray<SkRect> rects;
44 this->gatherRects(&rects);
45
46 fRectCount = rects.size();
48 for (int i = 0; i < fRectCount; ++i) {
49 fRects[i] = rects[i];
50 }
51 }
52
53 void onDraw(int loops, SkCanvas*) final {
54 for (int i = 0; i < loops; ++i) {
55 this->doBench();
56 }
57 }
58
59 void onPerCanvasPostDraw(SkCanvas*) override {
60#if PRINT_DRAWSET_COUNT
61 SkDebugf("%s >> grouped %d draws into %d sets <<\n",
63#endif
64 }
65
66 void doBench() {
68 for (int i = 0; i < fRectCount; ++i) {
69 const Rect& drawBounds = fRects[i];
70 CompressedPaintersOrder order = fManager->getMostRecentDraw(drawBounds).next();
71 fManager->recordDraw(drawBounds, order);
72 if (order > maxRead) {
73 maxRead = order;
74 }
75 }
76
77 fMaxRead = maxRead;
78 fManager->reset();
79 }
80
81 std::unique_ptr<BoundsManager> fManager;
86
88};
89
91public:
92 RandomBoundsManagerBench(std::unique_ptr<BoundsManager> manager,
93 const char* managerName,
94 int numRandomRects)
95 : BoundsManagerBench(std::move(manager))
96 , fNumRandomRects(numRandomRects) {
97 fName.printf("BoundsManager_rand_%i_%s", numRandomRects, managerName);
98 }
99
100private:
101 void gatherRects(TArray<SkRect>* rects) override {
102 SkRandom rand;
103 for (int i = 0; i < fNumRandomRects; ++i) {
104 rects->push_back(SkRect::MakeXYWH(rand.nextRangeF(0, 2000),
105 rand.nextRangeF(0, 2000),
106 rand.nextRangeF(0, 70),
107 rand.nextRangeF(0, 70)));
108 }
109 }
110
111 int fNumRandomRects;
112};
113
115public:
116 FileBoundsManagerBench(std::unique_ptr<BoundsManager> manager,
117 const char* managerName)
118 : BoundsManagerBench(std::move(manager)) {
119 if (!FLAGS_boundsManagerFile.isEmpty()) {
120 const char* filename = strrchr(FLAGS_boundsManagerFile[0], '/');
121 if (filename) {
122 ++filename;
123 } else {
124 filename = FLAGS_boundsManagerFile[0];
125 }
126 fName.printf("BoundsManager_file_%s_%s", filename, managerName);
127 }
128 }
129
130private:
131 bool isSuitableFor(Backend backend) final {
132 if (FLAGS_boundsManagerFile.isEmpty()) {
133 return false;
134 }
136 }
137
138 void gatherRects(TArray<SkRect>* rects) override {
139 if (FLAGS_boundsManagerFile.isEmpty()) {
140 return;
141 }
142 SkRect fileBounds = SkRect::MakeEmpty();
143 auto callback = [&](const SkMatrix& matrix,
144 const SkPath& path,
145 const SkPaint& paint) {
146 if (!paint.canComputeFastBounds() || path.isInverseFillType()) {
147 // These would pessimistically cover the entire canvas, but we don't have enough
148 // info in the benchmark to handle that, so just skip these draws.
149 return;
150 }
151
152 SkRect bounds = path.getBounds();
153 SkRect drawBounds = matrix.mapRect(paint.computeFastBounds(bounds, &bounds));
154 rects->push_back(drawBounds);
155
156 fileBounds.join(drawBounds);
157 };
158
159 const char* path = FLAGS_boundsManagerFile[0];
160 if (const char* ext = strrchr(path, '.'); ext && !strcmp(ext, ".svg")) {
161#if defined(SK_ENABLE_SVG)
163#else
164 SK_ABORT("must compile with svg backend to process svgs");
165#endif
166 } else {
168 }
169
170#if PRINT_DRAWSET_COUNT
171 SkDebugf("%s bounds are [%f %f %f %f]\n",
172 FLAGS_boundsManagerFile[0],
173 fileBounds.fLeft, fileBounds.fTop, fileBounds.fRight, fileBounds.fBottom);
174#endif
175 }
176
177};
178
179} // namespace skgpu::graphite
180
181#define DEF_BOUNDS_MANAGER_BENCH_SET(manager, name) \
182 DEF_BENCH( return new skgpu::graphite::RandomBoundsManagerBench(manager, name, 100); ) \
183 DEF_BENCH( return new skgpu::graphite::RandomBoundsManagerBench(manager, name, 500); ) \
184 DEF_BENCH( return new skgpu::graphite::RandomBoundsManagerBench(manager, name, 1000); ) \
185 DEF_BENCH( return new skgpu::graphite::RandomBoundsManagerBench(manager, name, 10000); ) \
186 DEF_BENCH( return new skgpu::graphite::FileBoundsManagerBench(manager, name); )
187
188
189DEF_BOUNDS_MANAGER_BENCH_SET(std::make_unique<skgpu::graphite::NaiveBoundsManager>(), "naive")
190DEF_BOUNDS_MANAGER_BENCH_SET(std::make_unique<skgpu::graphite::BruteForceBoundsManager>(), "brute")
191DEF_BOUNDS_MANAGER_BENCH_SET(skgpu::graphite::GridBoundsManager::Make({1800, 1800}, 128), "grid128")
192DEF_BOUNDS_MANAGER_BENCH_SET(skgpu::graphite::GridBoundsManager::Make({1800, 1800}, 512), "grid512")
193DEF_BOUNDS_MANAGER_BENCH_SET(std::make_unique<skgpu::graphite::HybridBoundsManager>(SkISize{1800, 1800}, 16, 64), "hybrid16x16n128")
194DEF_BOUNDS_MANAGER_BENCH_SET(std::make_unique<skgpu::graphite::HybridBoundsManager>(SkISize{1800, 1800}, 16, 128), "hybrid16x16n256")
195// Uncomment and adjust device size to match reported bounds from --boundsManagerFile
196// DEF_BOUNDS_MANAGER_BENCH_SET(skgpu::graphite::GridBoundsManager::MakeRes({w, h}, 8), "gridRes8")
197
198#undef DEF_BOUNDS_MANAGER_BENCH_SET
#define DEF_BOUNDS_MANAGER_BENCH_SET(manager, name)
#define DEFINE_string(name, defaultValue, helpString)
const char * backend
#define SK_ABORT(message,...)
Definition SkAssert.h:70
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
T * makeArray(size_t count)
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
void onDraw(int loops, SkCanvas *) final
BoundsManagerBench(std::unique_ptr< BoundsManager > manager)
void onPerCanvasPostDraw(SkCanvas *) override
std::unique_ptr< BoundsManager > fManager
bool isSuitableFor(Backend backend) override
virtual void gatherRects(TArray< SkRect > *rects)=0
FileBoundsManagerBench(std::unique_ptr< BoundsManager > manager, const char *managerName)
void gatherRects(TArray< SkRect > *rects) override
MonotonicValue next() const
Definition DrawOrder.h:42
RandomBoundsManagerBench(std::unique_ptr< BoundsManager > manager, const char *managerName, int numRandomRects)
void gatherRects(TArray< SkRect > *rects) override
int size() const
Definition SkTArray.h:416
const Paint & paint
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
void ExtractPathsFromSVG(const char filepath[], std::function< PathSniffCallback >)
void ExtractPathsFromSKP(const char filepath[], std::function< PathSniffCallback > callback)
Definition ref_ptr.h:256
static constexpr SkRect MakeEmpty()
Definition SkRect.h:595
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
void join(const SkRect &r)
Definition SkRect.cpp:126
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15