diff --git a/engine/src/flutter/display_list/display_list_benchmarks.cc b/engine/src/flutter/display_list/display_list_benchmarks.cc index a8f75ed381f..c6ded7baa6d 100644 --- a/engine/src/flutter/display_list/display_list_benchmarks.cc +++ b/engine/src/flutter/display_list/display_list_benchmarks.cc @@ -4,6 +4,7 @@ #include "flutter/display_list/display_list_benchmarks.h" #include "flutter/display_list/display_list_builder.h" +#include "flutter/display_list/display_list_flags.h" #include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkTextBlob.h" @@ -32,6 +33,47 @@ std::unique_ptr CreateCanvasProvider(BackendType backend_type) { return nullptr; } +SkPaint GetPaintForRun(unsigned attributes) { + SkPaint paint; + + if (attributes & kStrokedStyle_Flag && attributes & kFilledStyle_Flag) { + // Not currently exposed by Flutter, but we can probably benchmark this in + // the future + paint.setStyle(SkPaint::kStrokeAndFill_Style); + } else if (attributes & kStrokedStyle_Flag) { + paint.setStyle(SkPaint::kStroke_Style); + } else if (attributes & kFilledStyle_Flag) { + paint.setStyle(SkPaint::kFill_Style); + } + + if (attributes & kHairlineStroke_Flag) { + paint.setStrokeWidth(0.0f); + } else { + paint.setStrokeWidth(1.0f); + } + + paint.setAntiAlias(attributes & kAntiAliasing_Flag); + return paint; +} + +void AnnotateAttributes(unsigned attributes, + benchmark::State& state, + const DisplayListAttributeFlags flags) { + if (flags.always_stroked()) { + state.counters["HairlineStroke"] = + attributes & kHairlineStroke_Flag ? 1 : 0; + } + if (flags.applies_style()) { + state.counters["HairlineStroke"] = + attributes & kHairlineStroke_Flag ? 1 : 0; + state.counters["StrokedStyle"] = attributes & kStrokedStyle_Flag ? 1 : 0; + state.counters["FilledStyle"] = attributes & kFilledStyle_Flag ? 1 : 0; + } + if (flags.applies_anti_alias()) { + state.counters["AntiAliasing"] = attributes & kAntiAliasing_Flag ? 1 : 0; + } +} + // Constants chosen to produce benchmark results in the region of 1-50ms constexpr size_t kLinesToDraw = 10000; constexpr size_t kRectsToDraw = 5000; @@ -48,9 +90,15 @@ constexpr size_t kFixedCanvasSize = 1024; // to left (at the bottom) until 10,000 lines are drawn. // // The resulting image will be an hourglass shape. -void BM_DrawLine(benchmark::State& state, BackendType backend_type) { +void BM_DrawLine(benchmark::State& state, + BackendType backend_type, + unsigned attributes) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawLineFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawLineFlags); + size_t length = state.range(0); canvas_provider->InitializeSurface(length, length); @@ -78,9 +126,15 @@ void BM_DrawLine(benchmark::State& state, BackendType backend_type) { // the canvas and repeats until `kRectsToDraw` rects have been drawn. // // Half the drawn rects will not have an integral offset. -void BM_DrawRect(benchmark::State& state, BackendType backend_type) { +void BM_DrawRect(benchmark::State& state, + BackendType backend_type, + unsigned attributes) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawRectFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawRectFlags); + size_t length = state.range(0); size_t canvas_size = length * 2; canvas_provider->InitializeSurface(canvas_size, canvas_size); @@ -119,9 +173,15 @@ void BM_DrawRect(benchmark::State& state, BackendType backend_type) { // the canvas and repeats until `kOvalsToDraw` ovals have been drawn. // // Half the drawn ovals will not have an integral offset. -void BM_DrawOval(benchmark::State& state, BackendType backend_type) { +void BM_DrawOval(benchmark::State& state, + BackendType backend_type, + unsigned attributes) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawOvalFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawOvalFlags); + size_t length = state.range(0); size_t canvas_size = length * 2; canvas_provider->InitializeSurface(canvas_size, canvas_size); @@ -157,9 +217,15 @@ void BM_DrawOval(benchmark::State& state, BackendType backend_type) { // the canvas and repeats until `kCirclesToDraw` circles have been drawn. // // Half the drawn circles will not have an integral center point. -void BM_DrawCircle(benchmark::State& state, BackendType backend_type) { +void BM_DrawCircle(benchmark::State& state, + BackendType backend_type, + unsigned attributes) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawCircleFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawCircleFlags); + size_t length = state.range(0); size_t canvas_size = length * 2; canvas_provider->InitializeSurface(canvas_size, canvas_size); @@ -199,9 +265,14 @@ void BM_DrawCircle(benchmark::State& state, BackendType backend_type) { // Half the drawn rounded rects will not have an integral offset. void BM_DrawRRect(benchmark::State& state, BackendType backend_type, + unsigned attributes, SkRRect::Type type) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawRRectFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawRRectFlags); + size_t length = state.range(0); size_t canvas_size = length * 2; canvas_provider->InitializeSurface(canvas_size, canvas_size); @@ -264,9 +335,16 @@ void BM_DrawRRect(benchmark::State& state, canvas_provider->Snapshot(filename); } -void BM_DrawArc(benchmark::State& state, BackendType backend_type) { +void BM_DrawArc(benchmark::State& state, + BackendType backend_type, + unsigned attributes) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawArcNoCenterFlags); + AnnotateAttributes(attributes, state, + DisplayListOpFlags::kDrawArcNoCenterFlags); + size_t length = state.range(0); size_t canvas_size = length * 2; canvas_provider->InitializeSurface(canvas_size, canvas_size); @@ -472,9 +550,14 @@ std::string VerbToString(SkPath::Verb type) { // to the verb count. void BM_DrawPath(benchmark::State& state, BackendType backend_type, + unsigned attributes, SkPath::Verb type) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawPathFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawPathFlags); + size_t length = kFixedCanvasSize; canvas_provider->InitializeSurface(length, length); auto canvas = canvas_provider->GetSurface()->getCanvas(); @@ -602,9 +685,14 @@ std::string VertexModeToString(SkVertices::VertexMode mode) { // of the canvas width/height, with each point being equally spaced out. void BM_DrawVertices(benchmark::State& state, BackendType backend_type, + unsigned attributes, SkVertices::VertexMode mode) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawVerticesFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawVerticesFlags); + size_t length = kFixedCanvasSize; canvas_provider->InitializeSurface(length, length); auto canvas = canvas_provider->GetSurface()->getCanvas(); @@ -691,9 +779,35 @@ std::string PointModeToString(SkCanvas::PointMode mode) { // `DrawPoints` with N being the number of points being drawn. void BM_DrawPoints(benchmark::State& state, BackendType backend_type, + unsigned attributes, SkCanvas::PointMode mode) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + SkPaint paint; + switch (mode) { + case SkCanvas::kPoints_PointMode: + builder.setAttributesFromPaint( + GetPaintForRun(attributes), + DisplayListOpFlags::kDrawPointsAsPointsFlags); + AnnotateAttributes(attributes, state, + DisplayListOpFlags::kDrawPointsAsPointsFlags); + break; + case SkCanvas::kLines_PointMode: + builder.setAttributesFromPaint( + GetPaintForRun(attributes), + DisplayListOpFlags::kDrawPointsAsLinesFlags); + AnnotateAttributes(attributes, state, + DisplayListOpFlags::kDrawPointsAsLinesFlags); + break; + case SkCanvas::kPolygon_PointMode: + builder.setAttributesFromPaint( + GetPaintForRun(attributes), + DisplayListOpFlags::kDrawPointsAsPolygonFlags); + AnnotateAttributes(attributes, state, + DisplayListOpFlags::kDrawPointsAsPolygonFlags); + break; + } + size_t length = kFixedCanvasSize; canvas_provider->InitializeSurface(length, length); auto canvas = canvas_provider->GetSurface()->getCanvas(); @@ -732,10 +846,16 @@ sk_sp ImageFromBitmapWithNewID(const SkBitmap& bitmap) { // bitmaps or bitmaps that need to be uploaded to the GPU first. void BM_DrawImage(benchmark::State& state, BackendType backend_type, + unsigned attributes, const SkSamplingOptions& options, bool upload_bitmap) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawImageWithPaintFlags); + AnnotateAttributes(attributes, state, + DisplayListOpFlags::kDrawImageWithPaintFlags); + size_t bitmap_size = state.range(0); size_t canvas_size = 2 * bitmap_size; canvas_provider->InitializeSurface(canvas_size, canvas_size); @@ -803,11 +923,18 @@ std::string ConstraintToString(SkCanvas::SrcRectConstraint constraint) { // The bitmaps are shrunk down to 75% of their size when rendered to the canvas. void BM_DrawImageRect(benchmark::State& state, BackendType backend_type, + unsigned attributes, const SkSamplingOptions& options, SkCanvas::SrcRectConstraint constraint, bool upload_bitmap) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint( + GetPaintForRun(attributes), + DisplayListOpFlags::kDrawImageRectWithPaintFlags); + AnnotateAttributes(attributes, state, + DisplayListOpFlags::kDrawImageRectWithPaintFlags); + size_t bitmap_size = state.range(0); size_t canvas_size = 2 * bitmap_size; canvas_provider->InitializeSurface(canvas_size, canvas_size); @@ -879,10 +1006,17 @@ std::string FilterModeToString(const SkFilterMode mode) { // rendering. void BM_DrawImageNine(benchmark::State& state, BackendType backend_type, + unsigned attributes, const SkFilterMode filter, bool upload_bitmap) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint( + GetPaintForRun(attributes), + DisplayListOpFlags::kDrawImageNineWithPaintFlags); + AnnotateAttributes(attributes, state, + DisplayListOpFlags::kDrawImageNineWithPaintFlags); + size_t bitmap_size = state.range(0); size_t canvas_size = 2 * bitmap_size; canvas_provider->InitializeSurface(canvas_size, canvas_size); @@ -944,9 +1078,15 @@ void BM_DrawImageNine(benchmark::State& state, // // This benchmark will automatically calculate the Big-O complexity of // `DrawTextBlob` with N being the number of glyphs being drawn. -void BM_DrawTextBlob(benchmark::State& state, BackendType backend_type) { +void BM_DrawTextBlob(benchmark::State& state, + BackendType backend_type, + unsigned attributes) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawTextBlobFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawTextBlobFlags); + size_t glyph_runs = state.range(0); size_t canvas_size = kFixedCanvasSize; canvas_provider->InitializeSurface(canvas_size, canvas_size); @@ -1010,10 +1150,15 @@ void BM_DrawTextBlob(benchmark::State& state, BackendType backend_type) { // occluder. void BM_DrawShadow(benchmark::State& state, BackendType backend_type, + unsigned attributes, bool transparent_occluder, SkPath::Verb type) { auto canvas_provider = CreateCanvasProvider(backend_type); DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kDrawShadowFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawShadowFlags); + size_t length = kFixedCanvasSize; canvas_provider->InitializeSurface(length, length); auto canvas = canvas_provider->GetSurface()->getCanvas(); @@ -1060,5 +1205,56 @@ void BM_DrawShadow(benchmark::State& state, canvas_provider->Snapshot(filename); } +// Calls saveLayer N times from the root canvas layer, and optionally calls +// saveLayer a further M times nested inside that top saveLayer call. +// +// The total number of saveLayer calls will be N * (M+1). +// +// In each saveLayer call, simply draw the colour red with no clip rect. +void BM_SaveLayer(benchmark::State& state, + BackendType backend_type, + unsigned attributes, + size_t save_depth) { + auto canvas_provider = CreateCanvasProvider(backend_type); + DisplayListBuilder builder; + builder.setAttributesFromPaint(GetPaintForRun(attributes), + DisplayListOpFlags::kSaveLayerFlags); + AnnotateAttributes(attributes, state, DisplayListOpFlags::kSaveLayerFlags); + + size_t length = kFixedCanvasSize; + canvas_provider->InitializeSurface(length, length); + auto canvas = canvas_provider->GetSurface()->getCanvas(); + + size_t save_layer_calls = state.range(0); + + // Ensure we draw two overlapping rects to avoid any peephole optimisations + SkRect rect1 = SkRect::MakeLTRB(0, 0, 0.75f * length, 0.75f * length); + SkRect rect2 = + SkRect::MakeLTRB(0.25f * length, 0.25f * length, length, length); + + for (size_t i = 0; i < save_layer_calls; i++) { + for (size_t j = 0; j < save_depth; j++) { + builder.saveLayer(nullptr, false); + builder.drawRect(rect1); + builder.drawRect(rect2); + } + for (size_t j = 0; j < save_depth; j++) { + builder.restore(); + } + } + auto display_list = builder.Build(); + + // We only want to time the actual rasterization. + for (auto _ : state) { + display_list->RenderTo(canvas); + canvas_provider->GetSurface()->flushAndSubmit(true); + } + + auto filename = canvas_provider->BackendName() + "-SaveLayer-" + + std::to_string(save_depth) + "-" + + std::to_string(save_layer_calls) + ".png"; + canvas_provider->Snapshot(filename); +} + } // namespace testing } // namespace flutter diff --git a/engine/src/flutter/display_list/display_list_benchmarks.h b/engine/src/flutter/display_list/display_list_benchmarks.h index 1733ba9b998..ebdd010f79c 100644 --- a/engine/src/flutter/display_list/display_list_benchmarks.h +++ b/engine/src/flutter/display_list/display_list_benchmarks.h @@ -28,106 +28,136 @@ namespace testing { typedef enum { kSoftware_Backend, kOpenGL_Backend, kMetal_Backend } BackendType; +enum BenchmarkAttributes { + kEmpty_Flag = 0, + kStrokedStyle_Flag = 1 << 0, + kFilledStyle_Flag = 1 << 1, + kHairlineStroke_Flag = 1 << 2, + kAntiAliasing_Flag = 1 << 3 +}; + std::unique_ptr CreateCanvasProvider(BackendType backend_type); +SkPaint GetPaintForRun(unsigned attributes); // Benchmarks -void BM_DrawLine(benchmark::State& state, BackendType backend_type); -void BM_DrawRect(benchmark::State& state, BackendType backend_type); -void BM_DrawCircle(benchmark::State& state, BackendType backend_type); -void BM_DrawOval(benchmark::State& state, BackendType backend_type); -void BM_DrawArc(benchmark::State& state, BackendType backend_type); +void BM_DrawLine(benchmark::State& state, + BackendType backend_type, + unsigned attributes); +void BM_DrawRect(benchmark::State& state, + BackendType backend_type, + unsigned attributes); +void BM_DrawCircle(benchmark::State& state, + BackendType backend_type, + unsigned attributes); +void BM_DrawOval(benchmark::State& state, + BackendType backend_type, + unsigned attributes); +void BM_DrawArc(benchmark::State& state, + BackendType backend_type, + unsigned attributes); void BM_DrawRRect(benchmark::State& state, BackendType backend_type, + unsigned attributes, SkRRect::Type type); void BM_DrawPath(benchmark::State& state, BackendType backend_type, + unsigned attributes, SkPath::Verb type); void BM_DrawPoints(benchmark::State& state, BackendType backend_type, + unsigned attributes, SkCanvas::PointMode mode); void BM_DrawVertices(benchmark::State& state, BackendType backend_type, + unsigned attributes, SkVertices::VertexMode mode); void BM_DrawImage(benchmark::State& state, BackendType backend_type, + unsigned attributes, const SkSamplingOptions& options, bool upload_bitmap); void BM_DrawImageRect(benchmark::State& state, BackendType backend_type, + unsigned attributes, const SkSamplingOptions& options, SkCanvas::SrcRectConstraint constraint, bool upload_bitmap); void BM_DrawImageNine(benchmark::State& state, BackendType backend_type, + unsigned attributes, const SkFilterMode filter, bool upload_bitmap); -void BM_DrawTextBlob(benchmark::State& state, BackendType backend_type); +void BM_DrawTextBlob(benchmark::State& state, + BackendType backend_type, + unsigned attributes); void BM_DrawShadow(benchmark::State& state, BackendType backend_type, + unsigned attributes, bool transparent_occluder, SkPath::Verb type); - +void BM_SaveLayer(benchmark::State& state, + BackendType backend_type, + unsigned attributes, + size_t save_depth); // clang-format off -#define RUN_DISPLAYLIST_BENCHMARKS(BACKEND) \ - \ - /* \ - * DrawLine \ - */ \ +// DrawLine +#define DRAW_LINE_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawLine, BACKEND, \ - BackendType::k##BACKEND##_Backend) \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawRect \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawRect +#define DRAW_RECT_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawRect, BACKEND, \ - BackendType::k##BACKEND##_Backend) \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawOval \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawOval +#define DRAW_OVAL_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawOval, BACKEND, \ - BackendType::k##BACKEND##_Backend) \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawCircle \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawCircle +#define DRAW_CIRCLE_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawCircle, BACKEND, \ - BackendType::k##BACKEND##_Backend) \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawArc \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawArc +#define DRAW_ARC_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawArc, BACKEND, \ - BackendType::k##BACKEND##_Backend) \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES) \ ->RangeMultiplier(2) \ ->Range(128, 2048) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawPath \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawPath +#define DRAW_PATH_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawPath, \ Lines/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkPath::Verb::kLine_Verb) \ ->RangeMultiplier(2) \ ->Range(8, 512) \ @@ -138,6 +168,7 @@ void BM_DrawShadow(benchmark::State& state, BENCHMARK_CAPTURE(BM_DrawPath, \ Quads/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkPath::Verb::kQuad_Verb) \ ->RangeMultiplier(2) \ ->Range(8, 512) \ @@ -148,6 +179,7 @@ void BM_DrawShadow(benchmark::State& state, BENCHMARK_CAPTURE(BM_DrawPath, \ Conics/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkPath::Verb::kConic_Verb) \ ->RangeMultiplier(2) \ ->Range(8, 512) \ @@ -158,18 +190,19 @@ void BM_DrawShadow(benchmark::State& state, BENCHMARK_CAPTURE(BM_DrawPath, \ Cubics/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkPath::Verb::kCubic_Verb) \ ->RangeMultiplier(2) \ ->Range(8, 512) \ ->UseRealTime() \ ->Unit(benchmark::kMillisecond) \ - ->Complexity(); \ - \ - /* \ - * DrawPoints \ - */ \ + ->Complexity(); + +// DrawPoints +#define DRAW_POINTS_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawPoints, Points/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkCanvas::kPoints_PointMode) \ ->RangeMultiplier(2) \ ->Range(1024, 32768) \ @@ -178,6 +211,7 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE(BM_DrawPoints, Lines/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkCanvas::kLines_PointMode) \ ->RangeMultiplier(2) \ ->Range(1024, 32768) \ @@ -186,18 +220,19 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE(BM_DrawPoints, Polygon/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkCanvas::kPolygon_PointMode) \ ->RangeMultiplier(2) \ ->Range(1024, 32768) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawVertices \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawVertices +#define DRAW_VERTICES_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawVertices, \ TriangleStrip/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkVertices::VertexMode::kTriangleStrip_VertexMode) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ @@ -208,6 +243,7 @@ void BM_DrawShadow(benchmark::State& state, BENCHMARK_CAPTURE(BM_DrawVertices, \ TriangleFan/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkVertices::VertexMode::kTriangleFan_VertexMode) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ @@ -218,18 +254,19 @@ void BM_DrawShadow(benchmark::State& state, BENCHMARK_CAPTURE(BM_DrawVertices, \ Triangles/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkVertices::VertexMode::kTriangles_VertexMode) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ ->UseRealTime() \ ->Unit(benchmark::kMillisecond) \ - ->Complexity(); \ - \ - /* \ - * DrawRRect \ - */ \ + ->Complexity(); + +// DrawRRect +#define DRAW_RRECT_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawRRect, Symmetric/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkRRect::Type::kSimple_Type) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ @@ -238,6 +275,7 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE(BM_DrawRRect, NinePatch/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkRRect::Type::kNinePatch_Type) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ @@ -246,17 +284,18 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE(BM_DrawRRect, Complex/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkRRect::Type::kComplex_Type) \ ->RangeMultiplier(2) \ ->Range(16, 2048) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawImage \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawImage +#define DRAW_IMAGE_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawImage, Texture/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkSamplingOptions(), false) \ ->RangeMultiplier(2) \ ->Range(128, 512) \ @@ -265,18 +304,20 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE(BM_DrawImage, Upload/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkSamplingOptions(), true) \ ->RangeMultiplier(2) \ ->Range(128, 512) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawImageRect \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawImageRect +#define DRAW_IMAGE_RECT_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE( \ BM_DrawImageRect, Texture/Strict/BACKEND, \ - BackendType::k##BACKEND##_Backend, SkSamplingOptions(), \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + SkSamplingOptions(), \ SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint, false) \ ->RangeMultiplier(2) \ ->Range(32, 256) \ @@ -285,7 +326,9 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE( \ BM_DrawImageRect, Texture/Fast/BACKEND, \ - BackendType::k##BACKEND##_Backend, SkSamplingOptions(), \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + SkSamplingOptions(), \ SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint, false) \ ->RangeMultiplier(2) \ ->Range(32, 256) \ @@ -294,7 +337,9 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE( \ BM_DrawImageRect, Upload/Strict/BACKEND, \ - BackendType::k##BACKEND##_Backend, SkSamplingOptions(), \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + SkSamplingOptions(), \ SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint, true) \ ->RangeMultiplier(2) \ ->Range(32, 256) \ @@ -303,18 +348,20 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE( \ BM_DrawImageRect, Upload/Fast/BACKEND, \ - BackendType::k##BACKEND##_Backend, SkSamplingOptions(), \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + SkSamplingOptions(), \ SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint, true) \ ->RangeMultiplier(2) \ ->Range(32, 256) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawImageNine \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawImageNine +#define DRAW_IMAGE_NINE_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawImageNine, Texture/Nearest/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkFilterMode::kNearest, false) \ ->RangeMultiplier(2) \ ->Range(32, 256) \ @@ -323,6 +370,7 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE(BM_DrawImageNine, Upload/Nearest/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkFilterMode::kNearest, true) \ ->RangeMultiplier(2) \ ->Range(32, 256) \ @@ -331,6 +379,7 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE(BM_DrawImageNine, Texture/Linear/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkFilterMode::kLinear, false) \ ->RangeMultiplier(2) \ ->Range(32, 256) \ @@ -339,28 +388,30 @@ void BM_DrawShadow(benchmark::State& state, \ BENCHMARK_CAPTURE(BM_DrawImageNine, Upload/Linear/BACKEND, \ BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ SkFilterMode::kLinear, true) \ ->RangeMultiplier(2) \ ->Range(32, 256) \ ->UseRealTime() \ - ->Unit(benchmark::kMillisecond); \ - \ - /* \ - * DrawTextBlob \ - */ \ + ->Unit(benchmark::kMillisecond); + +// DrawTextBlob +#define DRAW_TEXT_BLOB_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawTextBlob, BACKEND, \ - BackendType::k##BACKEND##_Backend) \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES) \ ->RangeMultiplier(2) \ ->Range(1, 256) \ ->UseRealTime() \ ->Unit(benchmark::kMillisecond) \ - ->Complexity(); \ - \ - /* \ - * DrawShadow \ - */ \ + ->Complexity(); + +// DrawShadow +#define DRAW_SHADOW_BENCHMARKS(BACKEND, ATTRIBUTES) \ BENCHMARK_CAPTURE(BM_DrawShadow, Lines/Transparent/BACKEND, \ - BackendType::k##BACKEND##_Backend, true, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + true, \ SkPath::Verb::kLine_Verb) \ ->RangeMultiplier(2) \ ->Range(1, 32) \ @@ -368,7 +419,9 @@ void BM_DrawShadow(benchmark::State& state, ->Unit(benchmark::kMillisecond); \ \ BENCHMARK_CAPTURE(BM_DrawShadow, Quads/Transparent/BACKEND, \ - BackendType::k##BACKEND##_Backend, true, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + true, \ SkPath::Verb::kQuad_Verb) \ ->RangeMultiplier(2) \ ->Range(1, 32) \ @@ -376,7 +429,9 @@ void BM_DrawShadow(benchmark::State& state, ->Unit(benchmark::kMillisecond); \ \ BENCHMARK_CAPTURE(BM_DrawShadow, Conics/Transparent/BACKEND, \ - BackendType::k##BACKEND##_Backend, true, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + true, \ SkPath::Verb::kConic_Verb) \ ->RangeMultiplier(2) \ ->Range(1, 32) \ @@ -384,7 +439,9 @@ void BM_DrawShadow(benchmark::State& state, ->Unit(benchmark::kMillisecond); \ \ BENCHMARK_CAPTURE(BM_DrawShadow, Cubics/Transparent/BACKEND, \ - BackendType::k##BACKEND##_Backend, true, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + true, \ SkPath::Verb::kCubic_Verb) \ ->RangeMultiplier(2) \ ->Range(1, 32) \ @@ -392,7 +449,9 @@ void BM_DrawShadow(benchmark::State& state, ->Unit(benchmark::kMillisecond); \ \ BENCHMARK_CAPTURE(BM_DrawShadow, Lines/Opaque/BACKEND, \ - BackendType::k##BACKEND##_Backend, false, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + false, \ SkPath::Verb::kLine_Verb) \ ->RangeMultiplier(2) \ ->Range(1, 32) \ @@ -400,7 +459,9 @@ void BM_DrawShadow(benchmark::State& state, ->Unit(benchmark::kMillisecond); \ \ BENCHMARK_CAPTURE(BM_DrawShadow, Quads/Opaque/BACKEND, \ - BackendType::k##BACKEND##_Backend, false, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + false, \ SkPath::Verb::kQuad_Verb) \ ->RangeMultiplier(2) \ ->Range(1, 32) \ @@ -408,7 +469,9 @@ void BM_DrawShadow(benchmark::State& state, ->Unit(benchmark::kMillisecond); \ \ BENCHMARK_CAPTURE(BM_DrawShadow, Conics/Opaque/BACKEND, \ - BackendType::k##BACKEND##_Backend, false, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + false, \ SkPath::Verb::kConic_Verb) \ ->RangeMultiplier(2) \ ->Range(1, 32) \ @@ -416,13 +479,81 @@ void BM_DrawShadow(benchmark::State& state, ->Unit(benchmark::kMillisecond); \ \ BENCHMARK_CAPTURE(BM_DrawShadow, Cubics/Opaque/BACKEND, \ - BackendType::k##BACKEND##_Backend, false, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + false, \ SkPath::Verb::kCubic_Verb) \ ->RangeMultiplier(2) \ ->Range(1, 32) \ ->UseRealTime() \ ->Unit(benchmark::kMillisecond); +// SaveLayer +#define SAVE_LAYER_BENCHMARKS(BACKEND, ATTRIBUTES) \ + BENCHMARK_CAPTURE(BM_SaveLayer, BACKEND/Depth 1, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + 1) \ + ->RangeMultiplier(2) \ + ->Range(1, 128) \ + ->UseRealTime() \ + ->Unit(benchmark::kMillisecond); \ + \ + BENCHMARK_CAPTURE(BM_SaveLayer, BACKEND/Depth 8, \ + BackendType::k##BACKEND##_Backend, \ + ATTRIBUTES, \ + 8) \ + ->RangeMultiplier(2) \ + ->Range(1, 128) \ + ->UseRealTime() \ + ->Unit(benchmark::kMillisecond); + +// Applies stroke style and antialiasing +#define STROKE_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_LINE_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_POINTS_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_RECT_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_OVAL_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_CIRCLE_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_ARC_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_PATH_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_RRECT_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_TEXT_BLOB_BENCHMARKS(BACKEND, ATTRIBUTES) + +// Applies fill style and antialiasing +#define FILL_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_RECT_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_OVAL_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_CIRCLE_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_ARC_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_PATH_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_RRECT_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_TEXT_BLOB_BENCHMARKS(BACKEND, ATTRIBUTES) + +// Applies antialiasing +#define ANTI_ALIASING_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_IMAGE_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_IMAGE_RECT_BENCHMARKS(BACKEND, ATTRIBUTES) + +// Does not apply style or antialiasing +#define OTHER_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_IMAGE_NINE_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_VERTICES_BENCHMARKS(BACKEND, ATTRIBUTES) \ + DRAW_SHADOW_BENCHMARKS(BACKEND, ATTRIBUTES) \ + SAVE_LAYER_BENCHMARKS(BACKEND, ATTRIBUTES) + +#define RUN_DISPLAYLIST_BENCHMARKS(BACKEND) \ + STROKE_BENCHMARKS(BACKEND, kStrokedStyle_Flag) \ + STROKE_BENCHMARKS(BACKEND, kStrokedStyle_Flag | kAntiAliasing_Flag) \ + STROKE_BENCHMARKS(BACKEND, kStrokedStyle_Flag | kHairlineStroke_Flag) \ + STROKE_BENCHMARKS(BACKEND, kStrokedStyle_Flag | kHairlineStroke_Flag | \ + kAntiAliasing_Flag) \ + FILL_BENCHMARKS(BACKEND, kFilledStyle_Flag) \ + FILL_BENCHMARKS(BACKEND, kFilledStyle_Flag | kAntiAliasing_Flag) \ + ANTI_ALIASING_BENCHMARKS(BACKEND, kEmpty_Flag) \ + ANTI_ALIASING_BENCHMARKS(BACKEND, kAntiAliasing_Flag) \ + OTHER_BENCHMARKS(BACKEND, kEmpty_Flag) + // clang-format on } // namespace testing