// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/display_list/benchmarking/dl_benchmarks.h"
#include "flutter/display_list/dl_builder.h"
#include "flutter/display_list/dl_op_flags.h"
#include "flutter/display_list/skia/dl_sk_canvas.h"
#include "flutter/display_list/testing/dl_test_snippets.h"

#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkTextBlob.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
#include "third_party/skia/include/gpu/GrRecordingContext.h"
#include "third_party/skia/include/gpu/GrTypes.h"

namespace flutter {
namespace testing {

DlPaint GetPaintForRun(unsigned attributes) {
  DlPaint paint;

  if (attributes & kStrokedStyle && attributes & kFilledStyle) {
    // Not currently exposed by Flutter, but we can probably benchmark this in
    // the future
    paint.setDrawStyle(DlDrawStyle::kStrokeAndFill);
  } else if (attributes & kStrokedStyle) {
    paint.setDrawStyle(DlDrawStyle::kStroke);
  } else if (attributes & kFilledStyle) {
    paint.setDrawStyle(DlDrawStyle::kFill);
  }

  if (attributes & kHairlineStroke) {
    paint.setStrokeWidth(0.0f);
  } else {
    paint.setStrokeWidth(1.0f);
  }

  paint.setAntiAlias(attributes & kAntiAliasing);
  return paint;
}

static void FlushSubmitCpuSync(const sk_sp<SkSurface>& surface) {
  if (!surface) {
    return;
  }
  if (GrDirectContext* dContext =
          GrAsDirectContext(surface->recordingContext())) {
    dContext->flushAndSubmit(surface.get(), GrSyncCpu::kYes);
  }
}

void AnnotateAttributes(unsigned attributes,
                        benchmark::State& state,
                        const DisplayListAttributeFlags flags) {
  if (flags.always_stroked()) {
    state.counters["HairlineStroke"] = attributes & kHairlineStroke ? 1 : 0;
  }
  if (flags.applies_style()) {
    state.counters["HairlineStroke"] = attributes & kHairlineStroke ? 1 : 0;
    state.counters["StrokedStyle"] = attributes & kStrokedStyle ? 1 : 0;
    state.counters["FilledStyle"] = attributes & kFilledStyle ? 1 : 0;
  }
  if (flags.applies_anti_alias()) {
    state.counters["AntiAliasing"] = attributes & kAntiAliasing ? 1 : 0;
  }
}

// Constants chosen to produce benchmark results in the region of 1-50ms
constexpr size_t kLinesToDraw = 10000;
constexpr size_t kRectsToDraw = 5000;
constexpr size_t kOvalsToDraw = 1000;
constexpr size_t kCirclesToDraw = 5000;
constexpr size_t kRRectsToDraw = 5000;
constexpr size_t kDRRectsToDraw = 2000;
constexpr size_t kArcSweepSetsToDraw = 1000;
constexpr size_t kImagesToDraw = 500;
constexpr size_t kFixedCanvasSize = 1024;

// Draw a series of diagonal lines across a square canvas of width/height of
// the length requested. The lines will start from the top left corner to the
// bottom right corner, and move from left to right (at the top) and from right
// 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,
                 unsigned attributes) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawLineFlags);

  size_t length = state.range(0);

  surface_provider->InitializeSurface(length, length);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  state.counters["DrawCallCount"] = kLinesToDraw;
  for (size_t i = 0; i < kLinesToDraw; i++) {
    builder.DrawLine(SkPoint::Make(i % length, 0),
                     SkPoint::Make(length - i % length, length), paint);
  }

  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawLine-" +
                  std::to_string(state.range(0)) + ".png";
  surface_provider->Snapshot(filename);
}

// Draws a series of square rects of the requested width across
// 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,
                 unsigned attributes) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawRectFlags);

  size_t length = state.range(0);
  size_t canvas_size = length * 2;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  // As rects have SkScalar dimensions, we want to ensure that we also
  // draw rects with non-integer position and size
  const SkScalar offset = 0.5f;
  SkRect rect = SkRect::MakeLTRB(0, 0, length, length);

  state.counters["DrawCallCount"] = kRectsToDraw;
  for (size_t i = 0; i < kRectsToDraw; i++) {
    builder.DrawRect(rect, paint);
    rect.offset(offset, offset);
    if (rect.right() > canvas_size) {
      rect.offset(-canvas_size, 0);
    }
    if (rect.bottom() > canvas_size) {
      rect.offset(0, -canvas_size);
    }
  }

  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawRect-" +
                  std::to_string(state.range(0)) + ".png";
  surface_provider->Snapshot(filename);
}

// Draws a series of ovals of the requested height with aspect ratio 3:2 across
// 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,
                 unsigned attributes) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawOvalFlags);

  size_t length = state.range(0);
  size_t canvas_size = length * 2;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  SkRect rect = SkRect::MakeXYWH(0, 0, length * 1.5f, length);
  const SkScalar offset = 0.5f;

  state.counters["DrawCallCount"] = kOvalsToDraw;
  for (size_t i = 0; i < kOvalsToDraw; i++) {
    builder.DrawOval(rect, paint);
    rect.offset(offset, offset);
    if (rect.right() > canvas_size) {
      rect.offset(-canvas_size, 0);
    }
    if (rect.bottom() > canvas_size) {
      rect.offset(0, -canvas_size);
    }
  }
  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawOval-" +
                  std::to_string(state.range(0)) + ".png";
  surface_provider->Snapshot(filename);
}

// Draws a series of circles of the requested radius across
// 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,
                   unsigned attributes) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawCircleFlags);

  size_t length = state.range(0);
  size_t canvas_size = length * 2;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  SkScalar radius = length / 2.0f;
  const SkScalar offset = 0.5f;

  SkPoint center = SkPoint::Make(radius, radius);

  state.counters["DrawCallCount"] = kCirclesToDraw;
  for (size_t i = 0; i < kCirclesToDraw; i++) {
    builder.DrawCircle(center, radius, paint);
    center.offset(offset, offset);
    if (center.x() + radius > canvas_size) {
      center.set(radius, center.y());
    }
    if (center.y() + radius > canvas_size) {
      center.set(center.x(), radius);
    }
  }
  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawCircle-" +
                  std::to_string(state.range(0)) + ".png";
  surface_provider->Snapshot(filename);
}

// Draws a series of rounded rects of the requested width across
// the canvas and repeats until `kRRectsToDraw` rects have been drawn.
//
// 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 surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawRRectFlags);

  size_t length = state.range(0);
  size_t canvas_size = length * 2;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  SkVector radii[4] = {};
  switch (type) {
    case SkRRect::Type::kSimple_Type:
      radii[0] = SkVector::Make(5.0f, 5.0f);
      radii[1] = SkVector::Make(5.0f, 5.0f);
      radii[2] = SkVector::Make(5.0f, 5.0f);
      radii[3] = SkVector::Make(5.0f, 5.0f);
      break;
    case SkRRect::Type::kNinePatch_Type:
      radii[0] = SkVector::Make(5.0f, 2.0f);
      radii[1] = SkVector::Make(3.0f, 2.0f);
      radii[2] = SkVector::Make(3.0f, 4.0f);
      radii[3] = SkVector::Make(5.0f, 4.0f);
      break;
    case SkRRect::Type::kComplex_Type:
      radii[0] = SkVector::Make(5.0f, 4.0f);
      radii[1] = SkVector::Make(4.0f, 5.0f);
      radii[2] = SkVector::Make(3.0f, 6.0f);
      radii[3] = SkVector::Make(2.0f, 7.0f);
      break;
    default:
      break;
  }

  const SkScalar offset = 0.5f;
  const SkScalar multiplier = length / 16.0f;
  SkRRect rrect;

  SkVector set_radii[4];
  for (size_t i = 0; i < 4; i++) {
    set_radii[i] = radii[i] * multiplier;
  }
  rrect.setRectRadii(SkRect::MakeLTRB(0, 0, length, length), set_radii);

  state.counters["DrawCallCount"] = kRRectsToDraw;
  for (size_t i = 0; i < kRRectsToDraw; i++) {
    builder.DrawRRect(rrect, paint);
    rrect.offset(offset, offset);
    if (rrect.rect().right() > canvas_size) {
      rrect.offset(-canvas_size, 0);
    }
    if (rrect.rect().bottom() > canvas_size) {
      rrect.offset(0, -canvas_size);
    }
  }
  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawRRect-" +
                  std::to_string(state.range(0)) + ".png";
  surface_provider->Snapshot(filename);
}

// Draws a series of "DR" rects of the requested width across
// the canvas and repeats until `kRRectsToDraw` rects have been drawn.
//
// A "DR" rect is a shape consisting of the difference between two
// rounded rects.
//
// Half the drawn DR rects will not have an integral offset.
void BM_DrawDRRect(benchmark::State& state,
                   BackendType backend_type,
                   unsigned attributes,
                   SkRRect::Type type) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawDRRectFlags);

  size_t length = state.range(0);
  size_t canvas_size = length * 2;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  SkVector radii[4] = {};
  switch (type) {
    case SkRRect::Type::kSimple_Type:
      radii[0] = SkVector::Make(5.0f, 5.0f);
      radii[1] = SkVector::Make(5.0f, 5.0f);
      radii[2] = SkVector::Make(5.0f, 5.0f);
      radii[3] = SkVector::Make(5.0f, 5.0f);
      break;
    case SkRRect::Type::kNinePatch_Type:
      radii[0] = SkVector::Make(5.0f, 7.0f);
      radii[1] = SkVector::Make(3.0f, 7.0f);
      radii[2] = SkVector::Make(3.0f, 4.0f);
      radii[3] = SkVector::Make(5.0f, 4.0f);
      break;
    case SkRRect::Type::kComplex_Type:
      radii[0] = SkVector::Make(5.0f, 4.0f);
      radii[1] = SkVector::Make(4.0f, 5.0f);
      radii[2] = SkVector::Make(3.0f, 6.0f);
      radii[3] = SkVector::Make(8.0f, 7.0f);
      break;
    default:
      break;
  }

  const SkScalar offset = 0.5f;
  const SkScalar multiplier = length / 16.0f;
  SkRRect rrect, rrect_2;

  SkVector set_radii[4];
  for (size_t i = 0; i < 4; i++) {
    set_radii[i] = radii[i] * multiplier;
  }
  rrect.setRectRadii(SkRect::MakeLTRB(0, 0, length, length), set_radii);

  state.counters["DrawCallCount"] = kDRRectsToDraw;
  for (size_t i = 0; i < kDRRectsToDraw; i++) {
    rrect.inset(0.1f * length, 0.1f * length, &rrect_2);
    builder.DrawDRRect(rrect, rrect_2, paint);
    rrect.offset(offset, offset);
    if (rrect.rect().right() > canvas_size) {
      rrect.offset(-canvas_size, 0);
    }
    if (rrect.rect().bottom() > canvas_size) {
      rrect.offset(0, -canvas_size);
    }
  }
  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawDRRect-" +
                  std::to_string(state.range(0)) + ".png";
  surface_provider->Snapshot(filename);
}

void BM_DrawArc(benchmark::State& state,
                BackendType backend_type,
                unsigned attributes) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state,
                     DisplayListOpFlags::kDrawArcNoCenterFlags);

  size_t length = state.range(0);
  size_t canvas_size = length * 2;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  SkScalar starting_angle = 0.0f;
  SkScalar offset = 0.5f;

  // Just some random sweeps that will mostly circumnavigate the circle
  std::vector<SkScalar> segment_sweeps = {5.5f,  -10.0f, 42.0f, 71.7f, 90.0f,
                                          37.5f, 17.9f,  32.0f, 379.4f};

  SkRect bounds = SkRect::MakeLTRB(0, 0, length, length);

  state.counters["DrawCallCount"] = kArcSweepSetsToDraw * segment_sweeps.size();
  for (size_t i = 0; i < kArcSweepSetsToDraw; i++) {
    for (SkScalar sweep : segment_sweeps) {
      builder.DrawArc(bounds, starting_angle, sweep, false, paint);
      starting_angle += sweep + 5.0f;
    }
    bounds.offset(offset, offset);
    if (bounds.right() > canvas_size) {
      bounds.offset(-canvas_size, 0);
    }
    if (bounds.bottom() > canvas_size) {
      bounds.offset(0, -canvas_size);
    }
  }

  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawArc-" +
                  std::to_string(state.range(0)) + ".png";
  surface_provider->Snapshot(filename);
}

// Returns a list of SkPoints that represent `n` points equally spaced out
// along the circumference of a circle with radius `r` and centered on `center`.
std::vector<SkPoint> GetPolygonPoints(size_t n, SkPoint center, SkScalar r) {
  std::vector<SkPoint> points;
  SkScalar x, y;
  float angle;
  float full_circle = 2.0f * M_PI;
  for (size_t i = 0; i < n; i++) {
    angle = (full_circle / static_cast<float>(n)) * static_cast<float>(i);
    x = center.x() + r * std::cosf(angle);
    y = center.y() + r * std::sinf(angle);
    points.push_back(SkPoint::Make(x, y));
  }
  return points;
}

// Creates a path that represents a regular polygon with `sides` sides,
// centered on `center` with a radius of `radius`. The control points are
// equally spaced out along the circumference of the circle described by
// `radius` and `center`.
//
// The path segment connecting each control point is a line segment.
void GetLinesPath(SkPath& path, size_t sides, SkPoint center, float radius) {
  std::vector<SkPoint> points = GetPolygonPoints(sides, center, radius);
  path.moveTo(points[0]);
  for (size_t i = 1; i < sides; i++) {
    path.lineTo(points[i]);
  }
  path.lineTo(points[0]);
  path.close();
}

// Creates a path that represents a regular polygon with `sides` sides,
// centered on `center` with a radius of `radius`. The control points are
// equally spaced out along the circumference of the circle described by
// `radius` and `center`.
//
// The path segment connecting each control point is a quad bezier, with the
// bezier control point being on a circle with 80% of `radius` and with the
// control point angle half way between the start and end point angles for the
// polygon segment.
void GetQuadsPath(SkPath& path, size_t sides, SkPoint center, float radius) {
  std::vector<SkPoint> points = GetPolygonPoints(sides, center, radius);
  std::vector<SkPoint> control_points =
      GetPolygonPoints(sides * 2, center, radius * 0.8f);

  path.moveTo(points[0]);
  for (size_t i = 1; i < sides; i++) {
    path.quadTo(control_points[2 * i - 1], points[i]);
  }
  path.quadTo(control_points[2 * sides - 1], points[0]);
  path.close();
}

// Creates a path that represents a regular polygon with `sides` sides,
// centered on `center` with a radius of `radius`. The control points are
// equally spaced out along the circumference of the circle described by
// `radius` and `center`.
//
// The path segment connecting each control point is a conic, with the
// control point being on a circle with 80% of `radius` and with the
// control point angle half way between the start and end point angles for the
// polygon segment, and the conic weight set to 3.7f.
void GetConicsPath(SkPath& path, size_t sides, SkPoint center, float radius) {
  std::vector<SkPoint> points = GetPolygonPoints(sides, center, radius);
  std::vector<SkPoint> control_points =
      GetPolygonPoints(sides * 2, center, radius * 0.8f);

  path.moveTo(points[0]);
  for (size_t i = 1; i < sides; i++) {
    path.conicTo(control_points[2 * i - 1], points[i], 3.7f);
  }
  path.conicTo(control_points[2 * sides - 1], points[0], 3.7f);
  path.close();
}

// Creates a path that represents a regular polygon with `sides` sides,
// centered on `center` with a radius of `radius`. The control points are
// equally spaced out along the circumference of the circle described by
// `radius` and `center`.
//
// The path segment connecting each control point is a cubic, with the first
// control point being on a circle with 80% of `radius` and with the second
// control point being on a circle with 120% of `radius`. The first
// control point is 1/3, and the second control point is 2/3, of the angle
// between the start and end point angles for the polygon segment.
void GetCubicsPath(SkPath& path, size_t sides, SkPoint center, float radius) {
  std::vector<SkPoint> points = GetPolygonPoints(sides, center, radius);
  std::vector<SkPoint> inner_control_points =
      GetPolygonPoints(sides * 3, center, radius * 0.8f);
  std::vector<SkPoint> outer_control_points =
      GetPolygonPoints(sides * 3, center, radius * 1.2f);

  path.moveTo(points[0]);
  for (size_t i = 1; i < sides; i++) {
    path.cubicTo(inner_control_points[3 * i - 2],
                 outer_control_points[3 * i - 1], points[i]);
  }
  path.cubicTo(inner_control_points[3 * sides - 2],
               outer_control_points[3 * sides - 1], points[0]);
  path.close();
}

// Returns a path generated by one of the above path generators
// which is multiplied `number` times centered on each of the `number` control
// points along the circumference of a circle centered on `center` with radius
// `radius`.
//
// Each of the polygons will have `sides` sides, and the resulting path will be
// bounded by a circle with radius of 150% of `radius` (or another 20% on top of
// that for cubics)
void MultiplyPath(SkPath& path,
                  SkPath::Verb type,
                  SkPoint center,
                  size_t sides,
                  size_t number,
                  float radius) {
  std::vector<SkPoint> center_points =
      GetPolygonPoints(number, center, radius / 2.0f);

  for (SkPoint p : center_points) {
    switch (type) {
      case SkPath::Verb::kLine_Verb:
        GetLinesPath(path, sides, p, radius);
        break;
      case SkPath::Verb::kQuad_Verb:
        GetQuadsPath(path, sides, p, radius);
        break;
      case SkPath::Verb::kConic_Verb:
        GetConicsPath(path, sides, p, radius);
        break;
      case SkPath::Verb::kCubic_Verb:
        GetCubicsPath(path, sides, p, radius);
        break;
      default:
        break;
    }
  }
}

std::string VerbToString(SkPath::Verb type) {
  switch (type) {
    case SkPath::Verb::kLine_Verb:
      return "Lines";
    case SkPath::Verb::kQuad_Verb:
      return "Quads";
    case SkPath::Verb::kConic_Verb:
      return "Conics";
    case SkPath::Verb::kCubic_Verb:
      return "Cubics";
    default:
      return "Unknown";
  }
}

// Draws a series of overlapping 20-sided polygons where the path segment
// between each point is one of the verb types defined in SkPath.
//
// The number of polygons drawn will be varied to get an overall path
// with approximately 20*N verbs, so we can get an idea of the fixed
// cost of using drawPath as well as an idea of how the cost varies according
// to the verb count.
void BM_DrawPath(benchmark::State& state,
                 BackendType backend_type,
                 unsigned attributes,
                 SkPath::Verb type) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawPathFlags);

  size_t length = kFixedCanvasSize;
  surface_provider->InitializeSurface(length, length);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  SkPath path;

  std::string label = VerbToString(type);
  SkPoint center = SkPoint::Make(length / 2.0f, length / 2.0f);
  float radius = length * 0.25f;
  state.SetComplexityN(state.range(0));

  MultiplyPath(path, type, center, 20, state.range(0), radius);

  state.counters["VerbCount"] = path.countVerbs();
  state.counters["DrawCallCount"] = 1;

  builder.DrawPath(path, paint);
  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawPath-" + label +
                  "-" + std::to_string(state.range(0)) + ".png";
  surface_provider->Snapshot(filename);
}

// Returns a set of vertices that describe a circle that has a
// radius of `radius` and outer vertex count of approximately
// `vertex_count`. The final number of vertices will differ as we
// need to ensure the correct usage of vertices to ensure we do not
// request degenerate triangles be drawn. This final count is output
// through `final_vertex_count`.
//
// The resulting vertices will describe a disc consisting of a series
// of triangles with two vertices on the circumference of the disc,
// and the final vertex being the center point of the disc.
//
// Each vertex colour will alternate through Red, Green, Blue and Cyan.
std::shared_ptr<DlVertices> GetTestVertices(SkPoint center,
                                            float radius,
                                            size_t vertex_count,
                                            DlVertexMode mode,
                                            size_t& final_vertex_count) {
  size_t outer_vertex_count = vertex_count / 2;
  std::vector<SkPoint> outer_points =
      GetPolygonPoints(outer_vertex_count, center, radius);

  std::vector<SkPoint> vertices;
  std::vector<DlColor> colors;

  switch (mode) {
    case DlVertexMode::kTriangleFan:
      // Calling the points on the outer circle O_0, O_1, O_2, ..., and
      // the center point C, this should create a triangle fan with vertices
      // C, O_0, O_1, O_2, O_3, ...
      vertices.push_back(center);
      colors.push_back(DlColor(SK_ColorCYAN));
      for (size_t i = 0; i <= outer_points.size(); i++) {
        vertices.push_back(outer_points[i % outer_points.size()]);
        if (i % 3 == 0) {
          colors.push_back(DlColor(SK_ColorRED));
        } else if (i % 3 == 1) {
          colors.push_back(DlColor(SK_ColorGREEN));
        } else {
          colors.push_back(DlColor(SK_ColorBLUE));
        }
      }
      break;
    case DlVertexMode::kTriangles:
      // Calling the points on the outer circle O_0, O_1, O_2, ..., and
      // the center point C, this should create a series of triangles with
      // vertices O_0, O_1, C, O_1, O_2, C, O_2, O_3, C, ...
      for (size_t i = 0; i < outer_vertex_count; i++) {
        vertices.push_back(outer_points[i % outer_points.size()]);
        colors.push_back(DlColor(SK_ColorRED));
        vertices.push_back(outer_points[(i + 1) % outer_points.size()]);
        colors.push_back(DlColor(SK_ColorGREEN));
        vertices.push_back(center);
        colors.push_back(DlColor(SK_ColorBLUE));
      }
      break;
    case DlVertexMode::kTriangleStrip:
      // Calling the points on the outer circle O_0, O_1, O_2, ..., and
      // the center point C, this should create a strip with vertices
      // O_0, O_1, C, O_2, O_3, C, O_4, O_5, C, ...
      for (size_t i = 0; i <= outer_vertex_count; i++) {
        vertices.push_back(outer_points[i % outer_points.size()]);
        colors.push_back(i % 2 ? DlColor(SK_ColorRED) : DlColor(SK_ColorGREEN));
        if (i % 2 == 1) {
          vertices.push_back(center);
          colors.push_back(DlColor(SK_ColorBLUE));
        }
      }
      break;
    default:
      break;
  }

  final_vertex_count = vertices.size();
  return DlVertices::Make(mode, vertices.size(), vertices.data(), nullptr,
                          colors.data());
}

std::string VertexModeToString(DlVertexMode mode) {
  switch (mode) {
    case DlVertexMode::kTriangleStrip:
      return "TriangleStrip";
    case DlVertexMode::kTriangleFan:
      return "TriangleFan";
    case DlVertexMode::kTriangles:
      return "Triangles";
  }
  return "Unknown";
}

// Draws a series of discs generated by `GetTestVertices()` with
// 50 vertices in each disc. The number of discs drawn will vary according
// to the benchmark input, and the benchmark will automatically calculate
// the Big-O complexity of `DrawVertices` with N being the number of vertices
// being drawn.
//
// The discs drawn will be centered on points along a circle with radius of 25%
// of the canvas width/height, with each point being equally spaced out.
void BM_DrawVertices(benchmark::State& state,
                     BackendType backend_type,
                     unsigned attributes,
                     DlVertexMode mode) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawVerticesFlags);

  size_t length = kFixedCanvasSize;
  surface_provider->InitializeSurface(length, length);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  SkPoint center = SkPoint::Make(length / 2.0f, length / 2.0f);

  float radius = length / 4.0f;

  size_t vertex_count, total_vertex_count = 0;
  size_t disc_count = state.range(0);

  std::vector<SkPoint> center_points =
      GetPolygonPoints(disc_count, center, radius / 4.0f);

  state.counters["DrawCallCount"] = center_points.size();
  for (SkPoint p : center_points) {
    std::shared_ptr<DlVertices> vertices =
        GetTestVertices(p, radius, 50, mode, vertex_count);
    total_vertex_count += vertex_count;
    builder.DrawVertices(vertices.get(), DlBlendMode::kSrc, paint);
  }

  state.counters["VertexCount"] = total_vertex_count;
  state.SetComplexityN(total_vertex_count);

  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawVertices-" +
                  std::to_string(disc_count) + "-" + VertexModeToString(mode) +
                  ".png";
  surface_provider->Snapshot(filename);
}

// Generate `count` test points.
//
// The points are distributed using some fixed constant offsets that were
// chosen to appear somewhat random.
//
// The points generated will wrap in x and y for the bounds of `canvas_size`.
std::vector<SkPoint> GetTestPoints(size_t count, SkISize canvas_size) {
  std::vector<SkPoint> points;

  // Some arbitrary offsets to use when building the list of points
  std::vector<SkScalar> delta_x = {10.0f, 6.3f, 15.0f, 3.5f, 22.6f, 4.7f};
  std::vector<SkScalar> delta_y = {9.3f, -5.4f, 8.5f, -12.0f, 19.2f, -19.6f};

  SkPoint current = SkPoint::Make(0.0f, 0.0f);
  for (size_t i = 0; i < count; i++) {
    points.push_back(current);
    current.offset(delta_x[i % delta_x.size()], delta_y[i % delta_y.size()]);
    if (current.x() > canvas_size.width()) {
      current.offset(-canvas_size.width(), 25.0f);
    }
    if (current.y() > canvas_size.height()) {
      current.offset(0.0f, -canvas_size.height());
    }
  }

  return points;
}

std::string PointModeToString(DlCanvas::PointMode mode) {
  switch (mode) {
    case DlCanvas::PointMode::kLines:
      return "Lines";
    case DlCanvas::PointMode::kPolygon:
      return "Polygon";
    case DlCanvas::PointMode::kPoints:
    default:
      return "Points";
  }
}

// Draws a series of points generated by `GetTestPoints()` above to
// a fixed-size canvas. The benchmark will vary the number of points drawn,
// and they can be drawn in one of three modes - Lines, Polygon or Points mode.
//
// This benchmark will automatically calculate the Big-O complexity of
// `DrawPoints` with N being the number of points being drawn.
void BM_DrawPoints(benchmark::State& state,
                   BackendType backend_type,
                   unsigned attributes,
                   DlCanvas::PointMode mode) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  switch (mode) {
    case DlCanvas::PointMode::kPoints:
      AnnotateAttributes(attributes, state,
                         DisplayListOpFlags::kDrawPointsAsPointsFlags);
      break;
    case DlCanvas::PointMode::kLines:
      AnnotateAttributes(attributes, state,
                         DisplayListOpFlags::kDrawPointsAsLinesFlags);
      break;
    case DlCanvas::PointMode::kPolygon:
      AnnotateAttributes(attributes, state,
                         DisplayListOpFlags::kDrawPointsAsPolygonFlags);
      break;
  }

  size_t length = kFixedCanvasSize;
  surface_provider->InitializeSurface(length, length);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  size_t point_count = state.range(0);
  state.SetComplexityN(point_count);
  state.counters["PointCount"] = point_count;
  state.counters["DrawCallCount"] = 1;

  std::vector<SkPoint> points =
      GetTestPoints(point_count, SkISize::Make(length, length));
  builder.DrawPoints(mode, points.size(), points.data(), paint);

  auto display_list = builder.Build();

  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawPoints-" +
                  PointModeToString(mode) + "-" + std::to_string(point_count) +
                  ".png";
  surface_provider->Snapshot(filename);
}

sk_sp<SkImage> ImageFromBitmapWithNewID(const SkBitmap& bitmap) {
  // If we create an SkPixmap with a ref to the SkBitmap's pixel data,
  // then create an SkImage from that, we always get a new generation ID,
  // so we will avoid hitting the cache.
  SkPixmap pixmap;
  bitmap.peekPixels(&pixmap);
  return SkImages::RasterFromPixmap(pixmap, nullptr, nullptr);
}

// Draws `kImagesToDraw` bitmaps to a canvas, either with texture-backed
// bitmaps or bitmaps that need to be uploaded to the GPU first.
void BM_DrawImage(benchmark::State& state,
                  BackendType backend_type,
                  unsigned attributes,
                  DlImageSampling options,
                  bool upload_bitmap) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state,
                     DisplayListOpFlags::kDrawImageWithPaintFlags);

  size_t bitmap_size = state.range(0);
  size_t canvas_size = 2 * bitmap_size;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  sk_sp<SkImage> image;
  std::shared_ptr<DlSurfaceInstance> offscreen_instance;
  sk_sp<SkSurface> offscreen;
  SkBitmap bitmap;

  if (upload_bitmap) {
    SkImageInfo info = SkImageInfo::Make(bitmap_size, bitmap_size,
                                         SkColorType::kRGBA_8888_SkColorType,
                                         SkAlphaType::kPremul_SkAlphaType);
    bitmap.allocPixels(info, 0);
    bitmap.eraseColor(SK_ColorBLUE);
  } else {
    offscreen_instance =
        surface_provider->MakeOffscreenSurface(bitmap_size, bitmap_size);
    offscreen = offscreen_instance->sk_surface();
    offscreen->getCanvas()->clear(SK_ColorRED);
  }

  SkScalar offset = 0.5f;
  SkPoint dst = SkPoint::Make(0, 0);

  state.counters["DrawCallCount"] = kImagesToDraw;
  for (size_t i = 0; i < kImagesToDraw; i++) {
    image = upload_bitmap ? ImageFromBitmapWithNewID(bitmap)
                          : offscreen->makeImageSnapshot();
    builder.DrawImage(DlImage::Make(image), dst, options, &paint);

    dst.offset(offset, offset);
    if (dst.x() + bitmap_size > canvas_size) {
      dst.set(0, dst.y());
    }
    if (dst.y() + bitmap_size > canvas_size) {
      dst.set(dst.x(), 0);
    }
  }

  auto display_list = builder.Build();

  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawImage-" +
                  (upload_bitmap ? "Upload-" : "Texture-") +
                  std::to_string(bitmap_size) + ".png";
  surface_provider->Snapshot(filename);
}

std::string ConstraintToString(DlCanvas::SrcRectConstraint constraint) {
  switch (constraint) {
    case DlCanvas::SrcRectConstraint::kStrict:
      return "Strict";
    case DlCanvas::SrcRectConstraint::kFast:
      return "Fast";
    default:
      return "Unknown";
  }
}

// Draws `kImagesToDraw` bitmaps to a canvas, either with texture-backed
// bitmaps or bitmaps that need to be uploaded to the GPU first.
//
// 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,
                      DlImageSampling options,
                      DlCanvas::SrcRectConstraint constraint,
                      bool upload_bitmap) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state,
                     DisplayListOpFlags::kDrawImageRectWithPaintFlags);

  size_t bitmap_size = state.range(0);
  size_t canvas_size = 2 * bitmap_size;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  sk_sp<SkImage> image;
  std::shared_ptr<DlSurfaceInstance> offscreen_instance;
  sk_sp<SkSurface> offscreen;
  SkBitmap bitmap;

  if (upload_bitmap) {
    SkImageInfo info = SkImageInfo::Make(bitmap_size, bitmap_size,
                                         SkColorType::kRGBA_8888_SkColorType,
                                         SkAlphaType::kPremul_SkAlphaType);
    bitmap.allocPixels(info, 0);
    bitmap.eraseColor(SK_ColorBLUE);
  } else {
    offscreen_instance =
        surface_provider->MakeOffscreenSurface(bitmap_size, bitmap_size);
    offscreen = offscreen_instance->sk_surface();
    offscreen->getCanvas()->clear(SK_ColorRED);
  }

  SkScalar offset = 0.5f;
  SkRect src = SkRect::MakeXYWH(bitmap_size / 4.0f, bitmap_size / 4.0f,
                                bitmap_size / 2.0f, bitmap_size / 2.0f);
  SkRect dst =
      SkRect::MakeXYWH(0.0f, 0.0f, bitmap_size * 0.75f, bitmap_size * 0.75f);

  state.counters["DrawCallCount"] = kImagesToDraw;
  for (size_t i = 0; i < kImagesToDraw; i++) {
    image = upload_bitmap ? ImageFromBitmapWithNewID(bitmap)
                          : offscreen->makeImageSnapshot();
    builder.DrawImageRect(DlImage::Make(image), src, dst, options, &paint,
                          constraint);
    dst.offset(offset, offset);
    if (dst.right() > canvas_size) {
      dst.offsetTo(0, dst.y());
    }
    if (dst.bottom() > canvas_size) {
      dst.offsetTo(dst.x(), 0);
    }
  }

  auto display_list = builder.Build();

  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawImageRect-" +
                  (upload_bitmap ? "Upload-" : "Texture-") +
                  ConstraintToString(constraint) + "-" +
                  std::to_string(bitmap_size) + ".png";
  surface_provider->Snapshot(filename);
}

std::string FilterModeToString(const DlFilterMode mode) {
  switch (mode) {
    case DlFilterMode::kNearest:
      return "Nearest";
    case DlFilterMode::kLinear:
      return "Linear";
    default:
      return "Unknown";
  }
}

// Draws `kImagesToDraw` bitmaps to a canvas, either with texture-backed
// bitmaps or bitmaps that need to be uploaded to the GPU first.
//
// The image is split into 9 sub-rects and stretched proportionally for final
// rendering.
void BM_DrawImageNine(benchmark::State& state,
                      BackendType backend_type,
                      unsigned attributes,
                      const DlFilterMode filter,
                      bool upload_bitmap) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state,
                     DisplayListOpFlags::kDrawImageNineWithPaintFlags);

  size_t bitmap_size = state.range(0);
  size_t canvas_size = 2 * bitmap_size;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  SkIRect center = SkIRect::MakeXYWH(bitmap_size / 4, bitmap_size / 4,
                                     bitmap_size / 2, bitmap_size / 2);

  sk_sp<SkImage> image;
  std::shared_ptr<DlSurfaceInstance> offscreen_instance;
  sk_sp<SkSurface> offscreen;
  SkBitmap bitmap;

  if (upload_bitmap) {
    SkImageInfo info = SkImageInfo::Make(bitmap_size, bitmap_size,
                                         SkColorType::kRGBA_8888_SkColorType,
                                         SkAlphaType::kPremul_SkAlphaType);
    bitmap.allocPixels(info, 0);
    bitmap.eraseColor(SK_ColorBLUE);
  } else {
    offscreen_instance =
        surface_provider->MakeOffscreenSurface(bitmap_size, bitmap_size);
    offscreen = offscreen_instance->sk_surface();
    offscreen->getCanvas()->clear(SK_ColorRED);
  }

  SkScalar offset = 0.5f;
  SkRect dst =
      SkRect::MakeXYWH(0.0f, 0.0f, bitmap_size * 0.75f, bitmap_size * 0.75f);

  state.counters["DrawCallCount"] = kImagesToDraw;
  for (size_t i = 0; i < kImagesToDraw; i++) {
    image = upload_bitmap ? ImageFromBitmapWithNewID(bitmap)
                          : offscreen->makeImageSnapshot();
    builder.DrawImageNine(DlImage::Make(image), center, dst, filter, &paint);
    dst.offset(offset, offset);
    if (dst.right() > canvas_size) {
      dst.offsetTo(0, dst.y());
    }
    if (dst.bottom() > canvas_size) {
      dst.offsetTo(dst.x(), 0);
    }
  }

  auto display_list = builder.Build();

  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawImageNine-" +
                  (upload_bitmap ? "Upload-" : "Texture-") +
                  FilterModeToString(filter) + "-" +
                  std::to_string(bitmap_size) + ".png";
  surface_provider->Snapshot(filename);
}

// Draws a series of glyph runs with 32 glyphs in each run. The number of runs
// may vary according to the benchmark parameters. The text will start in the
// upper left corner of the canvas and advance from left to right and wrap at
// the canvas boundaries in both x and y.
//
// 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,
                     unsigned attributes) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawTextBlobFlags);

  size_t draw_calls = state.range(0);
  size_t canvas_size = kFixedCanvasSize;
  surface_provider->InitializeSurface(canvas_size, canvas_size);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  state.counters["DrawCallCount_Varies"] = draw_calls;
  state.counters["GlyphCount"] = draw_calls;
  char character[2] = {'A', '\0'};

  for (size_t i = 0; i < draw_calls; i++) {
    character[0] = 'A' + (i % 26);
    auto blob = SkTextBlob::MakeFromString(character, CreateTestFontOfSize(20));
    builder.DrawTextBlob(blob, 50.0f, 50.0f, paint);
  }

  auto display_list = builder.Build();

  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawTextBlob-" +
                  std::to_string(draw_calls) + ".png";
  surface_provider->Snapshot(filename);
}

// Draw the shadow for a 10-sided regular polygon where the polygon's
// sides are denoted by one of a Line, Quad, Conic or Cubic path segment.
//
// The elevation of the light source will vary according to the benchmark
// paremeters.
//
// The benchmark can be run with either a transparent occluder or an opaque
// occluder.
void BM_DrawShadow(benchmark::State& state,
                   BackendType backend_type,
                   unsigned attributes,
                   bool transparent_occluder,
                   SkPath::Verb type) {
  auto surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawShadowFlags);

  size_t length = kFixedCanvasSize;
  surface_provider->InitializeSurface(length, length);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->getCanvas());

  SkPath path;

  SkPoint center = SkPoint::Make(length / 2.0f, length / 2.0f);
  float radius = length * 0.25f;

  switch (type) {
    case SkPath::Verb::kLine_Verb:
      GetLinesPath(path, 10, center, radius);
      break;
    case SkPath::Verb::kQuad_Verb:
      GetQuadsPath(path, 10, center, radius);
      break;
    case SkPath::Verb::kConic_Verb:
      GetConicsPath(path, 10, center, radius);
      break;
    case SkPath::Verb::kCubic_Verb:
      GetCubicsPath(path, 10, center, radius);
      break;
    default:
      break;
  }

  float elevation = state.range(0);
  state.counters["DrawCallCount"] = 1;

  // We can hardcode dpr to 1.0f as we're varying elevation, and dpr is only
  // ever used in conjunction with elevation.
  builder.DrawShadow(path, DlColor(SK_ColorBLUE), elevation,
                     transparent_occluder, 1.0f);
  auto display_list = builder.Build();

  // We only want to time the actual rasterization.
  for ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-DrawShadow-" +
                  VerbToString(type) + "-" +
                  (transparent_occluder ? "Transparent-" : "Opaque-") +
                  std::to_string(elevation) + "-" + ".png";
  surface_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 surface_provider = DlSurfaceProvider::Create(backend_type);
  DisplayListBuilder builder;
  DlPaint paint = GetPaintForRun(attributes);

  AnnotateAttributes(attributes, state, DisplayListOpFlags::kSaveLayerFlags);

  size_t length = kFixedCanvasSize;
  surface_provider->InitializeSurface(length, length);
  auto surface = surface_provider->GetPrimarySurface()->sk_surface();
  auto canvas = DlSkCanvasAdapter(surface->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);

  state.counters["DrawCallCount_Varies"] = save_layer_calls * save_depth;
  for (size_t i = 0; i < save_layer_calls; i++) {
    for (size_t j = 0; j < save_depth; j++) {
      builder.SaveLayer(nullptr, nullptr);
      builder.DrawRect(rect1, paint);
      builder.DrawRect(rect2, paint);
    }
    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 ([[maybe_unused]] auto _ : state) {
    canvas.DrawDisplayList(display_list);
    FlushSubmitCpuSync(surface);
  }

  auto filename = surface_provider->backend_name() + "-SaveLayer-" +
                  std::to_string(save_depth) + "-" +
                  std::to_string(save_layer_calls) + ".png";
  surface_provider->Snapshot(filename);
}

#ifdef ENABLE_SOFTWARE_BENCHMARKS
RUN_DISPLAYLIST_BENCHMARKS(Software)
#endif

#ifdef ENABLE_OPENGL_BENCHMARKS
RUN_DISPLAYLIST_BENCHMARKS(OpenGL)
#endif

#ifdef ENABLE_METAL_BENCHMARKS
RUN_DISPLAYLIST_BENCHMARKS(Metal)
#endif

}  // namespace testing
}  // namespace flutter
