Refactor DisplayList Benchmarks (flutter/engine#30913)

Refactor DisplayList Benchmarks so that we allocate the CanvasProvider inside the test body. This allows for easier to understand memory management and object lifetimes, and fixes a leak on iOS/macOS.
This commit is contained in:
George Wright
2022-01-19 13:39:37 -08:00
committed by GitHub
parent 9776336eae
commit 0ad83b7100
11 changed files with 351 additions and 207 deletions

View File

@@ -38,9 +38,13 @@ FILE: ../../../flutter/display_list/display_list.cc
FILE: ../../../flutter/display_list/display_list.h
FILE: ../../../flutter/display_list/display_list_benchmarks.cc
FILE: ../../../flutter/display_list/display_list_benchmarks.h
FILE: ../../../flutter/display_list/display_list_benchmarks_canvas_provider.h
FILE: ../../../flutter/display_list/display_list_benchmarks_gl.cc
FILE: ../../../flutter/display_list/display_list_benchmarks_gl.h
FILE: ../../../flutter/display_list/display_list_benchmarks_metal.cc
FILE: ../../../flutter/display_list/display_list_benchmarks_metal.h
FILE: ../../../flutter/display_list/display_list_benchmarks_software.cc
FILE: ../../../flutter/display_list/display_list_benchmarks_software.h
FILE: ../../../flutter/display_list/display_list_builder.cc
FILE: ../../../flutter/display_list/display_list_builder.h
FILE: ../../../flutter/display_list/display_list_canvas_dispatcher.cc

View File

@@ -61,6 +61,7 @@ if (enable_unittests) {
"display_list_benchmarks.cc",
"display_list_benchmarks.h",
"display_list_benchmarks_software.cc",
"display_list_benchmarks_software.h",
]
deps = [
@@ -75,13 +76,23 @@ if (enable_unittests) {
"//third_party/skia",
]
defines = [ "ENABLE_SOFTWARE_BENCHMARKS" ]
if (!is_fuchsia) {
sources += [ "display_list_benchmarks_gl.cc" ]
defines += [ "ENABLE_OPENGL_BENCHMARKS" ]
sources += [
"display_list_benchmarks_gl.cc",
"display_list_benchmarks_gl.h",
]
deps += [ "//flutter/testing:opengl" ]
}
if (is_mac) {
sources += [ "display_list_benchmarks_metal.cc" ]
defines += [ "ENABLE_METAL_BENCHMARKS" ]
sources += [
"display_list_benchmarks_metal.cc",
"display_list_benchmarks_metal.h",
]
deps += [ "//flutter/testing:metal" ]
}
}
@@ -103,11 +114,15 @@ if (is_ios) {
]
ldflags =
[ "-Wl,-install_name,@rpath/libios_display_list_benchmarks.dylib" ]
defines = [
"BENCHMARKS_NO_SNAPSHOT",
"ENABLE_METAL_BENCHMARKS",
]
sources = [
"display_list_benchmarks.cc",
"display_list_benchmarks.h",
"display_list_benchmarks_metal.cc",
"display_list_benchmarks_metal.h",
]
deps = [

View File

@@ -11,6 +11,27 @@
namespace flutter {
namespace testing {
std::unique_ptr<CanvasProvider> CreateCanvasProvider(BackendType backend_type) {
switch (backend_type) {
#ifdef ENABLE_SOFTWARE_BENCHMARKS
case kSoftware_Backend:
return std::make_unique<SoftwareCanvasProvider>();
#endif
#ifdef ENABLE_OPENGL_BENCHMARKS
case kOpenGL_Backend:
return std::make_unique<OpenGLCanvasProvider>();
#endif
#ifdef ENABLE_METAL_BENCHMARKS
case kMetal_Backend:
return std::make_unique<MetalCanvasProvider>();
#endif
default:
return nullptr;
}
return nullptr;
}
// Constants chosen to produce benchmark results in the region of 1-50ms
constexpr size_t kLinesToDraw = 10000;
constexpr size_t kRectsToDraw = 5000;
@@ -27,8 +48,8 @@ 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,
std::unique_ptr<CanvasProvider> canvas_provider) {
void BM_DrawLine(benchmark::State& state, BackendType backend_type) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = state.range(0);
@@ -57,8 +78,8 @@ void BM_DrawLine(benchmark::State& state,
// 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,
std::unique_ptr<CanvasProvider> canvas_provider) {
void BM_DrawRect(benchmark::State& state, BackendType backend_type) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = state.range(0);
size_t canvas_size = length * 2;
@@ -98,8 +119,8 @@ void BM_DrawRect(benchmark::State& state,
// 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,
std::unique_ptr<CanvasProvider> canvas_provider) {
void BM_DrawOval(benchmark::State& state, BackendType backend_type) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = state.range(0);
size_t canvas_size = length * 2;
@@ -136,8 +157,8 @@ void BM_DrawOval(benchmark::State& state,
// 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,
std::unique_ptr<CanvasProvider> canvas_provider) {
void BM_DrawCircle(benchmark::State& state, BackendType backend_type) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = state.range(0);
size_t canvas_size = length * 2;
@@ -177,8 +198,9 @@ void BM_DrawCircle(benchmark::State& state,
//
// Half the drawn rounded rects will not have an integral offset.
void BM_DrawRRect(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
SkRRect::Type type) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = state.range(0);
size_t canvas_size = length * 2;
@@ -242,8 +264,8 @@ void BM_DrawRRect(benchmark::State& state,
canvas_provider->Snapshot(filename);
}
void BM_DrawArc(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider) {
void BM_DrawArc(benchmark::State& state, BackendType backend_type) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = state.range(0);
size_t canvas_size = length * 2;
@@ -449,8 +471,9 @@ std::string VerbToString(SkPath::Verb type) {
// 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,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
SkPath::Verb type) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = kFixedCanvasSize;
canvas_provider->InitializeSurface(length, length);
@@ -578,8 +601,9 @@ std::string VertexModeToString(SkVertices::VertexMode mode) {
// 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,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
SkVertices::VertexMode mode) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = kFixedCanvasSize;
canvas_provider->InitializeSurface(length, length);
@@ -666,8 +690,9 @@ std::string PointModeToString(SkCanvas::PointMode 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,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
SkCanvas::PointMode mode) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = kFixedCanvasSize;
canvas_provider->InitializeSurface(length, length);
@@ -706,9 +731,10 @@ sk_sp<SkImage> ImageFromBitmapWithNewID(const SkBitmap& bitmap) {
// 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,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
const SkSamplingOptions& options,
bool upload_bitmap) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t bitmap_size = state.range(0);
size_t canvas_size = 2 * bitmap_size;
@@ -776,10 +802,11 @@ 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,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
const SkSamplingOptions& options,
SkCanvas::SrcRectConstraint constraint,
bool upload_bitmap) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t bitmap_size = state.range(0);
size_t canvas_size = 2 * bitmap_size;
@@ -851,9 +878,10 @@ std::string FilterModeToString(const SkFilterMode mode) {
// The image is split into 9 sub-rects and stretched proportionally for final
// rendering.
void BM_DrawImageNine(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
const SkFilterMode filter,
bool upload_bitmap) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t bitmap_size = state.range(0);
size_t canvas_size = 2 * bitmap_size;
@@ -916,8 +944,8 @@ 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,
std::unique_ptr<CanvasProvider> canvas_provider) {
void BM_DrawTextBlob(benchmark::State& state, BackendType backend_type) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t glyph_runs = state.range(0);
size_t canvas_size = kFixedCanvasSize;
@@ -981,9 +1009,10 @@ void BM_DrawTextBlob(benchmark::State& state,
// The benchmark can be run with either a transparent occluder or an opaque
// occluder.
void BM_DrawShadow(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
bool transparent_occluder,
SkPath::Verb type) {
auto canvas_provider = CreateCanvasProvider(backend_type);
DisplayListBuilder builder;
size_t length = kFixedCanvasSize;
canvas_provider->InitializeSurface(length, length);

View File

@@ -5,8 +5,7 @@
#ifndef FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_H_
#define FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_H_
#include "flutter/fml/mapping.h"
#include "flutter/testing/testing.h"
#include "flutter/display_list/display_list_benchmarks_canvas_provider.h"
#include "third_party/benchmark/include/benchmark/benchmark.h"
#include "third_party/skia/include/core/SkCanvas.h"
@@ -14,79 +13,58 @@
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkVertices.h"
namespace flutter {
#ifdef ENABLE_SOFTWARE_BENCHMARKS
#include "flutter/display_list/display_list_benchmarks_software.h"
#endif
#ifdef ENABLE_OPENGL_BENCHMARKS
#include "flutter/display_list/display_list_benchmarks_gl.h"
#endif
#ifdef ENABLE_METAL_BENCHMARKS
#include "flutter/display_list/display_list_benchmarks_metal.h"
#endif
namespace flutter {
namespace testing {
class CanvasProvider {
public:
virtual ~CanvasProvider() = default;
virtual const std::string BackendName() = 0;
virtual void InitializeSurface(const size_t width, const size_t height) = 0;
virtual sk_sp<SkSurface> GetSurface() = 0;
virtual sk_sp<SkSurface> MakeOffscreenSurface(const size_t width,
const size_t height) = 0;
typedef enum { kSoftware_Backend, kOpenGL_Backend, kMetal_Backend } BackendType;
virtual bool Snapshot(std::string filename) {
auto image = GetSurface()->makeImageSnapshot();
if (!image) {
return false;
}
auto raster = image->makeRasterImage();
if (!raster) {
return false;
}
auto data = raster->encodeToData();
if (!data) {
return false;
}
fml::NonOwnedMapping mapping(static_cast<const uint8_t*>(data->data()),
data->size());
return WriteAtomically(OpenFixturesDirectory(), filename.c_str(), mapping);
}
};
std::unique_ptr<CanvasProvider> CreateCanvasProvider(BackendType backend_type);
// Benchmarks
void BM_DrawLine(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider);
void BM_DrawRect(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider);
void BM_DrawCircle(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider);
void BM_DrawOval(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider);
void BM_DrawArc(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider);
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_DrawRRect(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
SkRRect::Type type);
void BM_DrawPath(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
SkPath::Verb type);
void BM_DrawPoints(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
SkCanvas::PointMode mode);
void BM_DrawVertices(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
SkVertices::VertexMode mode);
void BM_DrawImage(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
const SkSamplingOptions& options,
bool upload_bitmap);
void BM_DrawImageRect(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
const SkSamplingOptions& options,
SkCanvas::SrcRectConstraint constraint,
bool upload_bitmap);
void BM_DrawImageNine(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
const SkFilterMode filter,
bool upload_bitmap);
void BM_DrawTextBlob(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider);
void BM_DrawTextBlob(benchmark::State& state, BackendType backend_type);
void BM_DrawShadow(benchmark::State& state,
std::unique_ptr<CanvasProvider> canvas_provider,
BackendType backend_type,
bool transparent_occluder,
SkPath::Verb type);
@@ -98,7 +76,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawLine \
*/ \
BENCHMARK_CAPTURE(BM_DrawLine, BACKEND, \
std::make_unique<BACKEND##CanvasProvider>()) \
BackendType::k##BACKEND##_Backend) \
->RangeMultiplier(2) \
->Range(16, 2048) \
->UseRealTime() \
@@ -108,7 +86,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawRect \
*/ \
BENCHMARK_CAPTURE(BM_DrawRect, BACKEND, \
std::make_unique<BACKEND##CanvasProvider>()) \
BackendType::k##BACKEND##_Backend) \
->RangeMultiplier(2) \
->Range(16, 2048) \
->UseRealTime() \
@@ -118,7 +96,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawOval \
*/ \
BENCHMARK_CAPTURE(BM_DrawOval, BACKEND, \
std::make_unique<BACKEND##CanvasProvider>()) \
BackendType::k##BACKEND##_Backend) \
->RangeMultiplier(2) \
->Range(16, 2048) \
->UseRealTime() \
@@ -128,7 +106,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawCircle \
*/ \
BENCHMARK_CAPTURE(BM_DrawCircle, BACKEND, \
std::make_unique<BACKEND##CanvasProvider>()) \
BackendType::k##BACKEND##_Backend) \
->RangeMultiplier(2) \
->Range(16, 2048) \
->UseRealTime() \
@@ -138,7 +116,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawArc \
*/ \
BENCHMARK_CAPTURE(BM_DrawArc, BACKEND, \
std::make_unique<BACKEND##CanvasProvider>()) \
BackendType::k##BACKEND##_Backend) \
->RangeMultiplier(2) \
->Range(128, 2048) \
->UseRealTime() \
@@ -149,40 +127,40 @@ void BM_DrawShadow(benchmark::State& state,
*/ \
BENCHMARK_CAPTURE(BM_DrawPath, \
Lines/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkPath::Verb::kLine_Verb) \
->RangeMultiplier(2) \
->Range(8, 1024) \
->Range(8, 512) \
->UseRealTime() \
->Unit(benchmark::kMillisecond) \
->Complexity(); \
\
BENCHMARK_CAPTURE(BM_DrawPath, \
Quads/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkPath::Verb::kQuad_Verb) \
->RangeMultiplier(2) \
->Range(8, 1024) \
->Range(8, 512) \
->UseRealTime() \
->Unit(benchmark::kMillisecond) \
->Complexity(); \
\
BENCHMARK_CAPTURE(BM_DrawPath, \
Conics/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkPath::Verb::kConic_Verb) \
->RangeMultiplier(2) \
->Range(8, 1024) \
->Range(8, 512) \
->UseRealTime() \
->Unit(benchmark::kMillisecond) \
->Complexity(); \
\
BENCHMARK_CAPTURE(BM_DrawPath, \
Cubics/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkPath::Verb::kCubic_Verb) \
->RangeMultiplier(2) \
->Range(8, 1024) \
->Range(8, 512) \
->UseRealTime() \
->Unit(benchmark::kMillisecond) \
->Complexity(); \
@@ -191,7 +169,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawPoints \
*/ \
BENCHMARK_CAPTURE(BM_DrawPoints, Points/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkCanvas::kPoints_PointMode) \
->RangeMultiplier(2) \
->Range(1024, 32768) \
@@ -199,7 +177,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawPoints, Lines/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkCanvas::kLines_PointMode) \
->RangeMultiplier(2) \
->Range(1024, 32768) \
@@ -207,7 +185,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawPoints, Polygon/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkCanvas::kPolygon_PointMode) \
->RangeMultiplier(2) \
->Range(1024, 32768) \
@@ -219,7 +197,7 @@ void BM_DrawShadow(benchmark::State& state,
*/ \
BENCHMARK_CAPTURE(BM_DrawVertices, \
TriangleStrip/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkVertices::VertexMode::kTriangleStrip_VertexMode) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@@ -229,7 +207,7 @@ void BM_DrawShadow(benchmark::State& state,
\
BENCHMARK_CAPTURE(BM_DrawVertices, \
TriangleFan/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkVertices::VertexMode::kTriangleFan_VertexMode) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@@ -239,7 +217,7 @@ void BM_DrawShadow(benchmark::State& state,
\
BENCHMARK_CAPTURE(BM_DrawVertices, \
Triangles/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkVertices::VertexMode::kTriangles_VertexMode) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@@ -251,7 +229,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawRRect \
*/ \
BENCHMARK_CAPTURE(BM_DrawRRect, Symmetric/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkRRect::Type::kSimple_Type) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@@ -259,7 +237,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawRRect, NinePatch/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkRRect::Type::kNinePatch_Type) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@@ -267,7 +245,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawRRect, Complex/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkRRect::Type::kComplex_Type) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@@ -278,18 +256,18 @@ void BM_DrawShadow(benchmark::State& state,
* DrawImage \
*/ \
BENCHMARK_CAPTURE(BM_DrawImage, Texture/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkSamplingOptions(), false) \
->RangeMultiplier(2) \
->Range(128, 1024) \
->Range(128, 512) \
->UseRealTime() \
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawImage, Upload/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkSamplingOptions(), true) \
->RangeMultiplier(2) \
->Range(128, 1024) \
->Range(128, 512) \
->UseRealTime() \
->Unit(benchmark::kMillisecond); \
\
@@ -298,7 +276,7 @@ void BM_DrawShadow(benchmark::State& state,
*/ \
BENCHMARK_CAPTURE( \
BM_DrawImageRect, Texture/Strict/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), SkSamplingOptions(), \
BackendType::k##BACKEND##_Backend, SkSamplingOptions(), \
SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint, false) \
->RangeMultiplier(2) \
->Range(32, 256) \
@@ -307,7 +285,7 @@ void BM_DrawShadow(benchmark::State& state,
\
BENCHMARK_CAPTURE( \
BM_DrawImageRect, Texture/Fast/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), SkSamplingOptions(), \
BackendType::k##BACKEND##_Backend, SkSamplingOptions(), \
SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint, false) \
->RangeMultiplier(2) \
->Range(32, 256) \
@@ -316,7 +294,7 @@ void BM_DrawShadow(benchmark::State& state,
\
BENCHMARK_CAPTURE( \
BM_DrawImageRect, Upload/Strict/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), SkSamplingOptions(), \
BackendType::k##BACKEND##_Backend, SkSamplingOptions(), \
SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint, true) \
->RangeMultiplier(2) \
->Range(32, 256) \
@@ -325,7 +303,7 @@ void BM_DrawShadow(benchmark::State& state,
\
BENCHMARK_CAPTURE( \
BM_DrawImageRect, Upload/Fast/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), SkSamplingOptions(), \
BackendType::k##BACKEND##_Backend, SkSamplingOptions(), \
SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint, true) \
->RangeMultiplier(2) \
->Range(32, 256) \
@@ -336,7 +314,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawImageNine \
*/ \
BENCHMARK_CAPTURE(BM_DrawImageNine, Texture/Nearest/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkFilterMode::kNearest, false) \
->RangeMultiplier(2) \
->Range(32, 256) \
@@ -344,7 +322,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawImageNine, Upload/Nearest/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkFilterMode::kNearest, true) \
->RangeMultiplier(2) \
->Range(32, 256) \
@@ -352,7 +330,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawImageNine, Texture/Linear/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkFilterMode::kLinear, false) \
->RangeMultiplier(2) \
->Range(32, 256) \
@@ -360,7 +338,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawImageNine, Upload/Linear/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), \
BackendType::k##BACKEND##_Backend, \
SkFilterMode::kLinear, true) \
->RangeMultiplier(2) \
->Range(32, 256) \
@@ -371,7 +349,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawTextBlob \
*/ \
BENCHMARK_CAPTURE(BM_DrawTextBlob, BACKEND, \
std::make_unique<BACKEND##CanvasProvider>()) \
BackendType::k##BACKEND##_Backend) \
->RangeMultiplier(2) \
->Range(1, 256) \
->UseRealTime() \
@@ -382,7 +360,7 @@ void BM_DrawShadow(benchmark::State& state,
* DrawShadow \
*/ \
BENCHMARK_CAPTURE(BM_DrawShadow, Lines/Transparent/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), true, \
BackendType::k##BACKEND##_Backend, true, \
SkPath::Verb::kLine_Verb) \
->RangeMultiplier(2) \
->Range(1, 32) \
@@ -390,7 +368,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Quads/Transparent/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), true, \
BackendType::k##BACKEND##_Backend, true, \
SkPath::Verb::kQuad_Verb) \
->RangeMultiplier(2) \
->Range(1, 32) \
@@ -398,7 +376,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Conics/Transparent/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), true, \
BackendType::k##BACKEND##_Backend, true, \
SkPath::Verb::kConic_Verb) \
->RangeMultiplier(2) \
->Range(1, 32) \
@@ -406,7 +384,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Cubics/Transparent/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), true, \
BackendType::k##BACKEND##_Backend, true, \
SkPath::Verb::kCubic_Verb) \
->RangeMultiplier(2) \
->Range(1, 32) \
@@ -414,7 +392,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Lines/Opaque/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), false, \
BackendType::k##BACKEND##_Backend, false, \
SkPath::Verb::kLine_Verb) \
->RangeMultiplier(2) \
->Range(1, 32) \
@@ -422,7 +400,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Quads/Opaque/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), false, \
BackendType::k##BACKEND##_Backend, false, \
SkPath::Verb::kQuad_Verb) \
->RangeMultiplier(2) \
->Range(1, 32) \
@@ -430,7 +408,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Conics/Opaque/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), false, \
BackendType::k##BACKEND##_Backend, false, \
SkPath::Verb::kConic_Verb) \
->RangeMultiplier(2) \
->Range(1, 32) \
@@ -438,7 +416,7 @@ void BM_DrawShadow(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Cubics/Opaque/BACKEND, \
std::make_unique<BACKEND##CanvasProvider>(), false, \
BackendType::k##BACKEND##_Backend, false, \
SkPath::Verb::kCubic_Verb) \
->RangeMultiplier(2) \
->Range(1, 32) \

View File

@@ -0,0 +1,51 @@
// 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.
#ifndef FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_CANVAS_PROVIDER_H_
#define FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_CANVAS_PROVIDER_H_
#include "flutter/fml/mapping.h"
#include "flutter/testing/testing.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace flutter {
namespace testing {
class CanvasProvider {
public:
virtual ~CanvasProvider() = default;
virtual const std::string BackendName() = 0;
virtual void InitializeSurface(const size_t width, const size_t height) = 0;
virtual sk_sp<SkSurface> GetSurface() = 0;
virtual sk_sp<SkSurface> MakeOffscreenSurface(const size_t width,
const size_t height) = 0;
virtual bool Snapshot(std::string filename) {
#ifdef BENCHMARKS_NO_SNAPSHOT
return false;
#else
auto image = GetSurface()->makeImageSnapshot();
if (!image) {
return false;
}
auto raster = image->makeRasterImage();
if (!raster) {
return false;
}
auto data = raster->encodeToData();
if (!data) {
return false;
}
fml::NonOwnedMapping mapping(static_cast<const uint8_t*>(data->data()),
data->size());
return WriteAtomically(OpenFixturesDirectory(), filename.c_str(), mapping);
#endif
}
};
} // namespace testing
} // namespace flutter
#endif // FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_CANVAS_PROVIDER_H_

View File

@@ -2,57 +2,48 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/display_list/display_list_benchmarks_gl.h"
#include "flutter/display_list/display_list_benchmarks.h"
#include "flutter/testing/test_gl_surface.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace flutter {
namespace testing {
class OpenGLCanvasProvider : public CanvasProvider {
public:
virtual ~OpenGLCanvasProvider() = default;
void InitializeSurface(const size_t width, const size_t height) override {
surface_size_ = SkISize::Make(width, height);
void OpenGLCanvasProvider::InitializeSurface(const size_t width,
const size_t height) {
surface_size_ = SkISize::Make(width, height);
gl_surface_ = std::make_unique<TestGLSurface>(surface_size_);
gl_surface_->MakeCurrent();
gl_surface_ = std::make_unique<TestGLSurface>(surface_size_);
gl_surface_->MakeCurrent();
const auto image_info = SkImageInfo::MakeN32Premul(surface_size_);
surface_ = SkSurface::MakeRenderTarget(
gl_surface_->GetGrContext().get(), SkBudgeted::kNo, image_info, 1,
kTopLeft_GrSurfaceOrigin, nullptr, false);
surface_->getCanvas()->clear(SK_ColorTRANSPARENT);
const auto image_info = SkImageInfo::MakeN32Premul(surface_size_);
surface_ = SkSurface::MakeRenderTarget(
gl_surface_->GetGrContext().get(), SkBudgeted::kNo, image_info, 1,
kTopLeft_GrSurfaceOrigin, nullptr, false);
surface_->getCanvas()->clear(SK_ColorTRANSPARENT);
}
sk_sp<SkSurface> OpenGLCanvasProvider::GetSurface() {
if (!gl_surface_->MakeCurrent()) {
return nullptr;
}
return surface_;
}
sk_sp<SkSurface> GetSurface() override {
if (!gl_surface_->MakeCurrent()) {
return nullptr;
}
return surface_;
}
sk_sp<SkSurface> OpenGLCanvasProvider::MakeOffscreenSurface(
const size_t width,
const size_t height) {
surface_size_ = SkISize::Make(width, height);
const auto image_info = SkImageInfo::MakeN32Premul(surface_size_);
sk_sp<SkSurface> MakeOffscreenSurface(const size_t width,
const size_t height) override {
surface_size_ = SkISize::Make(width, height);
const auto image_info = SkImageInfo::MakeN32Premul(surface_size_);
auto offscreen_surface = SkSurface::MakeRenderTarget(
gl_surface_->GetGrContext().get(), SkBudgeted::kNo, image_info, 1,
kTopLeft_GrSurfaceOrigin, nullptr, false);
auto offscreen_surface = SkSurface::MakeRenderTarget(
gl_surface_->GetGrContext().get(), SkBudgeted::kNo, image_info, 1,
kTopLeft_GrSurfaceOrigin, nullptr, false);
offscreen_surface->getCanvas()->clear(SK_ColorTRANSPARENT);
return offscreen_surface;
}
const std::string BackendName() override { return "OpenGL"; }
private:
SkISize surface_size_;
sk_sp<SkSurface> surface_;
std::unique_ptr<TestGLSurface> gl_surface_;
};
offscreen_surface->getCanvas()->clear(SK_ColorTRANSPARENT);
return offscreen_surface;
}
RUN_DISPLAYLIST_BENCHMARKS(OpenGL)

View File

@@ -0,0 +1,32 @@
// 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.
#ifndef FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_GL_H_
#define FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_GL_H_
#include "flutter/display_list/display_list_benchmarks_canvas_provider.h"
#include "flutter/testing/test_gl_surface.h"
namespace flutter {
namespace testing {
class OpenGLCanvasProvider : public CanvasProvider {
public:
virtual ~OpenGLCanvasProvider() = default;
void InitializeSurface(const size_t width, const size_t height) override;
sk_sp<SkSurface> GetSurface() override;
sk_sp<SkSurface> MakeOffscreenSurface(const size_t width,
const size_t height) override;
const std::string BackendName() override { return "OpenGL"; }
private:
SkISize surface_size_;
sk_sp<SkSurface> surface_;
std::unique_ptr<TestGLSurface> gl_surface_;
};
} // namespace testing
} // namespace flutter
#endif // FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_GL_H_

View File

@@ -2,45 +2,36 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/display_list/display_list_benchmarks_metal.h"
#include "flutter/display_list/display_list_benchmarks.h"
#include "flutter/testing/test_metal_surface.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace flutter {
namespace testing {
class MetalCanvasProvider : public CanvasProvider {
public:
virtual ~MetalCanvasProvider() = default;
void InitializeSurface(const size_t width, const size_t height) override {
metal_context_ = std::make_unique<TestMetalContext>();
metal_surface_ =
TestMetalSurface::Create(*metal_context_, SkISize::Make(width, height));
metal_surface_->GetSurface()->getCanvas()->clear(SK_ColorTRANSPARENT);
void MetalCanvasProvider::InitializeSurface(const size_t width,
const size_t height) {
metal_context_ = std::make_unique<TestMetalContext>();
metal_surface_ =
TestMetalSurface::Create(*metal_context_, SkISize::Make(width, height));
metal_surface_->GetSurface()->getCanvas()->clear(SK_ColorTRANSPARENT);
}
sk_sp<SkSurface> MetalCanvasProvider::GetSurface() {
if (!metal_surface_) {
return nullptr;
}
return metal_surface_->GetSurface();
}
sk_sp<SkSurface> GetSurface() override {
if (!metal_surface_) {
return nullptr;
}
return metal_surface_->GetSurface();
}
sk_sp<SkSurface> MakeOffscreenSurface(const size_t width,
const size_t height) override {
metal_offscreen_surface_ =
TestMetalSurface::Create(*metal_context_, SkISize::Make(width, height));
return metal_offscreen_surface_->GetSurface();
}
const std::string BackendName() override { return "Metal"; }
private:
std::unique_ptr<TestMetalContext> metal_context_;
std::unique_ptr<TestMetalSurface> metal_surface_;
std::unique_ptr<TestMetalSurface> metal_offscreen_surface_;
};
sk_sp<SkSurface> MetalCanvasProvider::MakeOffscreenSurface(
const size_t width,
const size_t height) {
metal_offscreen_surface_ =
TestMetalSurface::Create(*metal_context_, SkISize::Make(width, height));
return metal_offscreen_surface_->GetSurface();
}
RUN_DISPLAYLIST_BENCHMARKS(Metal)

View File

@@ -0,0 +1,33 @@
// 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.
#ifndef FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_METAL_H_
#define FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_METAL_H_
#include "flutter/display_list/display_list_benchmarks_canvas_provider.h"
#include "flutter/testing/test_metal_surface.h"
namespace flutter {
namespace testing {
class MetalCanvasProvider : public CanvasProvider {
public:
virtual ~MetalCanvasProvider() = default;
void InitializeSurface(const size_t width, const size_t height) override;
sk_sp<SkSurface> GetSurface() override;
sk_sp<SkSurface> MakeOffscreenSurface(const size_t width,
const size_t height) override;
const std::string BackendName() override { return "Metal"; }
private:
std::unique_ptr<TestMetalContext> metal_context_;
std::unique_ptr<TestMetalSurface> metal_surface_;
std::unique_ptr<TestMetalSurface> metal_offscreen_surface_;
};
} // namespace testing
} // namespace flutter
#endif // FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_METAL_H_

View File

@@ -2,36 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/display_list/display_list_benchmarks_software.h"
#include "flutter/display_list/display_list_benchmarks.h"
#include "flutter/display_list/display_list_builder.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "third_party/skia/include/core/SkTextBlob.h"
namespace flutter {
namespace testing {
class SoftwareCanvasProvider : public CanvasProvider {
public:
virtual ~SoftwareCanvasProvider() = default;
void InitializeSurface(const size_t width, const size_t height) override {
surface_ = SkSurface::MakeRasterN32Premul(width, height);
surface_->getCanvas()->clear(SK_ColorTRANSPARENT);
}
void SoftwareCanvasProvider::InitializeSurface(const size_t width,
const size_t height) {
surface_ = SkSurface::MakeRasterN32Premul(width, height);
surface_->getCanvas()->clear(SK_ColorTRANSPARENT);
}
sk_sp<SkSurface> GetSurface() override { return surface_; }
sk_sp<SkSurface> MakeOffscreenSurface(const size_t width,
const size_t height) override {
auto surface = SkSurface::MakeRasterN32Premul(width, height);
surface->getCanvas()->clear(SK_ColorTRANSPARENT);
return surface;
}
const std::string BackendName() override { return "Software"; }
private:
sk_sp<SkSurface> surface_;
};
sk_sp<SkSurface> SoftwareCanvasProvider::MakeOffscreenSurface(
const size_t width,
const size_t height) {
auto surface = SkSurface::MakeRasterN32Premul(width, height);
surface->getCanvas()->clear(SK_ColorTRANSPARENT);
return surface;
}
RUN_DISPLAYLIST_BENCHMARKS(Software)

View File

@@ -0,0 +1,31 @@
// 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.
#ifndef FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_SOFTWARE_H_
#define FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_SOFTWARE_H_
#include "flutter/display_list/display_list_benchmarks_canvas_provider.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace flutter {
namespace testing {
class SoftwareCanvasProvider : public CanvasProvider {
public:
virtual ~SoftwareCanvasProvider() = default;
void InitializeSurface(const size_t width, const size_t height) override;
sk_sp<SkSurface> GetSurface() override { return surface_; }
sk_sp<SkSurface> MakeOffscreenSurface(const size_t width,
const size_t height) override;
const std::string BackendName() override { return "Software"; }
private:
sk_sp<SkSurface> surface_;
};
} // namespace testing
} // namespace flutter
#endif // FLUTTER_FLOW_DISPLAY_LIST_BENCHMARKS_SOFTWARE_H_