Flutter Engine
 
Loading...
Searching...
No Matches
dl_region_benchmarks.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
10#include "third_party/skia/include/core/SkRegion.h"
11
12#include <random>
13
14namespace {
15
17
18template <typename RNG>
19std::vector<DlIRect> GenerateRects(RNG& rng,
20 const DlIRect& bounds,
21 int numRects,
22 int maxSize) {
23 auto max_size_x = std::min(maxSize, bounds.GetWidth());
24 auto max_size_y = std::min(maxSize, bounds.GetHeight());
25
26 std::uniform_int_distribution pos_x(bounds.GetLeft(),
27 bounds.GetRight() - max_size_x);
28 std::uniform_int_distribution pos_y(bounds.GetTop(),
29 bounds.GetBottom() - max_size_y);
30 std::uniform_int_distribution size_x(1, max_size_x);
31 std::uniform_int_distribution size_y(1, max_size_y);
32
33 std::vector<DlIRect> rects;
34 for (int i = 0; i < numRects; ++i) {
35 DlIRect rect =
36 DlIRect::MakeXYWH(pos_x(rng), pos_y(rng), size_x(rng), size_y(rng));
37 rects.push_back(rect);
38 }
39 return rects;
40}
41
42template <typename RNG>
43DlIRect RandomSubRect(RNG& rng, const DlIRect& rect, double size_factor) {
44 FML_DCHECK(size_factor <= 1);
45
46 int32_t width = rect.GetWidth() * size_factor;
47 int32_t height = rect.GetHeight() * size_factor;
48
49 std::uniform_int_distribution pos_x(0, rect.GetWidth() - width);
50 std::uniform_int_distribution pos_y(0, rect.GetHeight() - height);
51
52 return DlIRect::MakeXYWH(rect.GetLeft() + pos_x(rng),
53 rect.GetTop() + pos_y(rng), //
54 width, height);
55}
56
57class SkRegionAdapter {
58 public:
59 explicit SkRegionAdapter(const std::vector<DlIRect>& rects) {
60 region_.setRects(flutter::ToSkIRects(rects.data()), rects.size());
61 }
62
63 DlIRect getBounds() { return flutter::ToDlIRect(region_.getBounds()); }
64
65 static SkRegionAdapter unionRegions(const SkRegionAdapter& a1,
66 const SkRegionAdapter& a2) {
67 SkRegionAdapter result(a1);
68 result.region_.op(a2.region_, SkRegion::kUnion_Op);
69 return result;
70 }
71
72 static SkRegionAdapter intersectRegions(const SkRegionAdapter& a1,
73 const SkRegionAdapter& a2) {
74 SkRegionAdapter result(a1);
75 result.region_.op(a2.region_, SkRegion::kIntersect_Op);
76 return result;
77 }
78
79 bool intersects(const SkRegionAdapter& region) {
80 return region_.intersects(region.region_);
81 }
82
83 bool intersects(const DlIRect& rect) {
84 return region_.intersects(flutter::ToSkIRect(rect));
85 }
86
87 std::vector<DlIRect> getRects() {
88 std::vector<DlIRect> rects;
89 SkRegion::Iterator it(region_);
90 while (!it.done()) {
91 rects.push_back(flutter::ToDlIRect(it.rect()));
92 it.next();
93 }
94 return rects;
95 }
96
97 private:
98 SkRegion region_;
99};
100
101class DlRegionAdapter {
102 public:
103 explicit DlRegionAdapter(const std::vector<DlIRect>& rects)
104 : region_(rects) {}
105
106 static DlRegionAdapter unionRegions(const DlRegionAdapter& a1,
107 const DlRegionAdapter& a2) {
108 return DlRegionAdapter(
109 flutter::DlRegion::MakeUnion(a1.region_, a2.region_));
110 }
111
112 static DlRegionAdapter intersectRegions(const DlRegionAdapter& a1,
113 const DlRegionAdapter& a2) {
114 return DlRegionAdapter(
115 flutter::DlRegion::MakeIntersection(a1.region_, a2.region_));
116 }
117
118 DlIRect getBounds() { return region_.bounds(); }
119
120 bool intersects(const DlRegionAdapter& region) {
121 return region_.intersects(region.region_);
122 }
123
124 bool intersects(const DlIRect& rect) { return region_.intersects(rect); }
125
126 std::vector<DlIRect> getRects() { return region_.getRects(false); }
127
128 private:
129 explicit DlRegionAdapter(flutter::DlRegion&& region)
130 : region_(std::move(region)) {}
131
132 flutter::DlRegion region_;
133};
134
135template <typename Region>
136void RunFromRectsBenchmark(benchmark::State& state, int maxSize) {
137 std::random_device d;
138 std::seed_seq seed{2, 1, 3};
139 std::mt19937 rng(seed);
140
141 std::uniform_int_distribution pos(0, 4000);
142 std::uniform_int_distribution size(1, maxSize);
143
144 std::vector<DlIRect> rects;
145 for (int i = 0; i < 2000; ++i) {
146 DlIRect rect = DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng));
147 rects.push_back(rect);
148 }
149
150 while (state.KeepRunning()) {
151 Region region(rects);
152 }
153}
154
155template <typename Region>
156void RunGetRectsBenchmark(benchmark::State& state, int maxSize) {
157 std::random_device d;
158 std::seed_seq seed{2, 1, 3};
159 std::mt19937 rng(seed);
160
161 std::uniform_int_distribution pos(0, 4000);
162 std::uniform_int_distribution size(1, maxSize);
163
164 std::vector<DlIRect> rects;
165 for (int i = 0; i < 2000; ++i) {
166 DlIRect rect = DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng));
167 rects.push_back(rect);
168 }
169
170 Region region(rects);
171
172 while (state.KeepRunning()) {
173 auto vec2 = region.getRects();
174 }
175}
176
177enum RegionOp { kUnion, kIntersection };
178
179template <typename Region>
180void RunRegionOpBenchmark(benchmark::State& state,
181 RegionOp op,
182 bool withSingleRect,
183 int maxSize,
184 double sizeFactor) {
185 std::random_device d;
186 std::seed_seq seed{2, 1, 3};
187 std::mt19937 rng(seed);
188
189 DlIRect bounds1 = DlIRect::MakeWH(4000, 4000);
190 DlIRect bounds2 = RandomSubRect(rng, bounds1, sizeFactor);
191
192 auto rects = GenerateRects(rng, bounds1, 500, maxSize);
193 Region region1(rects);
194
195 rects = GenerateRects(rng, bounds2, withSingleRect ? 1 : 500 * sizeFactor,
196 maxSize);
197 Region region2(rects);
198
199 switch (op) {
200 case kUnion:
201 while (state.KeepRunning()) {
202 Region::unionRegions(region1, region2);
203 }
204 break;
205 case kIntersection:
206 while (state.KeepRunning()) {
207 Region::intersectRegions(region1, region2);
208 }
209 break;
210 }
211}
212
213template <typename Region>
214void RunIntersectsRegionBenchmark(benchmark::State& state,
215 int maxSize,
216 double sizeFactor) {
217 std::random_device d;
218 std::seed_seq seed{2, 1, 3};
219 std::mt19937 rng(seed);
220
221 DlIRect bounds1 = DlIRect::MakeWH(4000, 4000);
222 DlIRect bounds2 = RandomSubRect(rng, bounds1, sizeFactor);
223
224 auto rects = GenerateRects(rng, bounds1, 500, maxSize);
225 Region region1(rects);
226
227 rects = GenerateRects(rng, bounds2, 500 * sizeFactor, maxSize);
228 Region region2(rects);
229
230 while (state.KeepRunning()) {
231 region1.intersects(region2);
232 }
233}
234
235template <typename Region>
236void RunIntersectsSingleRectBenchmark(benchmark::State& state, int maxSize) {
237 std::random_device d;
238 std::seed_seq seed{2, 1, 3};
239 std::mt19937 rng(seed);
240
241 std::uniform_int_distribution pos(0, 4000);
242 std::uniform_int_distribution size(1, maxSize);
243
244 std::vector<DlIRect> rects;
245 for (int i = 0; i < 500; ++i) {
246 DlIRect rect = DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng));
247 rects.push_back(rect);
248 }
249 Region region1(rects);
250
251 rects.clear();
252 for (int i = 0; i < 100; ++i) {
253 DlIRect rect = DlIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng));
254 rects.push_back(rect);
255 }
256
257 while (state.KeepRunning()) {
258 for (auto& rect : rects) {
259 region1.intersects(rect);
260 }
261 }
262}
263
264} // namespace
265
266namespace flutter {
267
268static void BM_DlRegion_FromRects(benchmark::State& state, int maxSize) {
269 RunFromRectsBenchmark<DlRegionAdapter>(state, maxSize);
270}
271
272static void BM_SkRegion_FromRects(benchmark::State& state, int maxSize) {
273 RunFromRectsBenchmark<SkRegionAdapter>(state, maxSize);
274}
275
276static void BM_DlRegion_GetRects(benchmark::State& state, int maxSize) {
277 RunGetRectsBenchmark<DlRegionAdapter>(state, maxSize);
278}
279
280static void BM_SkRegion_GetRects(benchmark::State& state, int maxSize) {
281 RunGetRectsBenchmark<SkRegionAdapter>(state, maxSize);
282}
283
284static void BM_DlRegion_Operation(benchmark::State& state,
285 RegionOp op,
286 bool withSingleRect,
287 int maxSize,
288 double sizeFactor) {
289 RunRegionOpBenchmark<DlRegionAdapter>(state, op, withSingleRect, maxSize,
290 sizeFactor);
291}
292
293static void BM_SkRegion_Operation(benchmark::State& state,
294 RegionOp op,
295 bool withSingleRect,
296 int maxSize,
297 double sizeFactor) {
298 RunRegionOpBenchmark<SkRegionAdapter>(state, op, withSingleRect, maxSize,
299 sizeFactor);
300}
301
302static void BM_DlRegion_IntersectsRegion(benchmark::State& state,
303 int maxSize,
304 double sizeFactor) {
305 RunIntersectsRegionBenchmark<DlRegionAdapter>(state, maxSize, sizeFactor);
306}
307
308static void BM_SkRegion_IntersectsRegion(benchmark::State& state,
309 int maxSize,
310 double sizeFactor) {
311 RunIntersectsRegionBenchmark<SkRegionAdapter>(state, maxSize, sizeFactor);
312}
313
314static void BM_DlRegion_IntersectsSingleRect(benchmark::State& state,
315 int maxSize) {
316 RunIntersectsSingleRectBenchmark<DlRegionAdapter>(state, maxSize);
317}
318
319static void BM_SkRegion_IntersectsSingleRect(benchmark::State& state,
320 int maxSize) {
321 RunIntersectsSingleRectBenchmark<SkRegionAdapter>(state, maxSize);
322}
323
324const double kSizeFactorSmall = 0.3;
325
327 ->Unit(benchmark::kNanosecond);
329 ->Unit(benchmark::kNanosecond);
331 ->Unit(benchmark::kNanosecond);
333 ->Unit(benchmark::kNanosecond);
335 ->Unit(benchmark::kNanosecond);
337 ->Unit(benchmark::kNanosecond);
339 ->Unit(benchmark::kNanosecond);
341 ->Unit(benchmark::kNanosecond);
342
344 ->Unit(benchmark::kNanosecond);
346 ->Unit(benchmark::kNanosecond);
348 ->Unit(benchmark::kNanosecond);
350 ->Unit(benchmark::kNanosecond);
352 ->Unit(benchmark::kNanosecond);
354 ->Unit(benchmark::kNanosecond);
356 ->Unit(benchmark::kNanosecond);
358 ->Unit(benchmark::kNanosecond);
359
361 TinyAsymmetric,
362 30,
364 ->Unit(benchmark::kNanosecond);
366 TinyAsymmetric,
367 30,
369 ->Unit(benchmark::kNanosecond);
371 SmallAsymmetric,
372 100,
374 ->Unit(benchmark::kNanosecond);
376 SmallAsymmetric,
377 100,
379 ->Unit(benchmark::kNanosecond);
381 MediumAsymmetric,
382 400,
384 ->Unit(benchmark::kNanosecond);
386 MediumAsymmetric,
387 400,
389 ->Unit(benchmark::kNanosecond);
391 LargeAsymmetric,
392 1500,
394 ->Unit(benchmark::kNanosecond);
396 LargeAsymmetric,
397 1500,
399 ->Unit(benchmark::kNanosecond);
400
402 Union_Tiny,
403 RegionOp::kUnion,
404 false,
405 30,
406 1.0)
407 ->Unit(benchmark::kMicrosecond);
409 Union_Tiny,
410 RegionOp::kUnion,
411 false,
412 30,
413 1.0)
414 ->Unit(benchmark::kMicrosecond);
416 Union_Small,
417 RegionOp::kUnion,
418 false,
419 100,
420 1.0)
421 ->Unit(benchmark::kMicrosecond);
423 Union_Small,
424 RegionOp::kUnion,
425 false,
426 100,
427 1.0)
428 ->Unit(benchmark::kMicrosecond);
430 Union_Medium,
431 RegionOp::kUnion,
432 false,
433 400,
434 1.0)
435 ->Unit(benchmark::kMicrosecond);
437 Union_Medium,
438 RegionOp::kUnion,
439 false,
440 400,
441 1.0)
442 ->Unit(benchmark::kMicrosecond);
444 Union_Large,
445 RegionOp::kUnion,
446 false,
447 1500,
448 1.0)
449 ->Unit(benchmark::kMicrosecond);
451 Union_Large,
452 RegionOp::kUnion,
453 false,
454 1500,
455 1.0)
456 ->Unit(benchmark::kMicrosecond);
457
459 Union_TinyAsymmetric,
460 RegionOp::kUnion,
461 false,
462 30,
464 ->Unit(benchmark::kMicrosecond);
466 Union_TinyAsymmetric,
467 RegionOp::kUnion,
468 false,
469 30,
471 ->Unit(benchmark::kMicrosecond);
473 Union_SmallAsymmetric,
474 RegionOp::kUnion,
475 false,
476 100,
478 ->Unit(benchmark::kMicrosecond);
480 Union_SmallAsymmetric,
481 RegionOp::kUnion,
482 false,
483 100,
485 ->Unit(benchmark::kMicrosecond);
487 Union_MediumAsymmetric,
488 RegionOp::kUnion,
489 false,
490 400,
492 ->Unit(benchmark::kMicrosecond);
494 Union_MediumAsymmetric,
495 RegionOp::kUnion,
496 false,
497 400,
499 ->Unit(benchmark::kMicrosecond);
501 Union_LargeAsymmetric,
502 RegionOp::kUnion,
503 false,
504 1500,
506 ->Unit(benchmark::kMicrosecond);
508 Union_LargeAsymmetric,
509 RegionOp::kUnion,
510 false,
511 1500,
513 ->Unit(benchmark::kMicrosecond);
514
516 Intersection_Tiny,
517 RegionOp::kIntersection,
518 false,
519 30,
520 1.0)
521 ->Unit(benchmark::kMicrosecond);
523 Intersection_Tiny,
524 RegionOp::kIntersection,
525 false,
526 30,
527 1.0)
528 ->Unit(benchmark::kMicrosecond);
530 Intersection_Small,
531 RegionOp::kIntersection,
532 false,
533 100,
534 1.0)
535 ->Unit(benchmark::kMicrosecond);
537 Intersection_Small,
538 RegionOp::kIntersection,
539 false,
540 100,
541 1.0)
542 ->Unit(benchmark::kMicrosecond);
544 Intersection_Medium,
545 RegionOp::kIntersection,
546 false,
547 400,
548 1.0)
549 ->Unit(benchmark::kMicrosecond);
551 Intersection_Medium,
552 RegionOp::kIntersection,
553 false,
554 400,
555 1.0)
556 ->Unit(benchmark::kMicrosecond);
558 Intersection_Large,
559 RegionOp::kIntersection,
560 false,
561 1500,
562 1.0)
563 ->Unit(benchmark::kMicrosecond);
565 Intersection_Large,
566 RegionOp::kIntersection,
567 false,
568 1500,
569 1.0)
570 ->Unit(benchmark::kMicrosecond);
571
573 Intersection_TinyAsymmetric,
574 RegionOp::kIntersection,
575 false,
576 30,
578 ->Unit(benchmark::kMicrosecond);
580 Intersection_TinyAsymmetric,
581 RegionOp::kIntersection,
582 false,
583 30,
585 ->Unit(benchmark::kMicrosecond);
587 Intersection_SmallAsymmetric,
588 RegionOp::kIntersection,
589 false,
590 100,
592 ->Unit(benchmark::kMicrosecond);
594 Intersection_SmallAsymmetric,
595 RegionOp::kIntersection,
596 false,
597 100,
599 ->Unit(benchmark::kMicrosecond);
601 Intersection_MediumAsymmetric,
602 RegionOp::kIntersection,
603 false,
604 400,
606 ->Unit(benchmark::kMicrosecond);
608 Intersection_MediumAsymmetric,
609 RegionOp::kIntersection,
610 false,
611 400,
613 ->Unit(benchmark::kMicrosecond);
615 Intersection_LargeAsymmetric,
616 RegionOp::kIntersection,
617 false,
618 1500,
620 ->Unit(benchmark::kMicrosecond);
622 Intersection_LargeAsymmetric,
623 RegionOp::kIntersection,
624 false,
625 1500,
627 ->Unit(benchmark::kMicrosecond);
628
630 Intersection_SingleRect_Tiny,
631 RegionOp::kIntersection,
632 true,
633 30,
634 1.0)
635 ->Unit(benchmark::kMicrosecond);
637 Intersection_SingleRect_Tiny,
638 RegionOp::kIntersection,
639 true,
640 30,
641 1.0)
642 ->Unit(benchmark::kMicrosecond);
644 Intersection_SingleRect_Small,
645 RegionOp::kIntersection,
646 true,
647 100,
648 1.0)
649 ->Unit(benchmark::kMicrosecond);
651 Intersection_SingleRect_Small,
652 RegionOp::kIntersection,
653 true,
654 100,
655 1.0)
656 ->Unit(benchmark::kMicrosecond);
658 Intersection_SingleRect_Medium,
659 RegionOp::kIntersection,
660 true,
661 400,
662 1.0)
663 ->Unit(benchmark::kMicrosecond);
665 Intersection_SingleRect_Medium,
666 RegionOp::kIntersection,
667 true,
668 400,
669 1.0)
670 ->Unit(benchmark::kMicrosecond);
672 Intersection_SingleRect_Large,
673 RegionOp::kIntersection,
674 true,
675 1500,
676 1.0)
677 ->Unit(benchmark::kMicrosecond);
679 Intersection_SingleRect_Large,
680 RegionOp::kIntersection,
681 true,
682 1500,
683 1.0)
684 ->Unit(benchmark::kMicrosecond);
685
687 ->Unit(benchmark::kMicrosecond);
689 ->Unit(benchmark::kMicrosecond);
691 ->Unit(benchmark::kMicrosecond);
693 ->Unit(benchmark::kMicrosecond);
695 ->Unit(benchmark::kMicrosecond);
697 ->Unit(benchmark::kMicrosecond);
699 ->Unit(benchmark::kMicrosecond);
701 ->Unit(benchmark::kMicrosecond);
702
704 ->Unit(benchmark::kMicrosecond);
706 ->Unit(benchmark::kMicrosecond);
708 ->Unit(benchmark::kMicrosecond);
710 ->Unit(benchmark::kMicrosecond);
712 ->Unit(benchmark::kMicrosecond);
714 ->Unit(benchmark::kMicrosecond);
716 ->Unit(benchmark::kMicrosecond);
718 ->Unit(benchmark::kMicrosecond);
719
720} // namespace flutter
static DlRegion MakeIntersection(const DlRegion &a, const DlRegion &b)
Definition dl_region.cc:496
static DlRegion MakeUnion(const DlRegion &a, const DlRegion &b)
Definition dl_region.cc:405
auto & d
Definition main.cc:28
#define FML_DCHECK(condition)
Definition logging.h:122
static void BM_DlRegion_Operation(benchmark::State &state, RegionOp op, bool withSingleRect, int maxSize, double sizeFactor)
static void BM_SkRegion_IntersectsSingleRect(benchmark::State &state, int maxSize)
static void BM_DlRegion_GetRects(benchmark::State &state, int maxSize)
const SkIRect & ToSkIRect(const DlIRect &rect)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static void BM_SkRegion_FromRects(benchmark::State &state, int maxSize)
static void BM_SkRegion_GetRects(benchmark::State &state, int maxSize)
static void BM_DlRegion_IntersectsRegion(benchmark::State &state, int maxSize, double sizeFactor)
const double kSizeFactorSmall
impeller::IRect32 DlIRect
static void BM_DlRegion_FromRects(benchmark::State &state, int maxSize)
const DlIRect & ToDlIRect(const SkIRect &rect)
static void BM_SkRegion_Operation(benchmark::State &state, RegionOp op, bool withSingleRect, int maxSize, double sizeFactor)
static void BM_SkRegion_IntersectsRegion(benchmark::State &state, int maxSize, double sizeFactor)
static void BM_DlRegion_IntersectsSingleRect(benchmark::State &state, int maxSize)
BENCHMARK_CAPTURE(BM_DisplayListBuilderDefault, kDefault, DisplayListBuilderBenchmarkType::kDefault) -> Unit(benchmark::kMicrosecond)
const SkIRect * ToSkIRects(const DlIRect *rects)
Definition ref_ptr.h:261
int32_t height
int32_t width