Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 042ebae

Browse files
authored
Improve getting non-overlapping rectangles from RTree (#42399)
Fixes flutter/flutter#116070 Fixes flutter/flutter#126202 Introduces `DlRegion` class which implements subset of `SkRegion` required to get non-overlapping rectangles from region. The implementation is different and faster than `SkRegion` for this particular use-case (`display_list_region_benchmarks`): Edit: Updated benchmark to latest revision and natively (initial run went through rosetta) ``` ---------------------------------------------------------------------------- Benchmark Time CPU Iterations ---------------------------------------------------------------------------- BM_RegionBenchmarkDlRegion/Tiny 616 us 616 us 908 BM_RegionBenchmarkSkRegion/Tiny 70559 us 70557 us 10 BM_RegionBenchmarkDlRegion/Small 1315 us 1314 us 537 BM_RegionBenchmarkSkRegion/Small 121736 us 121717 us 6 BM_RegionBenchmarkDlRegion/Medium 1079 us 1079 us 650 BM_RegionBenchmarkSkRegion/Medium 22039 us 22035 us 32 BM_RegionBenchmarkDlRegion/Large 399 us 399 us 1763 BM_RegionBenchmarkSkRegion/Large 1510 us 1510 us 466 ``` ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [X] I listed at least one issue that this PR fixes in the description above. - [X] I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See [testing the engine] for instructions on writing and running engine tests. - [X] I updated/added relevant documentation (doc comments with `///`). - [X] I signed the [CLA]. - [X] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat
1 parent 7f12e34 commit 042ebae

File tree

14 files changed

+693
-99
lines changed

14 files changed

+693
-99
lines changed

BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ group("flutter") {
116116
public_deps += [
117117
"//flutter/display_list:display_list_benchmarks",
118118
"//flutter/display_list:display_list_builder_benchmarks",
119+
"//flutter/display_list:display_list_region_benchmarks",
119120
"//flutter/fml:fml_benchmarks",
120121
"//flutter/impeller/geometry:geometry_benchmarks",
121122
"//flutter/lib/ui:ui_benchmarks",

ci/licenses_golden/excluded_files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
../../../flutter/display_list/effects/dl_image_filter_unittests.cc
4040
../../../flutter/display_list/effects/dl_mask_filter_unittests.cc
4141
../../../flutter/display_list/effects/dl_path_effect_unittests.cc
42+
../../../flutter/display_list/geometry/dl_region_unittests.cc
4243
../../../flutter/display_list/geometry/dl_rtree_unittests.cc
4344
../../../flutter/display_list/skia/dl_sk_conversions_unittests.cc
4445
../../../flutter/display_list/skia/dl_sk_paint_dispatcher_unittests.cc

ci/licenses_golden/licenses_flutter

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ ORIGIN: ../../../flutter/display_list/benchmarking/dl_complexity_gl.h + ../../..
714714
ORIGIN: ../../../flutter/display_list/benchmarking/dl_complexity_helper.h + ../../../flutter/LICENSE
715715
ORIGIN: ../../../flutter/display_list/benchmarking/dl_complexity_metal.cc + ../../../flutter/LICENSE
716716
ORIGIN: ../../../flutter/display_list/benchmarking/dl_complexity_metal.h + ../../../flutter/LICENSE
717+
ORIGIN: ../../../flutter/display_list/benchmarking/dl_region_benchmarks.cc + ../../../flutter/LICENSE
717718
ORIGIN: ../../../flutter/display_list/display_list.cc + ../../../flutter/LICENSE
718719
ORIGIN: ../../../flutter/display_list/display_list.h + ../../../flutter/LICENSE
719720
ORIGIN: ../../../flutter/display_list/dl_attributes.h + ../../../flutter/LICENSE
@@ -748,6 +749,8 @@ ORIGIN: ../../../flutter/display_list/effects/dl_path_effect.cc + ../../../flutt
748749
ORIGIN: ../../../flutter/display_list/effects/dl_path_effect.h + ../../../flutter/LICENSE
749750
ORIGIN: ../../../flutter/display_list/effects/dl_runtime_effect.cc + ../../../flutter/LICENSE
750751
ORIGIN: ../../../flutter/display_list/effects/dl_runtime_effect.h + ../../../flutter/LICENSE
752+
ORIGIN: ../../../flutter/display_list/geometry/dl_region.cc + ../../../flutter/LICENSE
753+
ORIGIN: ../../../flutter/display_list/geometry/dl_region.h + ../../../flutter/LICENSE
751754
ORIGIN: ../../../flutter/display_list/geometry/dl_rtree.cc + ../../../flutter/LICENSE
752755
ORIGIN: ../../../flutter/display_list/geometry/dl_rtree.h + ../../../flutter/LICENSE
753756
ORIGIN: ../../../flutter/display_list/image/dl_image.cc + ../../../flutter/LICENSE
@@ -3380,6 +3383,7 @@ FILE: ../../../flutter/display_list/benchmarking/dl_complexity_gl.h
33803383
FILE: ../../../flutter/display_list/benchmarking/dl_complexity_helper.h
33813384
FILE: ../../../flutter/display_list/benchmarking/dl_complexity_metal.cc
33823385
FILE: ../../../flutter/display_list/benchmarking/dl_complexity_metal.h
3386+
FILE: ../../../flutter/display_list/benchmarking/dl_region_benchmarks.cc
33833387
FILE: ../../../flutter/display_list/display_list.cc
33843388
FILE: ../../../flutter/display_list/display_list.h
33853389
FILE: ../../../flutter/display_list/dl_attributes.h
@@ -3414,6 +3418,8 @@ FILE: ../../../flutter/display_list/effects/dl_path_effect.cc
34143418
FILE: ../../../flutter/display_list/effects/dl_path_effect.h
34153419
FILE: ../../../flutter/display_list/effects/dl_runtime_effect.cc
34163420
FILE: ../../../flutter/display_list/effects/dl_runtime_effect.h
3421+
FILE: ../../../flutter/display_list/geometry/dl_region.cc
3422+
FILE: ../../../flutter/display_list/geometry/dl_region.h
34173423
FILE: ../../../flutter/display_list/geometry/dl_rtree.cc
34183424
FILE: ../../../flutter/display_list/geometry/dl_rtree.h
34193425
FILE: ../../../flutter/display_list/image/dl_image.cc

display_list/BUILD.gn

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ source_set("display_list") {
5757
"effects/dl_path_effect.h",
5858
"effects/dl_runtime_effect.cc",
5959
"effects/dl_runtime_effect.h",
60+
"geometry/dl_region.cc",
61+
"geometry/dl_region.h",
6062
"geometry/dl_rtree.cc",
6163
"geometry/dl_rtree.h",
6264
"image/dl_image.cc",
@@ -112,6 +114,7 @@ if (enable_unittests) {
112114
"effects/dl_image_filter_unittests.cc",
113115
"effects/dl_mask_filter_unittests.cc",
114116
"effects/dl_path_effect_unittests.cc",
117+
"geometry/dl_region_unittests.cc",
115118
"geometry/dl_rtree_unittests.cc",
116119
"skia/dl_sk_conversions_unittests.cc",
117120
"skia/dl_sk_paint_dispatcher_unittests.cc",
@@ -182,6 +185,18 @@ if (enable_unittests) {
182185
"//flutter/testing:testing_lib",
183186
]
184187
}
188+
189+
executable("display_list_region_benchmarks") {
190+
testonly = true
191+
192+
sources = [ "benchmarking/dl_region_benchmarks.cc" ]
193+
194+
deps = [
195+
":display_list_fixtures",
196+
"//flutter/benchmarking",
197+
"//flutter/testing:testing_lib",
198+
]
199+
}
185200
}
186201

187202
fixtures_location("display_list_benchmarks_fixtures") {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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+
5+
#include "flutter/benchmarking/benchmarking.h"
6+
7+
#include "flutter/display_list/geometry/dl_region.h"
8+
#include "third_party/skia/include/core/SkRegion.h"
9+
10+
#include <random>
11+
12+
class SkRegionAdapter {
13+
public:
14+
void addRect(const SkIRect& rect) { region_.op(rect, SkRegion::kUnion_Op); }
15+
16+
std::vector<SkIRect> getRects() {
17+
std::vector<SkIRect> rects;
18+
SkRegion::Iterator it(region_);
19+
while (!it.done()) {
20+
rects.push_back(it.rect());
21+
it.next();
22+
}
23+
return rects;
24+
}
25+
26+
private:
27+
SkRegion region_;
28+
};
29+
30+
class DlRegionAdapter {
31+
public:
32+
void addRect(const SkIRect& rect) { rects_.push_back(rect); }
33+
34+
std::vector<SkIRect> getRects() {
35+
flutter::DlRegion region(std::move(rects_));
36+
return region.getRects(false);
37+
}
38+
39+
private:
40+
std::vector<SkIRect> rects_;
41+
};
42+
43+
template <typename Region>
44+
void RunRegionBenchmark(benchmark::State& state, int maxSize) {
45+
while (state.KeepRunning()) {
46+
std::random_device d;
47+
std::seed_seq seed{2, 1, 3};
48+
std::mt19937 rng(seed);
49+
50+
std::uniform_int_distribution pos(0, 4000);
51+
std::uniform_int_distribution size(1, maxSize);
52+
53+
Region region;
54+
55+
for (int i = 0; i < 2000; ++i) {
56+
SkIRect rect =
57+
SkIRect::MakeXYWH(pos(rng), pos(rng), size(rng), size(rng));
58+
region.addRect(rect);
59+
}
60+
61+
auto vec2 = region.getRects();
62+
}
63+
}
64+
65+
namespace flutter {
66+
67+
static void BM_RegionBenchmarkSkRegion(benchmark::State& state, int maxSize) {
68+
RunRegionBenchmark<SkRegionAdapter>(state, maxSize);
69+
}
70+
71+
static void BM_RegionBenchmarkDlRegion(benchmark::State& state, int maxSize) {
72+
RunRegionBenchmark<DlRegionAdapter>(state, maxSize);
73+
}
74+
75+
BENCHMARK_CAPTURE(BM_RegionBenchmarkDlRegion, Tiny, 30)
76+
->Unit(benchmark::kMicrosecond);
77+
BENCHMARK_CAPTURE(BM_RegionBenchmarkSkRegion, Tiny, 30)
78+
->Unit(benchmark::kMicrosecond);
79+
BENCHMARK_CAPTURE(BM_RegionBenchmarkDlRegion, Small, 100)
80+
->Unit(benchmark::kMicrosecond);
81+
BENCHMARK_CAPTURE(BM_RegionBenchmarkSkRegion, Small, 100)
82+
->Unit(benchmark::kMicrosecond);
83+
BENCHMARK_CAPTURE(BM_RegionBenchmarkDlRegion, Medium, 400)
84+
->Unit(benchmark::kMicrosecond);
85+
BENCHMARK_CAPTURE(BM_RegionBenchmarkSkRegion, Medium, 400)
86+
->Unit(benchmark::kMicrosecond);
87+
BENCHMARK_CAPTURE(BM_RegionBenchmarkDlRegion, Large, 1500)
88+
->Unit(benchmark::kMicrosecond);
89+
BENCHMARK_CAPTURE(BM_RegionBenchmarkSkRegion, Large, 1500)
90+
->Unit(benchmark::kMicrosecond);
91+
92+
} // namespace flutter

display_list/dl_builder.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,8 @@ void DisplayListBuilder::DrawDisplayList(const sk_sp<DisplayList> display_list,
11061106
case BoundsAccumulatorType::kRTree:
11071107
auto rtree = display_list->rtree();
11081108
if (rtree) {
1109-
std::list<SkRect> rects = rtree->searchAndConsolidateRects(bounds);
1109+
std::list<SkRect> rects =
1110+
rtree->searchAndConsolidateRects(bounds, false);
11101111
for (const SkRect& rect : rects) {
11111112
// TODO (https://github.com/flutter/flutter/issues/114919): Attributes
11121113
// are not necessarily `kDrawDisplayListFlags`.

0 commit comments

Comments
 (0)