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 | #include "flutter/display_list/testing/dl_test_snippets.h" |
7 | |
8 | namespace flutter { |
9 | |
10 | DlOpReceiver& DisplayListBuilderBenchmarkAccessor(DisplayListBuilder& builder) { |
11 | return builder.asReceiver(); |
12 | } |
13 | |
14 | namespace { |
15 | |
16 | static std::vector<testing::DisplayListInvocationGroup> allRenderingOps = |
17 | testing::CreateAllRenderingOps(); |
18 | |
19 | enum class DisplayListBuilderBenchmarkType { |
20 | kDefault, |
21 | kBounds, |
22 | kRtree, |
23 | kBoundsAndRtree, |
24 | }; |
25 | |
26 | static void InvokeAllRenderingOps(DisplayListBuilder& builder) { |
27 | DlOpReceiver& receiver = DisplayListBuilderBenchmarkAccessor(builder); |
28 | for (auto& group : allRenderingOps) { |
29 | for (size_t i = 0; i < group.variants.size(); i++) { |
30 | auto& invocation = group.variants[i]; |
31 | invocation.Invoke(builder&: receiver); |
32 | } |
33 | } |
34 | } |
35 | |
36 | static void Complete(DisplayListBuilder& builder, |
37 | DisplayListBuilderBenchmarkType type) { |
38 | auto display_list = builder.Build(); |
39 | switch (type) { |
40 | case DisplayListBuilderBenchmarkType::kBounds: |
41 | display_list->bounds(); |
42 | break; |
43 | case DisplayListBuilderBenchmarkType::kRtree: |
44 | display_list->rtree(); |
45 | break; |
46 | case DisplayListBuilderBenchmarkType::kBoundsAndRtree: |
47 | display_list->bounds(); |
48 | display_list->rtree(); |
49 | break; |
50 | case DisplayListBuilderBenchmarkType::kDefault: |
51 | break; |
52 | } |
53 | } |
54 | |
55 | bool NeedPrepareRTree(DisplayListBuilderBenchmarkType type) { |
56 | return type == DisplayListBuilderBenchmarkType::kRtree || |
57 | type == DisplayListBuilderBenchmarkType::kBoundsAndRtree; |
58 | } |
59 | |
60 | } // namespace |
61 | |
62 | static void BM_DisplayListBuilderDefault(benchmark::State& state, |
63 | DisplayListBuilderBenchmarkType type) { |
64 | bool prepare_rtree = NeedPrepareRTree(type); |
65 | while (state.KeepRunning()) { |
66 | DisplayListBuilder builder(prepare_rtree); |
67 | InvokeAllRenderingOps(builder); |
68 | Complete(builder, type); |
69 | } |
70 | } |
71 | |
72 | static void BM_DisplayListBuilderWithScaleAndTranslate( |
73 | benchmark::State& state, |
74 | DisplayListBuilderBenchmarkType type) { |
75 | bool prepare_rtree = NeedPrepareRTree(type); |
76 | while (state.KeepRunning()) { |
77 | DisplayListBuilder builder(prepare_rtree); |
78 | builder.Scale(sx: 3.5, sy: 3.5); |
79 | builder.Translate(tx: 10.3, ty: 6.9); |
80 | InvokeAllRenderingOps(builder); |
81 | Complete(builder, type); |
82 | } |
83 | } |
84 | |
85 | static void BM_DisplayListBuilderWithPerspective( |
86 | benchmark::State& state, |
87 | DisplayListBuilderBenchmarkType type) { |
88 | bool prepare_rtree = NeedPrepareRTree(type); |
89 | while (state.KeepRunning()) { |
90 | DisplayListBuilder builder(prepare_rtree); |
91 | builder.TransformFullPerspective(mxx: 0, mxy: 1, mxz: 0, mxt: 12, myx: 1, myy: 0, myz: 0, myt: 33, mzx: 3, mzy: 2, mzz: 5, mzt: 29, mwx: 0, |
92 | mwy: 0, mwz: 0, mwt: 12); |
93 | InvokeAllRenderingOps(builder); |
94 | Complete(builder, type); |
95 | } |
96 | } |
97 | |
98 | static void BM_DisplayListBuilderWithClipRect( |
99 | benchmark::State& state, |
100 | DisplayListBuilderBenchmarkType type) { |
101 | SkRect clip_bounds = SkRect::MakeLTRB(l: 6.5, t: 7.3, r: 90.2, b: 85.7); |
102 | bool prepare_rtree = NeedPrepareRTree(type); |
103 | while (state.KeepRunning()) { |
104 | DisplayListBuilder builder(prepare_rtree); |
105 | builder.ClipRect(rect: clip_bounds, clip_op: DlCanvas::ClipOp::kIntersect, is_aa: true); |
106 | InvokeAllRenderingOps(builder); |
107 | Complete(builder, type); |
108 | } |
109 | } |
110 | |
111 | static void BM_DisplayListBuilderWithSaveLayer( |
112 | benchmark::State& state, |
113 | DisplayListBuilderBenchmarkType type) { |
114 | bool prepare_rtree = NeedPrepareRTree(type); |
115 | while (state.KeepRunning()) { |
116 | DisplayListBuilder builder(prepare_rtree); |
117 | DlOpReceiver& receiver = DisplayListBuilderBenchmarkAccessor(builder); |
118 | for (auto& group : allRenderingOps) { |
119 | for (size_t i = 0; i < group.variants.size(); i++) { |
120 | auto& invocation = group.variants[i]; |
121 | builder.SaveLayer(bounds: nullptr, paint: nullptr); |
122 | invocation.Invoke(builder&: receiver); |
123 | builder.Restore(); |
124 | } |
125 | } |
126 | Complete(builder, type); |
127 | } |
128 | } |
129 | |
130 | static void BM_DisplayListBuilderWithSaveLayerAndImageFilter( |
131 | benchmark::State& state, |
132 | DisplayListBuilderBenchmarkType type) { |
133 | DlPaint layer_paint; |
134 | layer_paint.setImageFilter(&testing::kTestBlurImageFilter1); |
135 | SkRect layer_bounds = SkRect::MakeLTRB(l: 6.5, t: 7.3, r: 35.2, b: 42.7); |
136 | bool prepare_rtree = NeedPrepareRTree(type); |
137 | while (state.KeepRunning()) { |
138 | DisplayListBuilder builder(prepare_rtree); |
139 | DlOpReceiver& receiver = DisplayListBuilderBenchmarkAccessor(builder); |
140 | for (auto& group : allRenderingOps) { |
141 | for (size_t i = 0; i < group.variants.size(); i++) { |
142 | auto& invocation = group.variants[i]; |
143 | builder.SaveLayer(bounds: &layer_bounds, paint: &layer_paint); |
144 | invocation.Invoke(builder&: receiver); |
145 | builder.Restore(); |
146 | } |
147 | } |
148 | Complete(builder, type); |
149 | } |
150 | } |
151 | |
152 | BENCHMARK_CAPTURE(BM_DisplayListBuilderDefault, |
153 | kDefault, |
154 | DisplayListBuilderBenchmarkType::kDefault) |
155 | ->Unit(unit: benchmark::kMicrosecond); |
156 | BENCHMARK_CAPTURE(BM_DisplayListBuilderDefault, |
157 | kBounds, |
158 | DisplayListBuilderBenchmarkType::kBounds) |
159 | ->Unit(unit: benchmark::kMicrosecond); |
160 | BENCHMARK_CAPTURE(BM_DisplayListBuilderDefault, |
161 | kRtree, |
162 | DisplayListBuilderBenchmarkType::kRtree) |
163 | ->Unit(unit: benchmark::kMicrosecond); |
164 | BENCHMARK_CAPTURE(BM_DisplayListBuilderDefault, |
165 | kBoundsAndRtree, |
166 | DisplayListBuilderBenchmarkType::kBoundsAndRtree) |
167 | ->Unit(unit: benchmark::kMicrosecond); |
168 | |
169 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithScaleAndTranslate, |
170 | kDefault, |
171 | DisplayListBuilderBenchmarkType::kDefault) |
172 | ->Unit(unit: benchmark::kMicrosecond); |
173 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithScaleAndTranslate, |
174 | kBounds, |
175 | DisplayListBuilderBenchmarkType::kBounds) |
176 | ->Unit(unit: benchmark::kMicrosecond); |
177 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithScaleAndTranslate, |
178 | kRtree, |
179 | DisplayListBuilderBenchmarkType::kRtree) |
180 | ->Unit(unit: benchmark::kMicrosecond); |
181 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithScaleAndTranslate, |
182 | kBoundsAndRtree, |
183 | DisplayListBuilderBenchmarkType::kBoundsAndRtree) |
184 | ->Unit(unit: benchmark::kMicrosecond); |
185 | |
186 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithPerspective, |
187 | kDefault, |
188 | DisplayListBuilderBenchmarkType::kDefault) |
189 | ->Unit(unit: benchmark::kMicrosecond); |
190 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithPerspective, |
191 | kBounds, |
192 | DisplayListBuilderBenchmarkType::kBounds) |
193 | ->Unit(unit: benchmark::kMicrosecond); |
194 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithPerspective, |
195 | kRtree, |
196 | DisplayListBuilderBenchmarkType::kRtree) |
197 | ->Unit(unit: benchmark::kMicrosecond); |
198 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithPerspective, |
199 | kBoundsAndRtree, |
200 | DisplayListBuilderBenchmarkType::kBoundsAndRtree) |
201 | ->Unit(unit: benchmark::kMicrosecond); |
202 | |
203 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithClipRect, |
204 | kDefault, |
205 | DisplayListBuilderBenchmarkType::kDefault) |
206 | ->Unit(unit: benchmark::kMicrosecond); |
207 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithClipRect, |
208 | kBounds, |
209 | DisplayListBuilderBenchmarkType::kBounds) |
210 | ->Unit(unit: benchmark::kMicrosecond); |
211 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithClipRect, |
212 | kRtree, |
213 | DisplayListBuilderBenchmarkType::kRtree) |
214 | ->Unit(unit: benchmark::kMicrosecond); |
215 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithClipRect, |
216 | kBoundsAndRtree, |
217 | DisplayListBuilderBenchmarkType::kBoundsAndRtree) |
218 | ->Unit(unit: benchmark::kMicrosecond); |
219 | |
220 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithSaveLayer, |
221 | kDefault, |
222 | DisplayListBuilderBenchmarkType::kDefault) |
223 | ->Unit(unit: benchmark::kMicrosecond); |
224 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithSaveLayer, |
225 | kBounds, |
226 | DisplayListBuilderBenchmarkType::kBounds) |
227 | ->Unit(unit: benchmark::kMicrosecond); |
228 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithSaveLayer, |
229 | kRtree, |
230 | DisplayListBuilderBenchmarkType::kRtree) |
231 | ->Unit(unit: benchmark::kMicrosecond); |
232 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithSaveLayer, |
233 | kBoundsAndRtree, |
234 | DisplayListBuilderBenchmarkType::kBoundsAndRtree) |
235 | ->Unit(unit: benchmark::kMicrosecond); |
236 | |
237 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithSaveLayerAndImageFilter, |
238 | kDefault, |
239 | DisplayListBuilderBenchmarkType::kDefault) |
240 | ->Unit(unit: benchmark::kMicrosecond); |
241 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithSaveLayerAndImageFilter, |
242 | kBounds, |
243 | DisplayListBuilderBenchmarkType::kBounds) |
244 | ->Unit(unit: benchmark::kMicrosecond); |
245 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithSaveLayerAndImageFilter, |
246 | kRtree, |
247 | DisplayListBuilderBenchmarkType::kRtree) |
248 | ->Unit(unit: benchmark::kMicrosecond); |
249 | BENCHMARK_CAPTURE(BM_DisplayListBuilderWithSaveLayerAndImageFilter, |
250 | kBoundsAndRtree, |
251 | DisplayListBuilderBenchmarkType::kBoundsAndRtree) |
252 | ->Unit(unit: benchmark::kMicrosecond); |
253 | |
254 | } // namespace flutter |
255 | |