15#include "third_party/skia/include/core/SkBitmap.h"
16#include "third_party/skia/include/core/SkImage.h"
17#include "third_party/skia/include/core/SkSurface.h"
18#include "third_party/skia/include/core/SkTextBlob.h"
22#undef WRITE_BENCHMARK_SNAPSHOTS
29inline void SaveSnapshotIfNecessary(
30 const std::unique_ptr<DlSurfaceProvider>& provider,
31 const std::shared_ptr<DlSurfaceInstance>& surface,
32 benchmark::State& state,
33 const std::string& test_name) {
34#ifdef WRITE_BENCHMARK_SNAPSHOTS
35 auto filename = provider->GetBackendName() +
"-" + test_name +
"-" +
36 std::to_string(state.range(0)) +
".png";
37 surface->SnapshotToFile(filename);
45 rect_origin_(rect.GetOrigin()),
46 animation_delta_(animation_delta),
47 animation_limit_(animation_limit) {}
51 const std::shared_ptr<DlSurfaceInstance>& surface)
52 : RectAnimator(rect, animation_delta,
surface->GetSize()) {}
55 rect_ = rect_.Shift(animation_delta_);
56 if (rect_.GetRight() > animation_limit_.width) {
57 rect_ = rect_.Shift(rect_origin_.x - rect_.GetLeft(), 0);
59 if (rect_.GetBottom() > animation_limit_.height) {
60 rect_ = rect_.Shift(0, rect_origin_.y - rect_.GetTop());
64 const DlRect& GetRect()
const {
return rect_; }
65 const DlPoint GetPoint()
const {
return rect_.GetOrigin(); }
66 const DlPoint GetCenter()
const {
return rect_.GetCenter(); }
73 const DlSize animation_limit_;
82 void QuadTo(
const DlPoint& cp,
const DlPoint&
p2)
override { verb_count_++; }
92 void Close()
override { verb_count_++; }
94 uint32_t GetVerbCount()
const {
return verb_count_; }
97 uint32_t verb_count_ = 0u;
100DlPaint GetPaintForRun(
unsigned attributes) {
122 static auto blur5filter =
124 paint.setMaskFilter(blur5filter);
126 static auto blur10filter =
128 paint.setMaskFilter(blur10filter);
135void CheckAttributes(uint32_t attributes,
136 benchmark::State& state,
137 const DisplayListAttributeFlags flags) {
138 if (flags.always_stroked() && attributes &
kFilledStyle) {
139 state.SkipWithError(
"Cannot fill an operation that is always stroked");
141 if (flags.applies_style()) {
143 state.SkipWithError(
"must specify stroked and/or filled style");
147 state.SkipWithError(
"Cannot specify stroke style if op is not stroked");
154constexpr size_t kLinesToDraw = 10000;
155constexpr size_t kRectsToDraw = 5000;
156constexpr size_t kOvalsToDraw = 5000;
157constexpr size_t kCirclesToDraw = 5000;
158constexpr size_t kRRectsToDraw = 5000;
159constexpr size_t kRSEsToDraw = 5000;
160constexpr size_t kDRRectsToDraw = 2000;
161constexpr size_t kArcSweepSetsToDraw = 1000;
162constexpr size_t kImagesToDraw = 500;
163constexpr size_t kFixedCanvasSize = 1024;
172 size_t length = state.range(0);
175 auto surface = surface_provider->GetPrimarySurface();
180 for ([[maybe_unused]]
auto _ : state) {
190 size_t length = state.range(0);
193 auto surface = surface_provider->GetPrimarySurface();
198 auto display_list = builder.
Build();
201 for ([[maybe_unused]]
auto _ : state) {
202 surface->RenderDisplayList(display_list);
212 size_t length = state.range(0);
215 auto surface = surface_provider->GetPrimarySurface();
221 auto display_list = builder.
Build();
224 for ([[maybe_unused]]
auto _ : state) {
225 surface->RenderDisplayList(display_list);
238 unsigned attributes) {
241 DlPaint paint = GetPaintForRun(attributes);
245 size_t length = state.range(0);
248 auto surface = surface_provider->GetPrimarySurface();
252 state.counters[
"DrawCallCount"] = kLinesToDraw;
253 for (
size_t i = 0;
i < kLinesToDraw;
i++) {
258 auto display_list = builder.
Build();
259 FML_CHECK(display_list->GetRecordCount() >= kLinesToDraw);
262 size_t items_processed = 0;
263 for ([[maybe_unused]]
auto _ : state) {
264 surface->RenderDisplayList(display_list);
265 items_processed += kLinesToDraw;
268 state.SetItemsProcessed(items_processed);
270 SaveSnapshotIfNecessary(surface_provider,
surface, state,
"DrawLine");
279 unsigned attributes) {
282 DlPaint paint = GetPaintForRun(attributes);
286 size_t length = state.range(0);
287 surface_provider->InitializeSurface(
length * 2,
length * 2);
288 auto surface = surface_provider->GetPrimarySurface();
294 const DlPoint delta(0.5f, 0.5f);
297 state.counters[
"DrawCallCount"] = kRectsToDraw;
298 for (
size_t i = 0;
i < kRectsToDraw;
i++) {
299 builder.
DrawRect(animator.GetRect(), paint);
303 auto display_list = builder.
Build();
304 FML_CHECK(display_list->GetRecordCount() >= kRectsToDraw);
307 size_t items_processed = 0;
308 for ([[maybe_unused]]
auto _ : state) {
309 surface->RenderDisplayList(display_list);
310 items_processed += kRectsToDraw;
313 state.SetItemsProcessed(items_processed);
315 SaveSnapshotIfNecessary(surface_provider,
surface, state,
"DrawRect");
324 unsigned attributes) {
327 DlPaint paint = GetPaintForRun(attributes);
331 size_t length = state.range(0);
332 surface_provider->InitializeSurface(
length * 2,
length * 2);
333 auto surface = surface_provider->GetPrimarySurface();
337 const DlPoint delta(0.5f, 0.5f);
341 state.counters[
"DrawCallCount"] = kOvalsToDraw;
342 for (
size_t i = 0;
i < kOvalsToDraw;
i++) {
343 builder.
DrawOval(animator.GetRect(), paint);
346 auto display_list = builder.
Build();
347 FML_CHECK(display_list->GetRecordCount() >= kOvalsToDraw);
350 size_t items_processed = 0;
351 for ([[maybe_unused]]
auto _ : state) {
352 surface->RenderDisplayList(display_list);
353 items_processed += kOvalsToDraw;
356 state.SetItemsProcessed(items_processed);
358 SaveSnapshotIfNecessary(surface_provider,
surface, state,
"DrawOval");
367 unsigned attributes) {
370 DlPaint paint = GetPaintForRun(attributes);
374 size_t length = state.range(0);
375 surface_provider->InitializeSurface(
length * 2,
length * 2);
376 auto surface = surface_provider->GetPrimarySurface();
381 const DlPoint delta(0.5f, 0.5f);
384 state.counters[
"DrawCallCount"] = kCirclesToDraw;
385 for (
size_t i = 0;
i < kCirclesToDraw;
i++) {
386 builder.
DrawCircle(animator.GetCenter(), radius, paint);
389 auto display_list = builder.
Build();
390 FML_CHECK(display_list->GetRecordCount() >= kCirclesToDraw);
393 size_t items_processed = 0;
394 for ([[maybe_unused]]
auto _ : state) {
395 surface->RenderDisplayList(display_list);
396 items_processed += kCirclesToDraw;
399 state.SetItemsProcessed(items_processed);
401 SaveSnapshotIfNecessary(surface_provider,
surface, state,
"DrawCircle");
414 DlPaint paint = GetPaintForRun(attributes);
418 size_t length = state.range(0);
419 surface_provider->InitializeSurface(
length * 2,
length * 2);
420 auto surface = surface_provider->GetPrimarySurface();
454 radii = radii * multiplier;
456 state.counters[
"DrawCallCount"] = kRRectsToDraw;
457 for (
size_t i = 0;
i < kRRectsToDraw;
i++) {
462 auto display_list = builder.
Build();
463 FML_CHECK(display_list->GetRecordCount() >= kRRectsToDraw);
466 size_t items_processed = 0;
467 for ([[maybe_unused]]
auto _ : state) {
468 surface->RenderDisplayList(display_list);
469 items_processed += kRRectsToDraw;
472 state.SetItemsProcessed(items_processed);
474 SaveSnapshotIfNecessary(surface_provider,
surface, state,
"DrawRRect");
479 unsigned attributes) {
485 unsigned attributes) {
491 unsigned attributes) {
505 DlPaint paint = GetPaintForRun(attributes);
507 CheckAttributes(attributes, state,
510 size_t length = state.range(0);
511 surface_provider->InitializeSurface(
length * 2,
length * 2);
512 auto surface = surface_provider->GetPrimarySurface();
546 radii = radii * multiplier;
548 state.counters[
"DrawCallCount"] = kRSEsToDraw;
549 for (
size_t i = 0;
i < kRSEsToDraw;
i++) {
555 auto display_list = builder.
Build();
556 FML_CHECK(display_list->GetRecordCount() >= kRSEsToDraw);
559 size_t items_processed = 0;
560 for ([[maybe_unused]]
auto _ : state) {
561 surface->RenderDisplayList(display_list);
562 items_processed += kRSEsToDraw;
565 state.SetItemsProcessed(items_processed);
567 SaveSnapshotIfNecessary(surface_provider,
surface, state,
"DrawRSE");
572 unsigned attributes) {
578 unsigned attributes) {
584 unsigned attributes) {
601 DlPaint paint = GetPaintForRun(attributes);
605 size_t length = state.range(0);
606 surface_provider->InitializeSurface(
length * 2,
length * 2);
607 auto surface = surface_provider->GetPrimarySurface();
637 const DlPoint delta(0.5f, 0.5f);
644 state.counters[
"DrawCallCount"] = kDRRectsToDraw;
645 for (
size_t i = 0;
i < kDRRectsToDraw;
i++) {
646 const DlRect outer_rect = animator.GetRect();
647 const DlRect inner_rect = outer_rect.
Expand(inner_scale);
653 auto display_list = builder.
Build();
654 FML_CHECK(display_list->GetRecordCount() >= kDRRectsToDraw);
657 size_t items_processed = 0;
658 for ([[maybe_unused]]
auto _ : state) {
659 surface->RenderDisplayList(display_list);
660 items_processed += kDRRectsToDraw;
663 state.SetItemsProcessed(items_processed);
665 SaveSnapshotIfNecessary(surface_provider,
surface, state,
"DrawDRRect");
670 unsigned attributes) {
673 DlPaint paint = GetPaintForRun(attributes);
677 size_t length = state.range(0);
678 surface_provider->InitializeSurface(
length * 2,
length * 2);
679 auto surface = surface_provider->GetPrimarySurface();
687 std::vector<DlScalar> segment_sweeps = {5.5f, -10.0f, 42.0f, 71.7f, 90.0f,
688 37.5f, 17.9f, 32.0f, 379.4f};
693 size_t total_call_count = kArcSweepSetsToDraw * segment_sweeps.size();
694 state.counters[
"DrawCallCount"] = total_call_count;
695 for (
size_t i = 0;
i < kArcSweepSetsToDraw;
i++) {
696 for (
DlScalar sweep : segment_sweeps) {
697 builder.
DrawArc(animator.GetRect(), starting_angle, sweep,
false, paint);
698 starting_angle += sweep + 5.0f;
703 auto display_list = builder.
Build();
704 FML_CHECK(display_list->GetRecordCount() >= total_call_count);
707 size_t items_processed = 0;
708 for ([[maybe_unused]]
auto _ : state) {
709 surface->RenderDisplayList(display_list);
710 items_processed += total_call_count;
713 state.SetItemsProcessed(items_processed);
715 SaveSnapshotIfNecessary(surface_provider,
surface, state,
"DrawArc");
721 std::vector<DlPoint>
points;
724 float full_circle = 2.0f * M_PI;
725 for (
size_t i = 0;
i < n;
i++) {
726 angle = (full_circle /
static_cast<float>(n)) *
static_cast<float>(
i);
727 x = center.x + r * std::cosf(angle);
728 y = center.y + r * std::sinf(angle);
746 for (
size_t i = 1;
i < sides;
i++) {
750 path_builder.
Close();
767 std::vector<DlPoint> control_points =
771 for (
size_t i = 1;
i < sides;
i++) {
775 path_builder.
Close();
792 std::vector<DlPoint> control_points =
796 for (
size_t i = 1;
i < sides;
i++) {
800 path_builder.
Close();
818 std::vector<DlPoint> inner_control_points =
820 std::vector<DlPoint> outer_control_points =
824 for (
size_t i = 1;
i < sides;
i++) {
826 outer_control_points[3 *
i - 1],
points[
i]);
828 path_builder.
CubicCurveTo(inner_control_points[3 * sides - 2],
829 outer_control_points[3 * sides - 1],
points[0]);
830 path_builder.
Close();
847 std::vector<DlPoint> center_points =
850 for (
DlPoint p : center_points) {
898 DlPaint paint = GetPaintForRun(attributes);
902 size_t length = kFixedCanvasSize;
904 auto surface = surface_provider->GetPrimarySurface();
912 float radius =
length * 0.25f;
913 state.SetComplexityN(state.range(0));
918 DlPathVerbCounter counter;
920 state.counters[
"VerbCount"] = counter.GetVerbCount();
921 state.counters[
"DrawCallCount"] = 1;
924 auto display_list = builder.
Build();
927 surface->RenderDisplayList(display_list);
931 size_t items_processed = 0;
932 for ([[maybe_unused]]
auto _ : state) {
933 surface->RenderDisplayList(display_list);
934 items_processed += counter.GetVerbCount();
937 state.SetItemsProcessed(items_processed);
939 SaveSnapshotIfNecessary(surface_provider,
surface, state,
940 "DrawPath-" + label);
959 size_t& final_vertex_count) {
960 size_t outer_vertex_count = vertex_count / 2;
961 std::vector<DlPoint> outer_points =
964 std::vector<DlPoint> vertices;
965 std::vector<DlColor> colors;
972 vertices.push_back(center);
973 colors.push_back(
DlColor(SK_ColorCYAN));
974 for (
size_t i = 0;
i <= outer_points.size();
i++) {
975 vertices.push_back(outer_points[
i % outer_points.size()]);
977 colors.push_back(
DlColor(SK_ColorRED));
978 }
else if (
i % 3 == 1) {
979 colors.push_back(
DlColor(SK_ColorGREEN));
981 colors.push_back(
DlColor(SK_ColorBLUE));
989 for (
size_t i = 0;
i < outer_vertex_count;
i++) {
990 vertices.push_back(outer_points[
i % outer_points.size()]);
991 colors.push_back(
DlColor(SK_ColorRED));
992 vertices.push_back(outer_points[(
i + 1) % outer_points.size()]);
993 colors.push_back(
DlColor(SK_ColorGREEN));
994 vertices.push_back(center);
995 colors.push_back(
DlColor(SK_ColorBLUE));
1002 for (
size_t i = 0;
i <= outer_vertex_count;
i++) {
1003 vertices.push_back(outer_points[
i % outer_points.size()]);
1004 colors.push_back(
i % 2 ?
DlColor(SK_ColorRED) :
DlColor(SK_ColorGREEN));
1006 vertices.push_back(center);
1007 colors.push_back(
DlColor(SK_ColorBLUE));
1015 final_vertex_count = vertices.size();
1023 return "TriangleStrip";
1025 return "TriangleFan";
1042 unsigned attributes,
1046 DlPaint paint = GetPaintForRun(attributes);
1050 size_t length = kFixedCanvasSize;
1052 auto surface = surface_provider->GetPrimarySurface();
1054 surface->FlushSubmitCpuSync();
1058 float radius =
length / 4.0f;
1060 size_t vertex_count, total_vertex_count = 0;
1061 size_t disc_count = state.range(0);
1063 std::vector<DlPoint> center_points =
1066 state.counters[
"DrawCallCount"] = center_points.size();
1067 for (
DlPoint p : center_points) {
1068 std::shared_ptr<DlVertices> vertices =
1070 total_vertex_count += vertex_count;
1071 builder.
DrawVertices(vertices, DlBlendMode::kSrc, paint);
1074 state.counters[
"VertexCount"] = total_vertex_count;
1075 state.SetComplexityN(total_vertex_count);
1077 auto display_list = builder.
Build();
1078 FML_CHECK(display_list->GetRecordCount() >= center_points.size());
1081 size_t items_processed = 0;
1082 for ([[maybe_unused]]
auto _ : state) {
1083 surface->RenderDisplayList(display_list);
1084 items_processed += total_vertex_count;
1085 surface->FlushSubmitCpuSync();
1087 state.SetItemsProcessed(items_processed);
1089 SaveSnapshotIfNecessary(surface_provider,
surface, state,
1090 "DrawVertices-" + std::to_string(disc_count) +
"-" +
1101 std::vector<DlPoint>
points;
1104 std::vector<DlScalar> delta_x = {10.0f, 6.3f, 15.0f, 3.5f, 22.6f, 4.7f};
1105 std::vector<DlScalar> delta_y = {9.3f, -5.4f, 8.5f, -12.0f, 19.2f, -19.6f};
1108 for (
size_t i = 0;
i < count;
i++) {
1109 points.push_back(current);
1111 DlPoint(delta_x[
i % delta_x.size()], delta_y[
i % delta_y.size()]);
1112 if (current.
x > canvas_size.
width) {
1115 if (current.
y > canvas_size.
height) {
1143 unsigned attributes,
1147 DlPaint paint = GetPaintForRun(attributes);
1151 CheckAttributes(attributes, state,
1155 CheckAttributes(attributes, state,
1159 CheckAttributes(attributes, state,
1164 size_t length = kFixedCanvasSize;
1166 auto surface = surface_provider->GetPrimarySurface();
1168 surface->FlushSubmitCpuSync();
1170 size_t point_count = state.range(0);
1171 state.SetComplexityN(point_count);
1172 state.counters[
"PointCount"] = point_count;
1173 state.counters[
"DrawCallCount"] = 1;
1178 auto display_list = builder.
Build();
1180 size_t items_processed = 0;
1181 for ([[maybe_unused]]
auto _ : state) {
1182 surface->RenderDisplayList(display_list);
1183 items_processed += point_count;
1184 surface->FlushSubmitCpuSync();
1186 state.SetItemsProcessed(items_processed);
1188 SaveSnapshotIfNecessary(surface_provider,
surface, state,
1190 std::to_string(point_count));
1198 bitmap.peekPixels(&pixmap);
1199 return SkImages::RasterFromPixmap(pixmap,
nullptr,
nullptr);
1206 unsigned attributes,
1208 bool upload_bitmap) {
1211 DlPaint paint = GetPaintForRun(attributes);
1213 CheckAttributes(attributes, state,
1216 size_t bitmap_size = state.range(0);
1217 surface_provider->InitializeSurface(bitmap_size * 2, bitmap_size * 2);
1218 auto surface = surface_provider->GetPrimarySurface();
1220 surface->FlushSubmitCpuSync();
1222 sk_sp<DlImage>
image;
1225 if (upload_bitmap) {
1226 SkImageInfo info = SkImageInfo::Make(bitmap_size, bitmap_size,
1227 SkColorType::kRGBA_8888_SkColorType,
1228 SkAlphaType::kPremul_SkAlphaType);
1229 bitmap.allocPixels(info, 0);
1230 bitmap.eraseColor(SK_ColorBLUE);
1235 const DlPoint delta(0.5f, 0.5f);
1239 state.counters[
"DrawCallCount"] = kImagesToDraw;
1240 for (
size_t i = 0;
i < kImagesToDraw;
i++) {
1241 if (upload_bitmap) {
1249 auto display_list = builder.
Build();
1250 FML_CHECK(display_list->GetRecordCount() >= kImagesToDraw);
1252 size_t items_processed = 0;
1253 for ([[maybe_unused]]
auto _ : state) {
1254 surface->RenderDisplayList(display_list);
1255 items_processed += kImagesToDraw;
1256 surface->FlushSubmitCpuSync();
1258 state.SetItemsProcessed(items_processed);
1260 std::string image_type = (upload_bitmap ?
"Upload-" :
"Texture-");
1261 SaveSnapshotIfNecessary(
1262 surface_provider,
surface, state,
1263 "DrawImage-" + image_type + std::to_string(bitmap_size));
1267 switch (constraint) {
1283 unsigned attributes,
1286 bool upload_bitmap) {
1289 DlPaint paint = GetPaintForRun(attributes);
1291 CheckAttributes(attributes, state,
1294 size_t bitmap_size = state.range(0);
1295 surface_provider->InitializeSurface(bitmap_size * 2, bitmap_size * 2);
1296 auto surface = surface_provider->GetPrimarySurface();
1298 surface->FlushSubmitCpuSync();
1300 sk_sp<DlImage>
image;
1303 if (upload_bitmap) {
1304 SkImageInfo info = SkImageInfo::Make(bitmap_size, bitmap_size,
1305 SkColorType::kRGBA_8888_SkColorType,
1306 SkAlphaType::kPremul_SkAlphaType);
1307 bitmap.allocPixels(info, 0);
1308 bitmap.eraseColor(SK_ColorBLUE);
1313 const DlPoint delta(0.5f, 0.5f);
1315 bitmap_size / 2.0f, bitmap_size / 2.0f);
1316 DlSize size(bitmap_size * 0.75f, bitmap_size * 0.75f);
1319 state.counters[
"DrawCallCount"] = kImagesToDraw;
1320 for (
size_t i = 0;
i < kImagesToDraw;
i++) {
1321 if (upload_bitmap) {
1330 auto display_list = builder.
Build();
1331 FML_CHECK(display_list->GetRecordCount() >= kImagesToDraw);
1333 size_t items_processed = 0;
1334 for ([[maybe_unused]]
auto _ : state) {
1335 surface->RenderDisplayList(display_list);
1336 items_processed += kImagesToDraw;
1337 surface->FlushSubmitCpuSync();
1339 state.SetItemsProcessed(items_processed);
1341 std::string image_type = (upload_bitmap ?
"Upload-" :
"Texture-");
1342 SaveSnapshotIfNecessary(surface_provider,
surface, state,
1343 "DrawImageRect-" + image_type +
1345 std::to_string(bitmap_size));
1366 unsigned attributes,
1368 bool upload_bitmap) {
1371 DlPaint paint = GetPaintForRun(attributes);
1373 CheckAttributes(attributes, state,
1376 size_t bitmap_size = state.range(0);
1377 surface_provider->InitializeSurface(bitmap_size * 2, bitmap_size * 2);
1378 auto surface = surface_provider->GetPrimarySurface();
1380 surface->FlushSubmitCpuSync();
1383 bitmap_size / 2, bitmap_size / 2);
1385 sk_sp<DlImage>
image;
1388 if (upload_bitmap) {
1389 SkImageInfo info = SkImageInfo::Make(bitmap_size, bitmap_size,
1390 SkColorType::kRGBA_8888_SkColorType,
1391 SkAlphaType::kPremul_SkAlphaType);
1392 bitmap.allocPixels(info, 0);
1393 bitmap.eraseColor(SK_ColorBLUE);
1398 const DlPoint delta(0.5f, 0.5f);
1399 DlSize size(bitmap_size * 0.75f, bitmap_size * 0.75f);
1402 state.counters[
"DrawCallCount"] = kImagesToDraw;
1403 for (
size_t i = 0;
i < kImagesToDraw;
i++) {
1404 if (upload_bitmap) {
1412 auto display_list = builder.
Build();
1413 FML_CHECK(display_list->GetRecordCount() >= kImagesToDraw);
1415 size_t items_processed = 0;
1416 for ([[maybe_unused]]
auto _ : state) {
1417 surface->RenderDisplayList(display_list);
1418 items_processed += kImagesToDraw;
1419 surface->FlushSubmitCpuSync();
1421 state.SetItemsProcessed(items_processed);
1423 std::string image_type = (upload_bitmap ?
"Upload-" :
"Texture-");
1424 SaveSnapshotIfNecessary(surface_provider,
surface, state,
1425 "DrawImageNine-" + image_type +
1427 std::to_string(bitmap_size));
1439 unsigned attributes) {
1442 DlPaint paint = GetPaintForRun(attributes);
1446 size_t draw_calls = state.range(0);
1447 surface_provider->InitializeSurface(kFixedCanvasSize, kFixedCanvasSize);
1448 auto surface = surface_provider->GetPrimarySurface();
1450 surface->FlushSubmitCpuSync();
1452 state.SetComplexityN(draw_calls);
1453 state.counters[
"DrawCallCount_Varies"] = draw_calls;
1454 state.counters[
"GlyphCount"] = draw_calls;
1457 for (
size_t i = 0;
i < draw_calls;
i++) {
1463 auto display_list = builder.
Build();
1464 FML_CHECK(display_list->GetRecordCount() >= draw_calls);
1466 size_t items_processed = 0;
1467 for ([[maybe_unused]]
auto _ : state) {
1468 surface->RenderDisplayList(display_list);
1469 items_processed += draw_calls;
1470 surface->FlushSubmitCpuSync();
1472 state.SetItemsProcessed(items_processed);
1474 SaveSnapshotIfNecessary(surface_provider,
surface, state,
1475 "DrawTextBlob-" + std::to_string(draw_calls));
1488 unsigned attributes,
1489 bool transparent_occluder,
1493 DlPaint paint = GetPaintForRun(attributes);
1497 size_t length = kFixedCanvasSize;
1499 auto surface = surface_provider->GetPrimarySurface();
1501 surface->FlushSubmitCpuSync();
1506 float radius =
length * 0.25f;
1525 float elevation = state.range(0);
1526 state.counters[
"DrawCallCount"] = 1;
1533 transparent_occluder, 1.0f);
1534 auto display_list = builder.
Build();
1537 surface->RenderDisplayList(display_list);
1538 surface->FlushSubmitCpuSync();
1541 size_t items_processed = 0;
1542 for ([[maybe_unused]]
auto _ : state) {
1543 surface->RenderDisplayList(display_list);
1544 items_processed += 1;
1545 surface->FlushSubmitCpuSync();
1547 state.SetItemsProcessed(items_processed);
1549 SaveSnapshotIfNecessary(
1550 surface_provider,
surface, state,
1552 (transparent_occluder ?
"Transparent-" :
"Opaque-") +
1553 std::to_string(elevation));
1564 unsigned attributes,
1565 size_t save_depth) {
1568 DlPaint paint = GetPaintForRun(attributes);
1572 size_t length = kFixedCanvasSize;
1574 auto surface = surface_provider->GetPrimarySurface();
1576 surface->FlushSubmitCpuSync();
1578 size_t save_layer_calls = state.range(0);
1585 size_t total_save_calls = save_layer_calls * save_depth;
1586 state.counters[
"DrawCallCount_Varies"] = total_save_calls;
1587 for (
size_t i = 0;
i < save_layer_calls;
i++) {
1588 for (
size_t j = 0; j < save_depth; j++) {
1589 builder.
SaveLayer(std::nullopt,
nullptr);
1593 for (
size_t j = 0; j < save_depth; j++) {
1597 auto display_list = builder.
Build();
1598 FML_CHECK(display_list->GetRecordCount() >= total_save_calls);
1601 size_t items_processed = 0;
1602 for ([[maybe_unused]]
auto _ : state) {
1603 surface->RenderDisplayList(display_list);
1604 items_processed += total_save_calls;
1605 surface->FlushSubmitCpuSync();
1607 state.SetItemsProcessed(items_processed);
1609 SaveSnapshotIfNecessary(surface_provider,
surface, state,
1610 "SaveLayer-" + std::to_string(save_depth) +
"x" +
1611 std::to_string(save_layer_calls));
1614#ifdef DISPLAY_LIST_BENCHMARK_ALL_OPS
1616#ifdef ENABLE_SOFTWARE_BENCHMARKS
1620#ifdef ENABLE_OPENGL_BENCHMARKS
1624#ifdef ENABLE_METAL_BENCHMARKS
1645#define BENCHMARK_OVERHEAD(FUNC, BACKEND) \
1646 BENCHMARK_CAPTURE(BM_##FUNC, BACKEND, BackendType::k##BACKEND) \
1647 ->RangeMultiplier(4) \
1650 ->Unit(benchmark::kNanosecond);
1652#define DRAW_BENCHMARK_PRIMITIVES_LIMITS(BACKEND, TYPE, ATTRIBUTES, \
1654 BENCHMARK_CAPTURE(BM_Draw##TYPE, ATTRIBUTES/BACKEND, \
1655 BackendType::k##BACKEND, \
1656 k##ATTRIBUTES##Primitive) \
1657 ->RangeMultiplier(MULT) \
1660 ->Unit(benchmark::kMillisecond);
1662#define DRAW_BENCHMARK_PRIMITIVE(BACKEND, TYPE, ATTRIBUTES) \
1663 DRAW_BENCHMARK_PRIMITIVES_LIMITS(BACKEND, TYPE, ATTRIBUTES, 16, 1024, 4)
1665#define DRAW_BENCHMARK_SHADOW_PRIMITIVE(BACKEND, TYPE, ATTRIBUTES) \
1666 DRAW_BENCHMARK_PRIMITIVES_LIMITS(BACKEND, TYPE, ATTRIBUTES, 64, 256, 4)
1668#define DRAW_BENCHMARK_PRIMITIVES_LINE(BACKEND) \
1669 DRAW_BENCHMARK_PRIMITIVE(BACKEND, Line, AAHairline) \
1670 DRAW_BENCHMARK_PRIMITIVE(BACKEND, Line, AAStroke10) \
1672#define DRAW_BENCHMARK_PRIMITIVES_TYPE(BACKEND, TYPE) \
1673 DRAW_BENCHMARK_PRIMITIVE(BACKEND, TYPE, AAFilled) \
1674 DRAW_BENCHMARK_PRIMITIVE(BACKEND, TYPE, AAHairline) \
1675 DRAW_BENCHMARK_PRIMITIVE(BACKEND, TYPE, AAStroke10) \
1676 DRAW_BENCHMARK_SHADOW_PRIMITIVE(BACKEND, TYPE, FilledShadow5) \
1677 DRAW_BENCHMARK_SHADOW_PRIMITIVE(BACKEND, TYPE, FilledShadow10) \
1679#define DRAW_BENCHMARK_PRIMITIVE_SUITE(BACKEND) \
1680 BENCHMARK_OVERHEAD(SyncOverhead, BACKEND) \
1681 BENCHMARK_OVERHEAD(EmptyDisplayList, BACKEND) \
1682 BENCHMARK_OVERHEAD(SingleOpDisplayList, BACKEND) \
1683 DRAW_BENCHMARK_PRIMITIVES_LINE(BACKEND) \
1684 DRAW_BENCHMARK_PRIMITIVES_TYPE(BACKEND, Rect) \
1685 DRAW_BENCHMARK_PRIMITIVES_TYPE(BACKEND, Oval) \
1686 DRAW_BENCHMARK_PRIMITIVES_TYPE(BACKEND, Circle) \
1687 DRAW_BENCHMARK_PRIMITIVES_TYPE(BACKEND, SimpleRRect) \
1688 DRAW_BENCHMARK_PRIMITIVES_TYPE(BACKEND, ComplexRRect) \
1689 DRAW_BENCHMARK_PRIMITIVES_TYPE(BACKEND, SimpleRSE) \
1690 DRAW_BENCHMARK_PRIMITIVES_TYPE(BACKEND, ComplexRSE)
1694#ifdef ENABLE_SOFTWARE_BENCHMARKS
1698#ifdef ENABLE_OPENGL_BENCHMARKS
1702#ifdef ENABLE_METAL_BENCHMARKS
void DrawOval(const DlRect &bounds, const DlPaint &paint) override
void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast) override
void DrawVertices(const std::shared_ptr< DlVertices > &vertices, DlBlendMode mode, const DlPaint &paint) override
void DrawImageNine(const sk_sp< DlImage > &image, const DlIRect ¢er, const DlRect &dst, DlFilterMode filter, const DlPaint *paint=nullptr) override
void DrawRoundRect(const DlRoundRect &rrect, const DlPaint &paint) override
void DrawArc(const DlRect &bounds, DlScalar start, DlScalar sweep, bool useCenter, const DlPaint &paint) override
void DrawShadow(const DlPath &path, const DlColor color, const DlScalar elevation, bool transparent_occluder, DlScalar dpr) override
Draws the shadow of the given |path| rendered in the provided |color| (which is only consulted for it...
void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr) override
void DrawCircle(const DlPoint ¢er, DlScalar radius, const DlPaint &paint) override
void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt) override
void DrawLine(const DlPoint &p0, const DlPoint &p1, const DlPaint &paint) override
void DrawText(const std::shared_ptr< DlText > &text, DlScalar x, DlScalar y, const DlPaint &paint) override
void DrawRoundSuperellipse(const DlRoundSuperellipse &rse, const DlPaint &paint) override
sk_sp< DisplayList > Build()
void DrawPath(const DlPath &path, const DlPaint &paint) override
void DrawPoints(DlPointMode mode, uint32_t count, const DlPoint pts[], const DlPaint &paint) override
void DrawDiffRoundRect(const DlRoundRect &outer, const DlRoundRect &inner, const DlPaint &paint) override
void DrawRect(const DlRect &rect, const DlPaint &paint) override
static constexpr DisplayListAttributeFlags kDrawVerticesFlags
static constexpr DisplayListAttributeFlags kDrawArcNoCenterFlags
static constexpr DisplayListAttributeFlags kDrawImageRectWithPaintFlags
static constexpr DisplayListAttributeFlags kSaveLayerFlags
static constexpr DisplayListAttributeFlags kDrawOvalFlags
static constexpr DisplayListAttributeFlags kDrawPointsAsLinesFlags
static constexpr DisplayListAttributeFlags kDrawPointsAsPolygonFlags
static constexpr DisplayListAttributeFlags kDrawCircleFlags
static constexpr DisplayListAttributeFlags kDrawPathFlags
static constexpr DisplayListAttributeFlags kDrawLineFlags
static constexpr DisplayListAttributeFlags kDrawPointsAsPointsFlags
static constexpr DisplayListAttributeFlags kDrawImageWithPaintFlags
static constexpr DisplayListAttributeFlags kDrawImageNineWithPaintFlags
static constexpr DisplayListAttributeFlags kDrawTextFlags
static constexpr DisplayListAttributeFlags kDrawShadowFlags
static constexpr DisplayListAttributeFlags kDrawRSuperellipseFlags
static constexpr DisplayListAttributeFlags kDrawRRectFlags
static constexpr DisplayListAttributeFlags kDrawDRRectFlags
static constexpr DisplayListAttributeFlags kDrawRectFlags
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
static sk_sp< DlImage > Make(const SkImage *image)
DlPaint & setStrokeWidth(float width)
DlPaint & setDrawStyle(DlDrawStyle style)
DlPathBuilder & LineTo(DlPoint p2)
Draw a line from the current point to the indicated point p2.
DlPathBuilder & MoveTo(DlPoint p2)
Start a new contour that will originate at the indicated point p2.
const DlPath TakePath()
Returns the path constructed by this path builder and resets its internal state to the default state ...
DlPathBuilder & ConicCurveTo(DlPoint cp, DlPoint p2, DlScalar weight)
Draw a conic curve (a rational quadratic bezier curve) from the current point to the indicated point ...
DlPathBuilder & QuadraticCurveTo(DlPoint cp, DlPoint p2)
Draw a quadratic bezier curve from the current point to the indicated point p2, using the indicated p...
DlPathBuilder & Close()
The path is closed back to the location of the most recent MoveTo call. Contours that are filled are ...
DlPathBuilder & CubicCurveTo(DlPoint cp1, DlPoint cp2, DlPoint p2)
Draw a cubic bezier curve from the current point to the indicated point p2, using the indicated point...
void Dispatch(DlPathReceiver &receiver) const override
static std::shared_ptr< DlTextSkia > Make(const sk_sp< SkTextBlob > &blob)
static std::shared_ptr< DlVertices > Make(DlVertexMode mode, int vertex_count, const DlPoint vertices[], const DlPoint texture_coordinates[], const DlColor colors[], int index_count=0, const uint16_t indices[]=nullptr, const DlRect *bounds=nullptr)
Constructs a DlVector with compact inline storage for all of its required and optional lists of data.
static std::unique_ptr< DlSurfaceProvider > Create(BackendType backend_type)
#define DRAW_BENCHMARK_PRIMITIVE_SUITE(BACKEND)
#define RUN_DISPLAYLIST_BENCHMARKS(BACKEND)
FlutterVulkanImage * image
#define FML_CHECK(condition)
#define FML_UNREACHABLE()
std::shared_ptr< SkBitmap > bitmap
std::string VertexModeToString(DlVertexMode mode)
void BM_DrawNinePatchRSE(benchmark::State &state, BackendType backend_type, unsigned attributes)
void BM_DrawVertices(benchmark::State &state, BackendType backend_type, unsigned attributes, DlVertexMode mode)
void BM_DrawNinePatchRRect(benchmark::State &state, BackendType backend_type, unsigned attributes)
constexpr int kFilledShadow10Primitive
std::shared_ptr< DlVertices > GetTestVertices(DlPoint center, float radius, size_t vertex_count, DlVertexMode mode, size_t &final_vertex_count)
void BM_DrawPath(benchmark::State &state, BackendType backend_type, unsigned attributes, PathVerb type)
SkFont CreateTestFontOfSize(DlScalar scalar)
constexpr int kAAFilledPrimitive
void BM_DrawPoints(benchmark::State &state, BackendType backend_type, unsigned attributes, DlPointMode mode)
void BM_DrawOval(benchmark::State &state, BackendType backend_type, unsigned attributes)
void BM_DrawComplexRRect(benchmark::State &state, BackendType backend_type, unsigned attributes)
void GetLinesPath(DlPathBuilder &path_builder, size_t sides, DlPoint center, float radius)
void BM_DrawShadow(benchmark::State &state, BackendType backend_type, unsigned attributes, bool transparent_occluder, PathVerb type)
void BM_SyncOverhead(benchmark::State &state, BackendType backend_type)
std::string ConstraintToString(DlSrcRectConstraint constraint)
std::string PointModeToString(DlPointMode mode)
void BM_DrawImage(benchmark::State &state, BackendType backend_type, unsigned attributes, DlImageSampling options, bool upload_bitmap)
void BM_DrawLine(benchmark::State &state, BackendType backend_type, unsigned attributes)
void BM_DrawCircle(benchmark::State &state, BackendType backend_type, unsigned attributes)
void BM_DrawRRect(benchmark::State &state, BackendType backend_type, unsigned attributes, RRectType type)
void GetConicsPath(DlPathBuilder &path_builder, size_t sides, DlPoint center, float radius)
void GetQuadsPath(DlPathBuilder &path_builder, size_t sides, DlPoint center, float radius)
void BM_DrawRSE(benchmark::State &state, BackendType backend_type, unsigned attributes, RRectType type)
void BM_DrawRect(benchmark::State &state, BackendType backend_type, unsigned attributes)
sk_sp< DlImage > MakeTestImage(int w, int h, int checker_size)
std::string FilterModeToString(const DlFilterMode mode)
sk_sp< SkImage > ImageFromBitmapWithNewID(const SkBitmap &bitmap)
std::vector< DlPoint > GetPolygonPoints(size_t n, DlPoint center, DlScalar r)
std::string VerbToString(PathVerb type)
void BM_DrawDRRect(benchmark::State &state, BackendType backend_type, unsigned attributes, RRectType type)
void BM_DrawTextBlob(benchmark::State &state, BackendType backend_type, unsigned attributes)
std::vector< DlPoint > GetTestPoints(size_t count, DlISize canvas_size)
constexpr int kAAStroke10Primitive
void BM_DrawArc(benchmark::State &state, BackendType backend_type, unsigned attributes)
void MultiplyPath(DlPathBuilder &path_builder, PathVerb type, DlPoint center, size_t sides, size_t number, float radius)
constexpr int kFilledShadow5Primitive
void BM_DrawImageNine(benchmark::State &state, BackendType backend_type, unsigned attributes, const DlFilterMode filter, bool upload_bitmap)
void BM_SaveLayer(benchmark::State &state, BackendType backend_type, unsigned attributes, size_t save_depth)
void BM_DrawSimpleRRect(benchmark::State &state, BackendType backend_type, unsigned attributes)
void GetCubicsPath(DlPathBuilder &path_builder, size_t sides, DlPoint center, float radius)
void BM_DrawImageRect(benchmark::State &state, BackendType backend_type, unsigned attributes, DlImageSampling options, DlSrcRectConstraint constraint, bool upload_bitmap)
void BM_DrawSimpleRSE(benchmark::State &state, BackendType backend_type, unsigned attributes)
constexpr int kAAHairlinePrimitive
void BM_DrawComplexRSE(benchmark::State &state, BackendType backend_type, unsigned attributes)
void BM_EmptyDisplayList(benchmark::State &state, BackendType backend_type)
void BM_SingleOpDisplayList(benchmark::State &state, BackendType backend_type)
impeller::Scalar DlScalar
impeller::PathReceiver DlPathReceiver
impeller::ISize32 DlISize
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
@ kLines
draw each separate pair of points as a line segment
@ kPolygon
draw each pair of overlapping points as a line segment
@ kPoints
draw each point separately
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
DlVertexMode
Defines the way in which the vertices of a DlVertices object are separated into triangles into which ...
@ kTriangles
The vertices are taken 3 at a time to form a triangle.
@ kStrokeAndFill
both strokes and fills shapes
@ kStroke
strokes boundary of shapes
@ kFill
fills interior of shapes
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 mode
@ kNormal
fuzzy inside and outside
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
void CubicTo(PathBuilder *builder, Scalar x1, Scalar y1, Scalar x2, Scalar y2, Scalar x3, Scalar y3)
void Close(PathBuilder *builder)
impeller::ShaderType type
static constexpr DlColor kTransparent()
static constexpr DlColor kRed()
static RoundRect MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
static RoundSuperellipse MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
static constexpr TRect MakeWH(Type width, Type height)
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
static constexpr TRect MakeSize(const TSize< U > &size)
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
std::vector< Point > points