mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Create benchmarks for DisplayListBuilder (flutter/engine#34910)
This commit is contained in:
parent
9c88c82e33
commit
cbda16b4b4
@ -126,6 +126,7 @@ group("flutter") {
|
||||
if (enable_unittests && !is_win && !is_fuchsia) {
|
||||
public_deps += [
|
||||
"//flutter/display_list:display_list_benchmarks",
|
||||
"//flutter/display_list:display_list_builder_benchmarks",
|
||||
"//flutter/fml:fml_benchmarks",
|
||||
"//flutter/lib/ui:ui_benchmarks",
|
||||
"//flutter/shell/common:shell_benchmarks",
|
||||
|
||||
@ -55,6 +55,7 @@ FILE: ../../../flutter/display_list/display_list_blend_mode.cc
|
||||
FILE: ../../../flutter/display_list/display_list_blend_mode.h
|
||||
FILE: ../../../flutter/display_list/display_list_builder.cc
|
||||
FILE: ../../../flutter/display_list/display_list_builder.h
|
||||
FILE: ../../../flutter/display_list/display_list_builder_benchmarks.cc
|
||||
FILE: ../../../flutter/display_list/display_list_canvas_dispatcher.cc
|
||||
FILE: ../../../flutter/display_list/display_list_canvas_dispatcher.h
|
||||
FILE: ../../../flutter/display_list/display_list_canvas_recorder.cc
|
||||
|
||||
@ -154,6 +154,20 @@ if (enable_unittests) {
|
||||
[ "${fuchsia_sdk_path}/arch/${target_cpu}/sysroot/lib/libzircon.so" ]
|
||||
}
|
||||
}
|
||||
|
||||
executable("display_list_builder_benchmarks") {
|
||||
testonly = true
|
||||
|
||||
sources = [ "display_list_builder_benchmarks.cc" ]
|
||||
|
||||
deps = [
|
||||
":display_list",
|
||||
":display_list_fixtures",
|
||||
":display_list_testing",
|
||||
"//flutter/benchmarking",
|
||||
"//flutter/testing:testing_lib",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fixtures_location("display_list_benchmarks_fixtures") {
|
||||
|
||||
@ -0,0 +1,235 @@
|
||||
// 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/benchmarking/benchmarking.h"
|
||||
#include "flutter/display_list/display_list_test_utils.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace {
|
||||
|
||||
static std::vector<testing::DisplayListInvocationGroup> allRenderingOps =
|
||||
testing::CreateAllRenderingOps();
|
||||
|
||||
enum class DisplayListBuilderBenchmarkType {
|
||||
kDefault,
|
||||
kBounds,
|
||||
kRtree,
|
||||
kBoundsAndRtree,
|
||||
};
|
||||
|
||||
static void InvokeAllRenderingOps(DisplayListBuilder& builder) {
|
||||
for (auto& group : allRenderingOps) {
|
||||
for (size_t i = 0; i < group.variants.size(); i++) {
|
||||
auto& invocation = group.variants[i];
|
||||
invocation.Invoke(builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Complete(DisplayListBuilder& builder,
|
||||
DisplayListBuilderBenchmarkType type) {
|
||||
auto display_list = builder.Build();
|
||||
switch (type) {
|
||||
case DisplayListBuilderBenchmarkType::kBounds:
|
||||
display_list->bounds();
|
||||
break;
|
||||
case DisplayListBuilderBenchmarkType::kRtree:
|
||||
display_list->rtree();
|
||||
break;
|
||||
case DisplayListBuilderBenchmarkType::kBoundsAndRtree:
|
||||
display_list->bounds();
|
||||
display_list->rtree();
|
||||
break;
|
||||
case DisplayListBuilderBenchmarkType::kDefault:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
static void BM_DisplayListBuiderDefault(benchmark::State& state,
|
||||
DisplayListBuilderBenchmarkType type) {
|
||||
while (state.KeepRunning()) {
|
||||
DisplayListBuilder builder;
|
||||
InvokeAllRenderingOps(builder);
|
||||
Complete(builder, type);
|
||||
}
|
||||
}
|
||||
|
||||
static void BM_DisplayListBuiderWithScaleAndTranslate(
|
||||
benchmark::State& state,
|
||||
DisplayListBuilderBenchmarkType type) {
|
||||
while (state.KeepRunning()) {
|
||||
DisplayListBuilder builder;
|
||||
builder.scale(3.5, 3.5);
|
||||
builder.translate(10.3, 6.9);
|
||||
InvokeAllRenderingOps(builder);
|
||||
Complete(builder, type);
|
||||
}
|
||||
}
|
||||
|
||||
static void BM_DisplayListBuiderWithPerspective(
|
||||
benchmark::State& state,
|
||||
DisplayListBuilderBenchmarkType type) {
|
||||
while (state.KeepRunning()) {
|
||||
DisplayListBuilder builder;
|
||||
builder.transformFullPerspective(0, 1, 0, 12, 1, 0, 0, 33, 3, 2, 5, 29, 0,
|
||||
0, 0, 12);
|
||||
InvokeAllRenderingOps(builder);
|
||||
Complete(builder, type);
|
||||
}
|
||||
}
|
||||
|
||||
static void BM_DisplayListBuiderWithClipRect(
|
||||
benchmark::State& state,
|
||||
DisplayListBuilderBenchmarkType type) {
|
||||
SkRect clip_bounds = SkRect::MakeLTRB(6.5, 7.3, 90.2, 85.7);
|
||||
while (state.KeepRunning()) {
|
||||
DisplayListBuilder builder;
|
||||
builder.clipRect(clip_bounds, SkClipOp::kIntersect, true);
|
||||
InvokeAllRenderingOps(builder);
|
||||
Complete(builder, type);
|
||||
}
|
||||
}
|
||||
|
||||
static void BM_DisplayListBuiderWithSaveLayer(
|
||||
benchmark::State& state,
|
||||
DisplayListBuilderBenchmarkType type) {
|
||||
while (state.KeepRunning()) {
|
||||
DisplayListBuilder builder;
|
||||
for (auto& group : allRenderingOps) {
|
||||
for (size_t i = 0; i < group.variants.size(); i++) {
|
||||
auto& invocation = group.variants[i];
|
||||
builder.saveLayer(nullptr, false);
|
||||
invocation.Invoke(builder);
|
||||
builder.restore();
|
||||
}
|
||||
}
|
||||
Complete(builder, type);
|
||||
}
|
||||
}
|
||||
|
||||
static void BM_DisplayListBuiderWithSaveLayerAndImageFilter(
|
||||
benchmark::State& state,
|
||||
DisplayListBuilderBenchmarkType type) {
|
||||
DlPaint layer_paint;
|
||||
layer_paint.setImageFilter(&testing::kTestBlurImageFilter1);
|
||||
SkRect layer_bounds = SkRect::MakeLTRB(6.5, 7.3, 35.2, 42.7);
|
||||
while (state.KeepRunning()) {
|
||||
DisplayListBuilder builder;
|
||||
for (auto& group : allRenderingOps) {
|
||||
for (size_t i = 0; i < group.variants.size(); i++) {
|
||||
auto& invocation = group.variants[i];
|
||||
builder.saveLayer(&layer_bounds, &layer_paint);
|
||||
invocation.Invoke(builder);
|
||||
builder.restore();
|
||||
}
|
||||
}
|
||||
Complete(builder, type);
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderDefault,
|
||||
kDefault,
|
||||
DisplayListBuilderBenchmarkType::kDefault)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderDefault,
|
||||
kBounds,
|
||||
DisplayListBuilderBenchmarkType::kBounds)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderDefault,
|
||||
kRtree,
|
||||
DisplayListBuilderBenchmarkType::kRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderDefault,
|
||||
kBoundsAndRtree,
|
||||
DisplayListBuilderBenchmarkType::kBoundsAndRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithScaleAndTranslate,
|
||||
kDefault,
|
||||
DisplayListBuilderBenchmarkType::kDefault)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithScaleAndTranslate,
|
||||
kBounds,
|
||||
DisplayListBuilderBenchmarkType::kBounds)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithScaleAndTranslate,
|
||||
kRtree,
|
||||
DisplayListBuilderBenchmarkType::kRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithScaleAndTranslate,
|
||||
kBoundsAndRtree,
|
||||
DisplayListBuilderBenchmarkType::kBoundsAndRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithPerspective,
|
||||
kDefault,
|
||||
DisplayListBuilderBenchmarkType::kDefault)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithPerspective,
|
||||
kBounds,
|
||||
DisplayListBuilderBenchmarkType::kBounds)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithPerspective,
|
||||
kRtree,
|
||||
DisplayListBuilderBenchmarkType::kRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithPerspective,
|
||||
kBoundsAndRtree,
|
||||
DisplayListBuilderBenchmarkType::kBoundsAndRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithClipRect,
|
||||
kDefault,
|
||||
DisplayListBuilderBenchmarkType::kDefault)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithClipRect,
|
||||
kBounds,
|
||||
DisplayListBuilderBenchmarkType::kBounds)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithClipRect,
|
||||
kRtree,
|
||||
DisplayListBuilderBenchmarkType::kRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithClipRect,
|
||||
kBoundsAndRtree,
|
||||
DisplayListBuilderBenchmarkType::kBoundsAndRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithSaveLayer,
|
||||
kDefault,
|
||||
DisplayListBuilderBenchmarkType::kDefault)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithSaveLayer,
|
||||
kBounds,
|
||||
DisplayListBuilderBenchmarkType::kBounds)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithSaveLayer,
|
||||
kRtree,
|
||||
DisplayListBuilderBenchmarkType::kRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithSaveLayer,
|
||||
kBoundsAndRtree,
|
||||
DisplayListBuilderBenchmarkType::kBoundsAndRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithSaveLayerAndImageFilter,
|
||||
kDefault,
|
||||
DisplayListBuilderBenchmarkType::kDefault)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithSaveLayerAndImageFilter,
|
||||
kBounds,
|
||||
DisplayListBuilderBenchmarkType::kBounds)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithSaveLayerAndImageFilter,
|
||||
kRtree,
|
||||
DisplayListBuilderBenchmarkType::kRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
BENCHMARK_CAPTURE(BM_DisplayListBuiderWithSaveLayerAndImageFilter,
|
||||
kBoundsAndRtree,
|
||||
DisplayListBuilderBenchmarkType::kBoundsAndRtree)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
|
||||
} // namespace flutter
|
||||
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,12 @@
|
||||
#include "flutter/display_list/display_list_builder.h"
|
||||
|
||||
#include "third_party/skia/include/core/SkPicture.h"
|
||||
#include "third_party/skia/include/core/SkPictureRecorder.h"
|
||||
#include "third_party/skia/include/core/SkSurface.h"
|
||||
#include "third_party/skia/include/effects/SkBlenders.h"
|
||||
#include "third_party/skia/include/effects/SkDashPathEffect.h"
|
||||
#include "third_party/skia/include/effects/SkGradientShader.h"
|
||||
#include "third_party/skia/include/effects/SkImageFilters.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
@ -17,6 +23,313 @@ sk_sp<DisplayList> GetSampleDisplayList();
|
||||
sk_sp<DisplayList> GetSampleDisplayList(int ops);
|
||||
sk_sp<DisplayList> GetSampleNestedDisplayList();
|
||||
|
||||
typedef const std::function<void(DisplayListBuilder&)> DlInvoker;
|
||||
|
||||
constexpr SkPoint kEndPoints[] = {
|
||||
{0, 0},
|
||||
{100, 100},
|
||||
};
|
||||
const DlColor kColors[] = {
|
||||
DlColor::kGreen(),
|
||||
DlColor::kYellow(),
|
||||
DlColor::kBlue(),
|
||||
};
|
||||
constexpr float kStops[] = {
|
||||
0.0,
|
||||
0.5,
|
||||
1.0,
|
||||
};
|
||||
static std::vector<uint32_t> color_vector(kColors, kColors + 3);
|
||||
static std::vector<float> stops_vector(kStops, kStops + 3);
|
||||
|
||||
// clang-format off
|
||||
constexpr float kRotateColorMatrix[20] = {
|
||||
0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
};
|
||||
constexpr float kInvertColorMatrix[20] = {
|
||||
-1.0, 0, 0, 1.0, 0,
|
||||
0, -1.0, 0, 1.0, 0,
|
||||
0, 0, -1.0, 1.0, 0,
|
||||
1.0, 1.0, 1.0, 1.0, 0,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
const SkScalar kTestDashes1[] = {4.0, 2.0};
|
||||
const SkScalar kTestDashes2[] = {1.0, 1.5};
|
||||
|
||||
constexpr SkPoint TestPoints[] = {
|
||||
{10, 10},
|
||||
{20, 20},
|
||||
{10, 20},
|
||||
{20, 10},
|
||||
};
|
||||
#define TestPointCount sizeof(TestPoints) / (sizeof(TestPoints[0]))
|
||||
|
||||
static DlImageSampling kNearestSampling = DlImageSampling::kNearestNeighbor;
|
||||
static DlImageSampling kLinearSampling = DlImageSampling::kLinear;
|
||||
|
||||
static sk_sp<DlImage> MakeTestImage(int w, int h, int checker_size) {
|
||||
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(w, h);
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
SkPaint p0, p1;
|
||||
p0.setStyle(SkPaint::kFill_Style);
|
||||
p0.setColor(SK_ColorGREEN);
|
||||
p1.setStyle(SkPaint::kFill_Style);
|
||||
p1.setColor(SK_ColorBLUE);
|
||||
p1.setAlpha(128);
|
||||
for (int y = 0; y < w; y += checker_size) {
|
||||
for (int x = 0; x < h; x += checker_size) {
|
||||
SkPaint& cellp = ((x + y) & 1) == 0 ? p0 : p1;
|
||||
canvas->drawRect(SkRect::MakeXYWH(x, y, checker_size, checker_size),
|
||||
cellp);
|
||||
}
|
||||
}
|
||||
return DlImage::Make(surface->makeImageSnapshot());
|
||||
}
|
||||
|
||||
static auto TestImage1 = MakeTestImage(40, 40, 5);
|
||||
static auto TestImage2 = MakeTestImage(50, 50, 5);
|
||||
|
||||
static const sk_sp<SkBlender> kTestBlender1 =
|
||||
SkBlenders::Arithmetic(0.2, 0.2, 0.2, 0.2, false);
|
||||
static const sk_sp<SkBlender> kTestBlender2 =
|
||||
SkBlenders::Arithmetic(0.2, 0.2, 0.2, 0.2, true);
|
||||
static const sk_sp<SkBlender> kTestBlender3 =
|
||||
SkBlenders::Arithmetic(0.3, 0.3, 0.3, 0.3, true);
|
||||
static const DlImageColorSource kTestSource1(TestImage1->skia_image(),
|
||||
DlTileMode::kClamp,
|
||||
DlTileMode::kMirror,
|
||||
kLinearSampling);
|
||||
static const std::shared_ptr<DlColorSource> kTestSource2 =
|
||||
DlColorSource::MakeLinear(kEndPoints[0],
|
||||
kEndPoints[1],
|
||||
3,
|
||||
kColors,
|
||||
kStops,
|
||||
DlTileMode::kMirror);
|
||||
static const std::shared_ptr<DlColorSource> kTestSource3 =
|
||||
DlColorSource::MakeRadial(kEndPoints[0],
|
||||
10.0,
|
||||
3,
|
||||
kColors,
|
||||
kStops,
|
||||
DlTileMode::kMirror);
|
||||
static const std::shared_ptr<DlColorSource> kTestSource4 =
|
||||
DlColorSource::MakeConical(kEndPoints[0],
|
||||
10.0,
|
||||
kEndPoints[1],
|
||||
200.0,
|
||||
3,
|
||||
kColors,
|
||||
kStops,
|
||||
DlTileMode::kDecal);
|
||||
static const std::shared_ptr<DlColorSource> kTestSource5 =
|
||||
DlColorSource::MakeSweep(kEndPoints[0],
|
||||
0.0,
|
||||
360.0,
|
||||
3,
|
||||
kColors,
|
||||
kStops,
|
||||
DlTileMode::kDecal);
|
||||
static const DlBlendColorFilter kTestBlendColorFilter1(DlColor::kRed(),
|
||||
DlBlendMode::kDstATop);
|
||||
static const DlBlendColorFilter kTestBlendColorFilter2(DlColor::kBlue(),
|
||||
DlBlendMode::kDstATop);
|
||||
static const DlBlendColorFilter kTestBlendColorFilter3(DlColor::kRed(),
|
||||
DlBlendMode::kDstIn);
|
||||
static const DlMatrixColorFilter kTestMatrixColorFilter1(kRotateColorMatrix);
|
||||
static const DlMatrixColorFilter kTestMatrixColorFilter2(kInvertColorMatrix);
|
||||
static const DlBlurImageFilter kTestBlurImageFilter1(5.0,
|
||||
5.0,
|
||||
DlTileMode::kClamp);
|
||||
static const DlBlurImageFilter kTestBlurImageFilter2(6.0,
|
||||
5.0,
|
||||
DlTileMode::kClamp);
|
||||
static const DlBlurImageFilter kTestBlurImageFilter3(5.0,
|
||||
6.0,
|
||||
DlTileMode::kClamp);
|
||||
static const DlBlurImageFilter kTestBlurImageFilter4(5.0,
|
||||
5.0,
|
||||
DlTileMode::kDecal);
|
||||
static const DlDilateImageFilter kTestDilateImageFilter1(5.0, 5.0);
|
||||
static const DlDilateImageFilter kTestDilateImageFilter2(6.0, 5.0);
|
||||
static const DlDilateImageFilter kTestDilateImageFilter3(5.0, 6.0);
|
||||
static const DlErodeImageFilter kTestErodeImageFilter1(5.0, 5.0);
|
||||
static const DlErodeImageFilter kTestErodeImageFilter2(6.0, 5.0);
|
||||
static const DlErodeImageFilter kTestErodeImageFilter3(5.0, 6.0);
|
||||
static const DlMatrixImageFilter kTestMatrixImageFilter1(
|
||||
SkMatrix::RotateDeg(45),
|
||||
kNearestSampling);
|
||||
static const DlMatrixImageFilter kTestMatrixImageFilter2(
|
||||
SkMatrix::RotateDeg(85),
|
||||
kNearestSampling);
|
||||
static const DlMatrixImageFilter kTestMatrixImageFilter3(
|
||||
SkMatrix::RotateDeg(45),
|
||||
kLinearSampling);
|
||||
static const DlComposeImageFilter kTestComposeImageFilter1(
|
||||
kTestBlurImageFilter1,
|
||||
kTestMatrixImageFilter1);
|
||||
static const DlComposeImageFilter kTestComposeImageFilter2(
|
||||
kTestBlurImageFilter2,
|
||||
kTestMatrixImageFilter1);
|
||||
static const DlComposeImageFilter kTestComposeImageFilter3(
|
||||
kTestBlurImageFilter1,
|
||||
kTestMatrixImageFilter2);
|
||||
static const DlColorFilterImageFilter kTestCFImageFilter1(
|
||||
kTestBlendColorFilter1);
|
||||
static const DlColorFilterImageFilter kTestCFImageFilter2(
|
||||
kTestBlendColorFilter2);
|
||||
static const std::shared_ptr<DlPathEffect> kTestPathEffect1 =
|
||||
DlDashPathEffect::Make(kTestDashes1, 2, 0.0f);
|
||||
static const std::shared_ptr<DlPathEffect> kTestPathEffect2 =
|
||||
DlDashPathEffect::Make(kTestDashes2, 2, 0.0f);
|
||||
static const DlBlurMaskFilter kTestMaskFilter1(kNormal_SkBlurStyle, 3.0);
|
||||
static const DlBlurMaskFilter kTestMaskFilter2(kNormal_SkBlurStyle, 5.0);
|
||||
static const DlBlurMaskFilter kTestMaskFilter3(kSolid_SkBlurStyle, 3.0);
|
||||
static const DlBlurMaskFilter kTestMaskFilter4(kInner_SkBlurStyle, 3.0);
|
||||
static const DlBlurMaskFilter kTestMaskFilter5(kOuter_SkBlurStyle, 3.0);
|
||||
constexpr SkRect kTestBounds = SkRect::MakeLTRB(10, 10, 50, 60);
|
||||
static const SkRRect kTestRRect = SkRRect::MakeRectXY(kTestBounds, 5, 5);
|
||||
static const SkRRect kTestRRectRect = SkRRect::MakeRect(kTestBounds);
|
||||
static const SkRRect kTestInnerRRect =
|
||||
SkRRect::MakeRectXY(kTestBounds.makeInset(5, 5), 2, 2);
|
||||
static const SkPath kTestPathRect = SkPath::Rect(kTestBounds);
|
||||
static const SkPath kTestPathOval = SkPath::Oval(kTestBounds);
|
||||
static const SkPath kTestPath1 =
|
||||
SkPath::Polygon({{0, 0}, {10, 10}, {10, 0}, {0, 10}}, true);
|
||||
static const SkPath kTestPath2 =
|
||||
SkPath::Polygon({{0, 0}, {10, 10}, {0, 10}, {10, 0}}, true);
|
||||
static const SkPath kTestPath3 =
|
||||
SkPath::Polygon({{0, 0}, {10, 10}, {10, 0}, {0, 10}}, false);
|
||||
static const SkMatrix kTestMatrix1 = SkMatrix::Scale(2, 2);
|
||||
static const SkMatrix kTestMatrix2 = SkMatrix::RotateDeg(45);
|
||||
|
||||
static std::shared_ptr<const DlVertices> TestVertices1 =
|
||||
DlVertices::Make(DlVertexMode::kTriangles, //
|
||||
3,
|
||||
TestPoints,
|
||||
nullptr,
|
||||
kColors);
|
||||
static std::shared_ptr<const DlVertices> TestVertices2 =
|
||||
DlVertices::Make(DlVertexMode::kTriangleFan, //
|
||||
3,
|
||||
TestPoints,
|
||||
nullptr,
|
||||
kColors);
|
||||
|
||||
static constexpr int kTestDivs1[] = {10, 20, 30};
|
||||
static constexpr int kTestDivs2[] = {15, 20, 25};
|
||||
static constexpr int kTestDivs3[] = {15, 25};
|
||||
static constexpr SkCanvas::Lattice::RectType kTestRTypes[] = {
|
||||
SkCanvas::Lattice::RectType::kDefault,
|
||||
SkCanvas::Lattice::RectType::kTransparent,
|
||||
SkCanvas::Lattice::RectType::kFixedColor,
|
||||
SkCanvas::Lattice::RectType::kDefault,
|
||||
SkCanvas::Lattice::RectType::kTransparent,
|
||||
SkCanvas::Lattice::RectType::kFixedColor,
|
||||
SkCanvas::Lattice::RectType::kDefault,
|
||||
SkCanvas::Lattice::RectType::kTransparent,
|
||||
SkCanvas::Lattice::RectType::kFixedColor,
|
||||
};
|
||||
static constexpr SkColor kTestLatticeColors[] = {
|
||||
SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW,
|
||||
SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW,
|
||||
SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW,
|
||||
};
|
||||
static constexpr SkIRect kTestLatticeSrcRect = {1, 1, 39, 39};
|
||||
|
||||
static sk_sp<SkPicture> MakeTestPicture(int w, int h, SkColor color) {
|
||||
SkPictureRecorder recorder;
|
||||
SkRTreeFactory rtree_factory;
|
||||
SkCanvas* cv = recorder.beginRecording(kTestBounds, &rtree_factory);
|
||||
SkPaint paint;
|
||||
paint.setColor(color);
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
cv->drawRect(SkRect::MakeWH(w, h), paint);
|
||||
return recorder.finishRecordingAsPicture();
|
||||
}
|
||||
static sk_sp<SkPicture> TestPicture1 = MakeTestPicture(20, 20, SK_ColorGREEN);
|
||||
static sk_sp<SkPicture> TestPicture2 = MakeTestPicture(25, 25, SK_ColorBLUE);
|
||||
|
||||
static sk_sp<DisplayList> MakeTestDisplayList(int w, int h, SkColor color) {
|
||||
DisplayListBuilder builder;
|
||||
builder.setColor(color);
|
||||
builder.drawRect(SkRect::MakeWH(w, h));
|
||||
return builder.Build();
|
||||
}
|
||||
static sk_sp<DisplayList> TestDisplayList1 =
|
||||
MakeTestDisplayList(20, 20, SK_ColorGREEN);
|
||||
static sk_sp<DisplayList> TestDisplayList2 =
|
||||
MakeTestDisplayList(25, 25, SK_ColorBLUE);
|
||||
|
||||
static sk_sp<SkTextBlob> MakeTextBlob(std::string string) {
|
||||
return SkTextBlob::MakeFromText(string.c_str(), string.size(), SkFont(),
|
||||
SkTextEncoding::kUTF8);
|
||||
}
|
||||
static sk_sp<SkTextBlob> TestBlob1 = MakeTextBlob("TestBlob1");
|
||||
static sk_sp<SkTextBlob> TestBlob2 = MakeTextBlob("TestBlob2");
|
||||
|
||||
struct DisplayListInvocation {
|
||||
unsigned int op_count_;
|
||||
size_t byte_count_;
|
||||
|
||||
// in some cases, running the sequence through an SkCanvas will result
|
||||
// in fewer ops/bytes. Attribute invocations are recorded in an SkPaint
|
||||
// and not forwarded on, and SkCanvas culls unused save/restore/transforms.
|
||||
int sk_op_count_;
|
||||
size_t sk_byte_count_;
|
||||
|
||||
DlInvoker invoker;
|
||||
bool supports_group_opacity_ = false;
|
||||
|
||||
bool sk_version_matches() {
|
||||
return (static_cast<int>(op_count_) == sk_op_count_ &&
|
||||
byte_count_ == sk_byte_count_);
|
||||
}
|
||||
|
||||
// A negative sk_op_count means "do not test this op".
|
||||
// Used mainly for these cases:
|
||||
// - we cannot encode a DrawShadowRec (Skia private header)
|
||||
// - SkCanvas cannot receive a DisplayList
|
||||
// - SkCanvas may or may not inline an SkPicture
|
||||
bool sk_testing_invalid() { return sk_op_count_ < 0; }
|
||||
|
||||
bool is_empty() { return byte_count_ == 0; }
|
||||
|
||||
bool supports_group_opacity() { return supports_group_opacity_; }
|
||||
|
||||
unsigned int op_count() { return op_count_; }
|
||||
// byte count for the individual ops, no DisplayList overhead
|
||||
size_t raw_byte_count() { return byte_count_; }
|
||||
// byte count for the ops with DisplayList overhead, comparable
|
||||
// to |DisplayList.byte_count().
|
||||
size_t byte_count() { return sizeof(DisplayList) + byte_count_; }
|
||||
|
||||
int sk_op_count() { return sk_op_count_; }
|
||||
// byte count for the ops with DisplayList overhead as translated
|
||||
// through an SkCanvas interface, comparable to |DisplayList.byte_count().
|
||||
size_t sk_byte_count() { return sizeof(DisplayList) + sk_byte_count_; }
|
||||
|
||||
void Invoke(DisplayListBuilder& builder) { invoker(builder); }
|
||||
|
||||
sk_sp<DisplayList> Build() {
|
||||
DisplayListBuilder builder;
|
||||
invoker(builder);
|
||||
return builder.Build();
|
||||
}
|
||||
};
|
||||
|
||||
struct DisplayListInvocationGroup {
|
||||
std::string op_name;
|
||||
std::vector<DisplayListInvocation> variants;
|
||||
};
|
||||
|
||||
std::vector<DisplayListInvocationGroup> CreateAllRenderingOps();
|
||||
std::vector<DisplayListInvocationGroup> CreateAllGroups();
|
||||
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
|
||||
|
||||
@ -9,883 +9,17 @@
|
||||
#include "flutter/display_list/display_list_builder.h"
|
||||
#include "flutter/display_list/display_list_canvas_recorder.h"
|
||||
#include "flutter/display_list/display_list_rtree.h"
|
||||
#include "flutter/display_list/display_list_test_utils.h"
|
||||
#include "flutter/display_list/display_list_utils.h"
|
||||
#include "flutter/fml/math.h"
|
||||
#include "flutter/testing/display_list_testing.h"
|
||||
#include "flutter/testing/testing.h"
|
||||
#include "third_party/skia/include/core/SkPictureRecorder.h"
|
||||
#include "third_party/skia/include/core/SkSurface.h"
|
||||
#include "third_party/skia/include/effects/SkBlenders.h"
|
||||
#include "third_party/skia/include/effects/SkDashPathEffect.h"
|
||||
#include "third_party/skia/include/effects/SkGradientShader.h"
|
||||
#include "third_party/skia/include/effects/SkImageFilters.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
|
||||
constexpr SkPoint kEndPoints[] = {
|
||||
{0, 0},
|
||||
{100, 100},
|
||||
};
|
||||
const DlColor kColors[] = {
|
||||
DlColor::kGreen(),
|
||||
DlColor::kYellow(),
|
||||
DlColor::kBlue(),
|
||||
};
|
||||
constexpr float kStops[] = {
|
||||
0.0,
|
||||
0.5,
|
||||
1.0,
|
||||
};
|
||||
std::vector<uint32_t> color_vector(kColors, kColors + 3);
|
||||
std::vector<float> stops_vector(kStops, kStops + 3);
|
||||
|
||||
// clang-format off
|
||||
constexpr float kRotateColorMatrix[20] = {
|
||||
0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
};
|
||||
constexpr float kInvertColorMatrix[20] = {
|
||||
-1.0, 0, 0, 1.0, 0,
|
||||
0, -1.0, 0, 1.0, 0,
|
||||
0, 0, -1.0, 1.0, 0,
|
||||
1.0, 1.0, 1.0, 1.0, 0,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
const SkScalar kTestDashes1[] = {4.0, 2.0};
|
||||
const SkScalar kTestDashes2[] = {1.0, 1.5};
|
||||
|
||||
constexpr SkPoint TestPoints[] = {
|
||||
{10, 10},
|
||||
{20, 20},
|
||||
{10, 20},
|
||||
{20, 10},
|
||||
};
|
||||
#define TestPointCount sizeof(TestPoints) / (sizeof(TestPoints[0]))
|
||||
|
||||
static DlImageSampling kNearestSampling = DlImageSampling::kNearestNeighbor;
|
||||
static DlImageSampling kLinearSampling = DlImageSampling::kLinear;
|
||||
|
||||
static sk_sp<DlImage> MakeTestImage(int w, int h, int checker_size) {
|
||||
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(w, h);
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
SkPaint p0, p1;
|
||||
p0.setStyle(SkPaint::kFill_Style);
|
||||
p0.setColor(SK_ColorGREEN);
|
||||
p1.setStyle(SkPaint::kFill_Style);
|
||||
p1.setColor(SK_ColorBLUE);
|
||||
p1.setAlpha(128);
|
||||
for (int y = 0; y < w; y += checker_size) {
|
||||
for (int x = 0; x < h; x += checker_size) {
|
||||
SkPaint& cellp = ((x + y) & 1) == 0 ? p0 : p1;
|
||||
canvas->drawRect(SkRect::MakeXYWH(x, y, checker_size, checker_size),
|
||||
cellp);
|
||||
}
|
||||
}
|
||||
return DlImage::Make(surface->makeImageSnapshot());
|
||||
}
|
||||
|
||||
static auto TestImage1 = MakeTestImage(40, 40, 5);
|
||||
static auto TestImage2 = MakeTestImage(50, 50, 5);
|
||||
|
||||
static const sk_sp<SkBlender> kTestBlender1 =
|
||||
SkBlenders::Arithmetic(0.2, 0.2, 0.2, 0.2, false);
|
||||
static const sk_sp<SkBlender> kTestBlender2 =
|
||||
SkBlenders::Arithmetic(0.2, 0.2, 0.2, 0.2, true);
|
||||
static const sk_sp<SkBlender> kTestBlender3 =
|
||||
SkBlenders::Arithmetic(0.3, 0.3, 0.3, 0.3, true);
|
||||
static const DlImageColorSource kTestSource1(TestImage1->skia_image(),
|
||||
DlTileMode::kClamp,
|
||||
DlTileMode::kMirror,
|
||||
kLinearSampling);
|
||||
static const std::shared_ptr<DlColorSource> kTestSource2 =
|
||||
DlColorSource::MakeLinear(kEndPoints[0],
|
||||
kEndPoints[1],
|
||||
3,
|
||||
kColors,
|
||||
kStops,
|
||||
DlTileMode::kMirror);
|
||||
static const std::shared_ptr<DlColorSource> kTestSource3 =
|
||||
DlColorSource::MakeRadial(kEndPoints[0],
|
||||
10.0,
|
||||
3,
|
||||
kColors,
|
||||
kStops,
|
||||
DlTileMode::kMirror);
|
||||
static const std::shared_ptr<DlColorSource> kTestSource4 =
|
||||
DlColorSource::MakeConical(kEndPoints[0],
|
||||
10.0,
|
||||
kEndPoints[1],
|
||||
200.0,
|
||||
3,
|
||||
kColors,
|
||||
kStops,
|
||||
DlTileMode::kDecal);
|
||||
static const std::shared_ptr<DlColorSource> kTestSource5 =
|
||||
DlColorSource::MakeSweep(kEndPoints[0],
|
||||
0.0,
|
||||
360.0,
|
||||
3,
|
||||
kColors,
|
||||
kStops,
|
||||
DlTileMode::kDecal);
|
||||
static const DlBlendColorFilter kTestBlendColorFilter1(DlColor::kRed(),
|
||||
DlBlendMode::kDstATop);
|
||||
static const DlBlendColorFilter kTestBlendColorFilter2(DlColor::kBlue(),
|
||||
DlBlendMode::kDstATop);
|
||||
static const DlBlendColorFilter kTestBlendColorFilter3(DlColor::kRed(),
|
||||
DlBlendMode::kDstIn);
|
||||
static const DlMatrixColorFilter kTestMatrixColorFilter1(kRotateColorMatrix);
|
||||
static const DlMatrixColorFilter kTestMatrixColorFilter2(kInvertColorMatrix);
|
||||
static const DlBlurImageFilter kTestBlurImageFilter1(5.0,
|
||||
5.0,
|
||||
DlTileMode::kClamp);
|
||||
static const DlBlurImageFilter kTestBlurImageFilter2(6.0,
|
||||
5.0,
|
||||
DlTileMode::kClamp);
|
||||
static const DlBlurImageFilter kTestBlurImageFilter3(5.0,
|
||||
6.0,
|
||||
DlTileMode::kClamp);
|
||||
static const DlBlurImageFilter kTestBlurImageFilter4(5.0,
|
||||
5.0,
|
||||
DlTileMode::kDecal);
|
||||
static const DlDilateImageFilter kTestDilateImageFilter1(5.0, 5.0);
|
||||
static const DlDilateImageFilter kTestDilateImageFilter2(6.0, 5.0);
|
||||
static const DlDilateImageFilter kTestDilateImageFilter3(5.0, 6.0);
|
||||
static const DlErodeImageFilter kTestErodeImageFilter1(5.0, 5.0);
|
||||
static const DlErodeImageFilter kTestErodeImageFilter2(6.0, 5.0);
|
||||
static const DlErodeImageFilter kTestErodeImageFilter3(5.0, 6.0);
|
||||
static const DlMatrixImageFilter kTestMatrixImageFilter1(
|
||||
SkMatrix::RotateDeg(45),
|
||||
kNearestSampling);
|
||||
static const DlMatrixImageFilter kTestMatrixImageFilter2(
|
||||
SkMatrix::RotateDeg(85),
|
||||
kNearestSampling);
|
||||
static const DlMatrixImageFilter kTestMatrixImageFilter3(
|
||||
SkMatrix::RotateDeg(45),
|
||||
kLinearSampling);
|
||||
static const DlComposeImageFilter kTestComposeImageFilter1(
|
||||
kTestBlurImageFilter1,
|
||||
kTestMatrixImageFilter1);
|
||||
static const DlComposeImageFilter kTestComposeImageFilter2(
|
||||
kTestBlurImageFilter2,
|
||||
kTestMatrixImageFilter1);
|
||||
static const DlComposeImageFilter kTestComposeImageFilter3(
|
||||
kTestBlurImageFilter1,
|
||||
kTestMatrixImageFilter2);
|
||||
static const DlColorFilterImageFilter kTestCFImageFilter1(
|
||||
kTestBlendColorFilter1);
|
||||
static const DlColorFilterImageFilter kTestCFImageFilter2(
|
||||
kTestBlendColorFilter2);
|
||||
static const std::shared_ptr<DlPathEffect> kTestPathEffect1 =
|
||||
DlDashPathEffect::Make(kTestDashes1, 2, 0.0f);
|
||||
static const std::shared_ptr<DlPathEffect> kTestPathEffect2 =
|
||||
DlDashPathEffect::Make(kTestDashes2, 2, 0.0f);
|
||||
static const DlBlurMaskFilter kTestMaskFilter1(kNormal_SkBlurStyle, 3.0);
|
||||
static const DlBlurMaskFilter kTestMaskFilter2(kNormal_SkBlurStyle, 5.0);
|
||||
static const DlBlurMaskFilter kTestMaskFilter3(kSolid_SkBlurStyle, 3.0);
|
||||
static const DlBlurMaskFilter kTestMaskFilter4(kInner_SkBlurStyle, 3.0);
|
||||
static const DlBlurMaskFilter kTestMaskFilter5(kOuter_SkBlurStyle, 3.0);
|
||||
constexpr SkRect kTestBounds = SkRect::MakeLTRB(10, 10, 50, 60);
|
||||
static const SkRRect kTestRRect = SkRRect::MakeRectXY(kTestBounds, 5, 5);
|
||||
static const SkRRect kTestRRectRect = SkRRect::MakeRect(kTestBounds);
|
||||
static const SkRRect kTestInnerRRect =
|
||||
SkRRect::MakeRectXY(kTestBounds.makeInset(5, 5), 2, 2);
|
||||
static const SkPath kTestPathRect = SkPath::Rect(kTestBounds);
|
||||
static const SkPath kTestPathOval = SkPath::Oval(kTestBounds);
|
||||
static const SkPath kTestPath1 =
|
||||
SkPath::Polygon({{0, 0}, {10, 10}, {10, 0}, {0, 10}}, true);
|
||||
static const SkPath kTestPath2 =
|
||||
SkPath::Polygon({{0, 0}, {10, 10}, {0, 10}, {10, 0}}, true);
|
||||
static const SkPath kTestPath3 =
|
||||
SkPath::Polygon({{0, 0}, {10, 10}, {10, 0}, {0, 10}}, false);
|
||||
static const SkMatrix kTestMatrix1 = SkMatrix::Scale(2, 2);
|
||||
static const SkMatrix kTestMatrix2 = SkMatrix::RotateDeg(45);
|
||||
|
||||
static std::shared_ptr<const DlVertices> TestVertices1 =
|
||||
DlVertices::Make(DlVertexMode::kTriangles, //
|
||||
3,
|
||||
TestPoints,
|
||||
nullptr,
|
||||
kColors);
|
||||
static std::shared_ptr<const DlVertices> TestVertices2 =
|
||||
DlVertices::Make(DlVertexMode::kTriangleFan, //
|
||||
3,
|
||||
TestPoints,
|
||||
nullptr,
|
||||
kColors);
|
||||
|
||||
static constexpr int kTestDivs1[] = {10, 20, 30};
|
||||
static constexpr int kTestDivs2[] = {15, 20, 25};
|
||||
static constexpr int kTestDivs3[] = {15, 25};
|
||||
static constexpr SkCanvas::Lattice::RectType kTestRTypes[] = {
|
||||
SkCanvas::Lattice::RectType::kDefault,
|
||||
SkCanvas::Lattice::RectType::kTransparent,
|
||||
SkCanvas::Lattice::RectType::kFixedColor,
|
||||
SkCanvas::Lattice::RectType::kDefault,
|
||||
SkCanvas::Lattice::RectType::kTransparent,
|
||||
SkCanvas::Lattice::RectType::kFixedColor,
|
||||
SkCanvas::Lattice::RectType::kDefault,
|
||||
SkCanvas::Lattice::RectType::kTransparent,
|
||||
SkCanvas::Lattice::RectType::kFixedColor,
|
||||
};
|
||||
static constexpr SkColor kTestLatticeColors[] = {
|
||||
SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW,
|
||||
SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW,
|
||||
SK_ColorBLUE, SK_ColorGREEN, SK_ColorYELLOW,
|
||||
};
|
||||
static constexpr SkIRect kTestLatticeSrcRect = {1, 1, 39, 39};
|
||||
|
||||
static sk_sp<SkPicture> MakeTestPicture(int w, int h, SkColor color) {
|
||||
SkPictureRecorder recorder;
|
||||
SkRTreeFactory rtree_factory;
|
||||
SkCanvas* cv = recorder.beginRecording(kTestBounds, &rtree_factory);
|
||||
SkPaint paint;
|
||||
paint.setColor(color);
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
cv->drawRect(SkRect::MakeWH(w, h), paint);
|
||||
return recorder.finishRecordingAsPicture();
|
||||
}
|
||||
static sk_sp<SkPicture> TestPicture1 = MakeTestPicture(20, 20, SK_ColorGREEN);
|
||||
static sk_sp<SkPicture> TestPicture2 = MakeTestPicture(25, 25, SK_ColorBLUE);
|
||||
|
||||
static sk_sp<DisplayList> MakeTestDisplayList(int w, int h, SkColor color) {
|
||||
DisplayListBuilder builder;
|
||||
builder.setColor(color);
|
||||
builder.drawRect(SkRect::MakeWH(w, h));
|
||||
return builder.Build();
|
||||
}
|
||||
static sk_sp<DisplayList> TestDisplayList1 =
|
||||
MakeTestDisplayList(20, 20, SK_ColorGREEN);
|
||||
static sk_sp<DisplayList> TestDisplayList2 =
|
||||
MakeTestDisplayList(25, 25, SK_ColorBLUE);
|
||||
|
||||
static sk_sp<SkTextBlob> MakeTextBlob(std::string string) {
|
||||
return SkTextBlob::MakeFromText(string.c_str(), string.size(), SkFont(),
|
||||
SkTextEncoding::kUTF8);
|
||||
}
|
||||
static sk_sp<SkTextBlob> TestBlob1 = MakeTextBlob("TestBlob1");
|
||||
static sk_sp<SkTextBlob> TestBlob2 = MakeTextBlob("TestBlob2");
|
||||
|
||||
// ---------------
|
||||
// Test Suite data
|
||||
// ---------------
|
||||
|
||||
typedef const std::function<void(DisplayListBuilder&)> DlInvoker;
|
||||
|
||||
struct DisplayListInvocation {
|
||||
unsigned int op_count_;
|
||||
size_t byte_count_;
|
||||
|
||||
// in some cases, running the sequence through an SkCanvas will result
|
||||
// in fewer ops/bytes. Attribute invocations are recorded in an SkPaint
|
||||
// and not forwarded on, and SkCanvas culls unused save/restore/transforms.
|
||||
int sk_op_count_;
|
||||
size_t sk_byte_count_;
|
||||
|
||||
DlInvoker invoker;
|
||||
bool supports_group_opacity_ = false;
|
||||
|
||||
bool sk_version_matches() {
|
||||
return (static_cast<int>(op_count_) == sk_op_count_ &&
|
||||
byte_count_ == sk_byte_count_);
|
||||
}
|
||||
|
||||
// A negative sk_op_count means "do not test this op".
|
||||
// Used mainly for these cases:
|
||||
// - we cannot encode a DrawShadowRec (Skia private header)
|
||||
// - SkCanvas cannot receive a DisplayList
|
||||
// - SkCanvas may or may not inline an SkPicture
|
||||
bool sk_testing_invalid() { return sk_op_count_ < 0; }
|
||||
|
||||
bool is_empty() { return byte_count_ == 0; }
|
||||
|
||||
bool supports_group_opacity() { return supports_group_opacity_; }
|
||||
|
||||
unsigned int op_count() { return op_count_; }
|
||||
// byte count for the individual ops, no DisplayList overhead
|
||||
size_t raw_byte_count() { return byte_count_; }
|
||||
// byte count for the ops with DisplayList overhead, comparable
|
||||
// to |DisplayList.byte_count().
|
||||
size_t byte_count() { return sizeof(DisplayList) + byte_count_; }
|
||||
|
||||
int sk_op_count() { return sk_op_count_; }
|
||||
// byte count for the ops with DisplayList overhead as translated
|
||||
// through an SkCanvas interface, comparable to |DisplayList.byte_count().
|
||||
size_t sk_byte_count() { return sizeof(DisplayList) + sk_byte_count_; }
|
||||
|
||||
sk_sp<DisplayList> Build() {
|
||||
DisplayListBuilder builder;
|
||||
invoker(builder);
|
||||
return builder.Build();
|
||||
}
|
||||
};
|
||||
|
||||
struct DisplayListInvocationGroup {
|
||||
std::string op_name;
|
||||
std::vector<DisplayListInvocation> variants;
|
||||
};
|
||||
|
||||
std::vector<DisplayListInvocationGroup> allGroups = {
|
||||
{ "SetAntiAlias", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setAntiAlias(true);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setAntiAlias(false);}},
|
||||
}
|
||||
},
|
||||
{ "SetDither", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setDither(true);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setDither(false);}},
|
||||
}
|
||||
},
|
||||
{ "SetInvertColors", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setInvertColors(true);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setInvertColors(false);}},
|
||||
}
|
||||
},
|
||||
{ "SetStrokeCap", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStrokeCap(DlStrokeCap::kRound);}},
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStrokeCap(DlStrokeCap::kSquare);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setStrokeCap(DlStrokeCap::kButt);}},
|
||||
}
|
||||
},
|
||||
{ "SetStrokeJoin", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStrokeJoin(DlStrokeJoin::kBevel);}},
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStrokeJoin(DlStrokeJoin::kRound);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setStrokeJoin(DlStrokeJoin::kMiter);}},
|
||||
}
|
||||
},
|
||||
{ "SetStyle", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStyle(DlDrawStyle::kStroke);}},
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStyle(DlDrawStyle::kStrokeAndFill);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setStyle(DlDrawStyle::kFill);}},
|
||||
}
|
||||
},
|
||||
{ "SetStrokeWidth", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStrokeWidth(1.0);}},
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStrokeWidth(5.0);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setStrokeWidth(0.0);}},
|
||||
}
|
||||
},
|
||||
{ "SetStrokeMiter", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStrokeMiter(0.0);}},
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setStrokeMiter(5.0);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setStrokeMiter(4.0);}},
|
||||
}
|
||||
},
|
||||
{ "SetColor", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setColor(SK_ColorGREEN);}},
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setColor(SK_ColorBLUE);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setColor(SK_ColorBLACK);}},
|
||||
}
|
||||
},
|
||||
{ "SetBlendModeOrBlender", {
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setBlendMode(DlBlendMode::kSrcIn);}},
|
||||
{0, 8, 0, 0, [](DisplayListBuilder& b) {b.setBlendMode(DlBlendMode::kDstIn);}},
|
||||
{0, 16, 0, 0, [](DisplayListBuilder& b) {b.setBlender(kTestBlender1);}},
|
||||
{0, 16, 0, 0, [](DisplayListBuilder& b) {b.setBlender(kTestBlender2);}},
|
||||
{0, 16, 0, 0, [](DisplayListBuilder& b) {b.setBlender(kTestBlender3);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setBlendMode(DlBlendMode::kSrcOver);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setBlender(nullptr);}},
|
||||
}
|
||||
},
|
||||
{ "SetColorSource", {
|
||||
{0, 96, 0, 0, [](DisplayListBuilder& b) {b.setColorSource(&kTestSource1);}},
|
||||
// stop_count * (sizeof(float) + sizeof(uint32_t)) = 80
|
||||
{0, 80 + 6 * 4, 0, 0, [](DisplayListBuilder& b) {b.setColorSource(kTestSource2.get());}},
|
||||
{0, 80 + 6 * 4, 0, 0, [](DisplayListBuilder& b) {b.setColorSource(kTestSource3.get());}},
|
||||
{0, 88 + 6 * 4, 0, 0, [](DisplayListBuilder& b) {b.setColorSource(kTestSource4.get());}},
|
||||
{0, 80 + 6 * 4, 0, 0, [](DisplayListBuilder& b) {b.setColorSource(kTestSource5.get());}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setColorSource(nullptr);}},
|
||||
}
|
||||
},
|
||||
{ "SetImageFilter", {
|
||||
{0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestBlurImageFilter1);}},
|
||||
{0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestBlurImageFilter2);}},
|
||||
{0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestBlurImageFilter3);}},
|
||||
{0, 32, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestBlurImageFilter4);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestDilateImageFilter1);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestDilateImageFilter2);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestDilateImageFilter3);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestErodeImageFilter1);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestErodeImageFilter2);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestErodeImageFilter3);}},
|
||||
{0, 64, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestMatrixImageFilter1);}},
|
||||
{0, 64, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestMatrixImageFilter2);}},
|
||||
{0, 64, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestMatrixImageFilter3);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestComposeImageFilter1);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestComposeImageFilter2);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestComposeImageFilter3);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestCFImageFilter1);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(&kTestCFImageFilter2);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setImageFilter(nullptr);}},
|
||||
}
|
||||
},
|
||||
{ "SetColorFilter", {
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setColorFilter(&kTestBlendColorFilter1);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setColorFilter(&kTestBlendColorFilter2);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setColorFilter(&kTestBlendColorFilter3);}},
|
||||
{0, 96, 0, 0, [](DisplayListBuilder& b) {b.setColorFilter(&kTestMatrixColorFilter1);}},
|
||||
{0, 96, 0, 0, [](DisplayListBuilder& b) {b.setColorFilter(&kTestMatrixColorFilter2);}},
|
||||
{0, 16, 0, 0, [](DisplayListBuilder& b) {b.setColorFilter(DlSrgbToLinearGammaColorFilter::instance.get());}},
|
||||
{0, 16, 0, 0, [](DisplayListBuilder& b) {b.setColorFilter(DlLinearToSrgbGammaColorFilter::instance.get());}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setColorFilter(nullptr);}},
|
||||
}
|
||||
},
|
||||
{ "SetPathEffect", {
|
||||
// sizeof(DlDashPathEffect) + 2 * sizeof(SkScalar)
|
||||
{0, 32, 0, 0, [](DisplayListBuilder& b) {b.setPathEffect(kTestPathEffect1.get());}},
|
||||
{0, 32, 0, 0, [](DisplayListBuilder& b) {b.setPathEffect(kTestPathEffect2.get());}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setPathEffect(nullptr);}},
|
||||
}
|
||||
},
|
||||
{ "SetMaskFilter", {
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setMaskFilter(&kTestMaskFilter1);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setMaskFilter(&kTestMaskFilter2);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setMaskFilter(&kTestMaskFilter3);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setMaskFilter(&kTestMaskFilter4);}},
|
||||
{0, 24, 0, 0, [](DisplayListBuilder& b) {b.setMaskFilter(&kTestMaskFilter5);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.setMaskFilter(nullptr);}},
|
||||
}
|
||||
},
|
||||
{ "Save(Layer)+Restore", {
|
||||
{5, 104, 5, 104, [](DisplayListBuilder& b) {
|
||||
b.saveLayer(nullptr, SaveLayerOptions::kNoAttributes, &kTestCFImageFilter1);
|
||||
b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
b.drawRect({5, 5, 15, 15});
|
||||
b.drawRect({10, 10, 20, 20});
|
||||
b.restore();
|
||||
}},
|
||||
// There are many reasons that save and restore can elide content, including
|
||||
// whether or not there are any draw operations between them, whether or not
|
||||
// there are any state changes to restore, and whether group rendering (opacity)
|
||||
// optimizations can allow attributes to be distributed to the children.
|
||||
// To prevent those cases we include at least one clip operation and 2 overlapping
|
||||
// rendering primitives between each save/restore pair.
|
||||
{5, 88, 5, 88, [](DisplayListBuilder& b) {
|
||||
b.save();
|
||||
b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
b.drawRect({5, 5, 15, 15});
|
||||
b.drawRect({10, 10, 20, 20});
|
||||
b.restore();
|
||||
}},
|
||||
{5, 88, 5, 88, [](DisplayListBuilder& b) {
|
||||
b.saveLayer(nullptr, false);
|
||||
b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
b.drawRect({5, 5, 15, 15});
|
||||
b.drawRect({10, 10, 20, 20});
|
||||
b.restore();
|
||||
}},
|
||||
{5, 88, 5, 88, [](DisplayListBuilder& b) {
|
||||
b.saveLayer(nullptr, true);
|
||||
b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
b.drawRect({5, 5, 15, 15});
|
||||
b.drawRect({10, 10, 20, 20});
|
||||
b.restore();
|
||||
}},
|
||||
{5, 104, 5, 104, [](DisplayListBuilder& b) {
|
||||
b.saveLayer(&kTestBounds, false);
|
||||
b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
b.drawRect({5, 5, 15, 15});
|
||||
b.drawRect({10, 10, 20, 20});
|
||||
b.restore();
|
||||
}},
|
||||
{5, 104, 5, 104, [](DisplayListBuilder& b) {
|
||||
b.saveLayer(&kTestBounds, true);
|
||||
b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
b.drawRect({5, 5, 15, 15});
|
||||
b.drawRect({10, 10, 20, 20});
|
||||
b.restore();
|
||||
}},
|
||||
// backdrop variants - using the TestCFImageFilter because it can be
|
||||
// reconstituted in the DL->SkCanvas->DL stream
|
||||
// {5, 104, 5, 104, [](DisplayListBuilder& b) {
|
||||
// b.saveLayer(nullptr, SaveLayerOptions::kNoAttributes, &kTestCFImageFilter1);
|
||||
// b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
// b.drawRect({5, 5, 15, 15});
|
||||
// b.drawRect({10, 10, 20, 20});
|
||||
// b.restore();
|
||||
// }},
|
||||
{5, 104, 5, 104, [](DisplayListBuilder& b) {
|
||||
b.saveLayer(nullptr, SaveLayerOptions::kWithAttributes, &kTestCFImageFilter1);
|
||||
b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
b.drawRect({5, 5, 15, 15});
|
||||
b.drawRect({10, 10, 20, 20});
|
||||
b.restore();
|
||||
}},
|
||||
{5, 120, 5, 120, [](DisplayListBuilder& b) {
|
||||
b.saveLayer(&kTestBounds, SaveLayerOptions::kNoAttributes, &kTestCFImageFilter1);
|
||||
b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
b.drawRect({5, 5, 15, 15});
|
||||
b.drawRect({10, 10, 20, 20});
|
||||
b.restore();
|
||||
}},
|
||||
{5, 120, 5, 120, [](DisplayListBuilder& b) {
|
||||
b.saveLayer(&kTestBounds, SaveLayerOptions::kWithAttributes, &kTestCFImageFilter1);
|
||||
b.clipRect({0, 0, 25, 25}, SkClipOp::kIntersect, true);
|
||||
b.drawRect({5, 5, 15, 15});
|
||||
b.drawRect({10, 10, 20, 20});
|
||||
b.restore();
|
||||
}},
|
||||
}
|
||||
},
|
||||
{ "Translate", {
|
||||
// cv.translate(0, 0) is ignored
|
||||
{1, 16, 1, 16, [](DisplayListBuilder& b) {b.translate(10, 10);}},
|
||||
{1, 16, 1, 16, [](DisplayListBuilder& b) {b.translate(10, 15);}},
|
||||
{1, 16, 1, 16, [](DisplayListBuilder& b) {b.translate(15, 10);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.translate(0, 0);}},
|
||||
}
|
||||
},
|
||||
{ "Scale", {
|
||||
// cv.scale(1, 1) is ignored
|
||||
{1, 16, 1, 16, [](DisplayListBuilder& b) {b.scale(2, 2);}},
|
||||
{1, 16, 1, 16, [](DisplayListBuilder& b) {b.scale(2, 3);}},
|
||||
{1, 16, 1, 16, [](DisplayListBuilder& b) {b.scale(3, 2);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.scale(1, 1);}},
|
||||
}
|
||||
},
|
||||
{ "Rotate", {
|
||||
// cv.rotate(0) is ignored, otherwise expressed as concat(rotmatrix)
|
||||
{1, 8, 1, 32, [](DisplayListBuilder& b) {b.rotate(30);}},
|
||||
{1, 8, 1, 32, [](DisplayListBuilder& b) {b.rotate(45);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.rotate(0);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.rotate(360);}},
|
||||
}
|
||||
},
|
||||
{ "Skew", {
|
||||
// cv.skew(0, 0) is ignored, otherwise expressed as concat(skewmatrix)
|
||||
{1, 16, 1, 32, [](DisplayListBuilder& b) {b.skew(0.1, 0.1);}},
|
||||
{1, 16, 1, 32, [](DisplayListBuilder& b) {b.skew(0.1, 0.2);}},
|
||||
{1, 16, 1, 32, [](DisplayListBuilder& b) {b.skew(0.2, 0.1);}},
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.skew(0, 0);}},
|
||||
}
|
||||
},
|
||||
{ "Transform2DAffine", {
|
||||
{1, 32, 1, 32, [](DisplayListBuilder& b) {b.transform2DAffine(0, 1, 12, 1, 0, 33);}},
|
||||
// b.transform(identity) is ignored
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.transform2DAffine(1, 0, 0, 0, 1, 0);}},
|
||||
}
|
||||
},
|
||||
{ "TransformFullPerspective", {
|
||||
{1, 72, 1, 72, [](DisplayListBuilder& b) {b.transformFullPerspective(0, 1, 0, 12,
|
||||
1, 0, 0, 33,
|
||||
3, 2, 5, 29,
|
||||
0, 0, 0, 12);}},
|
||||
// b.transform(2D affine) is reduced to 2x3
|
||||
{1, 32, 1, 32, [](DisplayListBuilder& b) {b.transformFullPerspective(2, 1, 0, 4,
|
||||
1, 3, 0, 5,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);}},
|
||||
// b.transform(identity) is ignored
|
||||
{0, 0, 0, 0, [](DisplayListBuilder& b) {b.transformFullPerspective(1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);}},
|
||||
}
|
||||
},
|
||||
{ "ClipRect", {
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipRect(kTestBounds, SkClipOp::kIntersect, true);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipRect(kTestBounds.makeOffset(1, 1),
|
||||
SkClipOp::kIntersect, true);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipRect(kTestBounds, SkClipOp::kIntersect, false);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipRect(kTestBounds, SkClipOp::kDifference, true);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipRect(kTestBounds, SkClipOp::kDifference, false);}},
|
||||
}
|
||||
},
|
||||
{ "ClipRRect", {
|
||||
{1, 64, 1, 64, [](DisplayListBuilder& b) {b.clipRRect(kTestRRect, SkClipOp::kIntersect, true);}},
|
||||
{1, 64, 1, 64, [](DisplayListBuilder& b) {b.clipRRect(kTestRRect.makeOffset(1, 1),
|
||||
SkClipOp::kIntersect, true);}},
|
||||
{1, 64, 1, 64, [](DisplayListBuilder& b) {b.clipRRect(kTestRRect, SkClipOp::kIntersect, false);}},
|
||||
{1, 64, 1, 64, [](DisplayListBuilder& b) {b.clipRRect(kTestRRect, SkClipOp::kDifference, true);}},
|
||||
{1, 64, 1, 64, [](DisplayListBuilder& b) {b.clipRRect(kTestRRect, SkClipOp::kDifference, false);}},
|
||||
}
|
||||
},
|
||||
{ "ClipPath", {
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipPath(kTestPath1, SkClipOp::kIntersect, true);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipPath(kTestPath2, SkClipOp::kIntersect, true);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipPath(kTestPath3, SkClipOp::kIntersect, true);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipPath(kTestPath1, SkClipOp::kIntersect, false);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipPath(kTestPath1, SkClipOp::kDifference, true);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipPath(kTestPath1, SkClipOp::kDifference, false);}},
|
||||
// clipPath(rect) becomes clipRect
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.clipPath(kTestPathRect, SkClipOp::kIntersect, true);}},
|
||||
// clipPath(oval) becomes clipRRect
|
||||
{1, 64, 1, 64, [](DisplayListBuilder& b) {b.clipPath(kTestPathOval, SkClipOp::kIntersect, true);}},
|
||||
}
|
||||
},
|
||||
{ "DrawPaint", {
|
||||
{1, 8, 1, 8, [](DisplayListBuilder& b) {b.drawPaint();}},
|
||||
}
|
||||
},
|
||||
{ "DrawColor", {
|
||||
// cv.drawColor becomes cv.drawPaint(paint)
|
||||
{1, 16, 1, 24, [](DisplayListBuilder& b) {b.drawColor(SK_ColorBLUE, DlBlendMode::kSrcIn);}},
|
||||
{1, 16, 1, 24, [](DisplayListBuilder& b) {b.drawColor(SK_ColorBLUE, DlBlendMode::kDstIn);}},
|
||||
{1, 16, 1, 24, [](DisplayListBuilder& b) {b.drawColor(SK_ColorCYAN, DlBlendMode::kSrcIn);}},
|
||||
}
|
||||
},
|
||||
{ "DrawLine", {
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawLine({0, 0}, {10, 10});}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawLine({0, 1}, {10, 10});}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawLine({0, 0}, {20, 10});}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawLine({0, 0}, {10, 20});}},
|
||||
}
|
||||
},
|
||||
{ "DrawRect", {
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawRect({0, 0, 10, 10});}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawRect({0, 1, 10, 10});}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawRect({0, 0, 20, 10});}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawRect({0, 0, 10, 20});}},
|
||||
}
|
||||
},
|
||||
{ "DrawOval", {
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawOval({0, 0, 10, 10});}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawOval({0, 1, 10, 10});}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawOval({0, 0, 20, 10});}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawOval({0, 0, 10, 20});}},
|
||||
}
|
||||
},
|
||||
{ "DrawCircle", {
|
||||
// cv.drawCircle becomes cv.drawOval
|
||||
{1, 16, 1, 24, [](DisplayListBuilder& b) {b.drawCircle({0, 0}, 10);}},
|
||||
{1, 16, 1, 24, [](DisplayListBuilder& b) {b.drawCircle({0, 5}, 10);}},
|
||||
{1, 16, 1, 24, [](DisplayListBuilder& b) {b.drawCircle({0, 0}, 20);}},
|
||||
}
|
||||
},
|
||||
{ "DrawRRect", {
|
||||
{1, 56, 1, 56, [](DisplayListBuilder& b) {b.drawRRect(kTestRRect);}},
|
||||
{1, 56, 1, 56, [](DisplayListBuilder& b) {b.drawRRect(kTestRRect.makeOffset(5, 5));}},
|
||||
}
|
||||
},
|
||||
{ "DrawDRRect", {
|
||||
{1, 112, 1, 112, [](DisplayListBuilder& b) {b.drawDRRect(kTestRRect, kTestInnerRRect);}},
|
||||
{1, 112, 1, 112, [](DisplayListBuilder& b) {b.drawDRRect(kTestRRect.makeOffset(5, 5),
|
||||
kTestInnerRRect.makeOffset(4, 4));}},
|
||||
}
|
||||
},
|
||||
{ "DrawPath", {
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawPath(kTestPath1);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawPath(kTestPath2);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawPath(kTestPath3);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawPath(kTestPathRect);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawPath(kTestPathOval);}},
|
||||
}
|
||||
},
|
||||
{ "DrawArc", {
|
||||
{1, 32, 1, 32, [](DisplayListBuilder& b) {b.drawArc(kTestBounds, 45, 270, false);}},
|
||||
{1, 32, 1, 32, [](DisplayListBuilder& b) {b.drawArc(kTestBounds.makeOffset(1, 1),
|
||||
45, 270, false);}},
|
||||
{1, 32, 1, 32, [](DisplayListBuilder& b) {b.drawArc(kTestBounds, 30, 270, false);}},
|
||||
{1, 32, 1, 32, [](DisplayListBuilder& b) {b.drawArc(kTestBounds, 45, 260, false);}},
|
||||
{1, 32, 1, 32, [](DisplayListBuilder& b) {b.drawArc(kTestBounds, 45, 270, true);}},
|
||||
}
|
||||
},
|
||||
{ "DrawPoints", {
|
||||
{1, 8 + TestPointCount * 8, 1, 8 + TestPointCount * 8,
|
||||
[](DisplayListBuilder& b) {b.drawPoints(SkCanvas::kPoints_PointMode,
|
||||
TestPointCount,
|
||||
TestPoints);}},
|
||||
{1, 8 + (TestPointCount - 1) * 8, 1, 8 + (TestPointCount - 1) * 8,
|
||||
[](DisplayListBuilder& b) {b.drawPoints(SkCanvas::kPoints_PointMode,
|
||||
TestPointCount - 1,
|
||||
TestPoints);}},
|
||||
{1, 8 + TestPointCount * 8, 1, 8 + TestPointCount * 8,
|
||||
[](DisplayListBuilder& b) {b.drawPoints(SkCanvas::kLines_PointMode,
|
||||
TestPointCount,
|
||||
TestPoints);}},
|
||||
{1, 8 + TestPointCount * 8, 1, 8 + TestPointCount * 8,
|
||||
[](DisplayListBuilder& b) {b.drawPoints(SkCanvas::kPolygon_PointMode,
|
||||
TestPointCount,
|
||||
TestPoints);}},
|
||||
}
|
||||
},
|
||||
{ "DrawVertices", {
|
||||
{1, 112, 1, 16, [](DisplayListBuilder& b) {b.drawVertices(TestVertices1, DlBlendMode::kSrcIn);}},
|
||||
{1, 112, 1, 16, [](DisplayListBuilder& b) {b.drawVertices(TestVertices1, DlBlendMode::kDstIn);}},
|
||||
{1, 112, 1, 16, [](DisplayListBuilder& b) {b.drawVertices(TestVertices2, DlBlendMode::kSrcIn);}},
|
||||
}
|
||||
},
|
||||
{ "DrawImage", {
|
||||
{1, 24, -1, 48, [](DisplayListBuilder& b) {b.drawImage(TestImage1, {10, 10}, kNearestSampling, false);}},
|
||||
{1, 24, -1, 48, [](DisplayListBuilder& b) {b.drawImage(TestImage1, {10, 10}, kNearestSampling, true);}},
|
||||
{1, 24, -1, 48, [](DisplayListBuilder& b) {b.drawImage(TestImage1, {20, 10}, kNearestSampling, false);}},
|
||||
{1, 24, -1, 48, [](DisplayListBuilder& b) {b.drawImage(TestImage1, {10, 20}, kNearestSampling, false);}},
|
||||
{1, 24, -1, 48, [](DisplayListBuilder& b) {b.drawImage(TestImage1, {10, 10}, kLinearSampling, false);}},
|
||||
{1, 24, -1, 48, [](DisplayListBuilder& b) {b.drawImage(TestImage2, {10, 10}, kNearestSampling, false);}},
|
||||
}
|
||||
},
|
||||
{ "DrawImageRect", {
|
||||
{1, 56, -1, 80, [](DisplayListBuilder& b) {b.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
|
||||
kNearestSampling, false);}},
|
||||
{1, 56, -1, 80, [](DisplayListBuilder& b) {b.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
|
||||
kNearestSampling, true);}},
|
||||
{1, 56, -1, 80, [](DisplayListBuilder& b) {b.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
|
||||
kNearestSampling, false,
|
||||
SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint);}},
|
||||
{1, 56, -1, 80, [](DisplayListBuilder& b) {b.drawImageRect(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
|
||||
kNearestSampling, false);}},
|
||||
{1, 56, -1, 80, [](DisplayListBuilder& b) {b.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
|
||||
kNearestSampling, false);}},
|
||||
{1, 56, -1, 80, [](DisplayListBuilder& b) {b.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
|
||||
kLinearSampling, false);}},
|
||||
{1, 56, -1, 80, [](DisplayListBuilder& b) {b.drawImageRect(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
|
||||
kNearestSampling, false);}},
|
||||
}
|
||||
},
|
||||
{ "DrawImageNine", {
|
||||
// SkVanvas::drawImageNine is immediately converted to drawImageLattice
|
||||
{1, 48, -1, 80, [](DisplayListBuilder& b) {b.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
|
||||
DlFilterMode::kNearest, false);}},
|
||||
{1, 48, -1, 80, [](DisplayListBuilder& b) {b.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
|
||||
DlFilterMode::kNearest, true);}},
|
||||
{1, 48, -1, 80, [](DisplayListBuilder& b) {b.drawImageNine(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
|
||||
DlFilterMode::kNearest, false);}},
|
||||
{1, 48, -1, 80, [](DisplayListBuilder& b) {b.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
|
||||
DlFilterMode::kNearest, false);}},
|
||||
{1, 48, -1, 80, [](DisplayListBuilder& b) {b.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
|
||||
DlFilterMode::kLinear, false);}},
|
||||
{1, 48, -1, 80, [](DisplayListBuilder& b) {b.drawImageNine(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
|
||||
DlFilterMode::kNearest, false);}},
|
||||
}
|
||||
},
|
||||
{ "DrawImageLattice", {
|
||||
// Lattice:
|
||||
// const int* fXDivs; //!< x-axis values dividing bitmap
|
||||
// const int* fYDivs; //!< y-axis values dividing bitmap
|
||||
// const RectType* fRectTypes; //!< array of fill types
|
||||
// int fXCount; //!< number of x-coordinates
|
||||
// int fYCount; //!< number of y-coordinates
|
||||
// const SkIRect* fBounds; //!< source bounds to draw from
|
||||
// const SkColor* fColors; //!< array of colors
|
||||
// size = 64 + fXCount * 4 + fYCount * 4
|
||||
// if fColors and fRectTypes are not null, add (fXCount + 1) * (fYCount + 1) * 5
|
||||
{1, 88, -1, 88, [](DisplayListBuilder& b) {b.drawImageLattice(TestImage1,
|
||||
{kTestDivs1, kTestDivs1, nullptr, 3, 3, nullptr, nullptr},
|
||||
{10, 10, 40, 40}, DlFilterMode::kNearest, false);}},
|
||||
{1, 88, -1, 88, [](DisplayListBuilder& b) {b.drawImageLattice(TestImage1,
|
||||
{kTestDivs1, kTestDivs1, nullptr, 3, 3, nullptr, nullptr},
|
||||
{10, 10, 40, 45}, DlFilterMode::kNearest, false);}},
|
||||
{1, 88, -1, 88, [](DisplayListBuilder& b) {b.drawImageLattice(TestImage1,
|
||||
{kTestDivs2, kTestDivs1, nullptr, 3, 3, nullptr, nullptr},
|
||||
{10, 10, 40, 40}, DlFilterMode::kNearest, false);}},
|
||||
// One less yDiv does not change the allocation due to 8-byte alignment
|
||||
{1, 88, -1, 88, [](DisplayListBuilder& b) {b.drawImageLattice(TestImage1,
|
||||
{kTestDivs1, kTestDivs1, nullptr, 3, 2, nullptr, nullptr},
|
||||
{10, 10, 40, 40}, DlFilterMode::kNearest, false);}},
|
||||
{1, 88, -1, 88, [](DisplayListBuilder& b) {b.drawImageLattice(TestImage1,
|
||||
{kTestDivs1, kTestDivs1, nullptr, 3, 3, nullptr, nullptr},
|
||||
{10, 10, 40, 40}, DlFilterMode::kLinear, false);}},
|
||||
{1, 96, -1, 96, [](DisplayListBuilder& b) {b.setColor(SK_ColorMAGENTA);
|
||||
b.drawImageLattice(TestImage1,
|
||||
{kTestDivs1, kTestDivs1, nullptr, 3, 3, nullptr, nullptr},
|
||||
{10, 10, 40, 40}, DlFilterMode::kNearest, true);}},
|
||||
{1, 88, -1, 88, [](DisplayListBuilder& b) {b.drawImageLattice(TestImage2,
|
||||
{kTestDivs1, kTestDivs1, nullptr, 3, 3, nullptr, nullptr},
|
||||
{10, 10, 40, 40}, DlFilterMode::kNearest, false);}},
|
||||
// Supplying fBounds does not change size because the Op record always includes it
|
||||
{1, 88, -1, 88, [](DisplayListBuilder& b) {b.drawImageLattice(TestImage1,
|
||||
{kTestDivs1, kTestDivs1, nullptr, 3, 3, &kTestLatticeSrcRect, nullptr},
|
||||
{10, 10, 40, 40}, DlFilterMode::kNearest, false);}},
|
||||
{1, 128, -1, 128, [](DisplayListBuilder& b) {b.drawImageLattice(TestImage1,
|
||||
{kTestDivs3, kTestDivs3, kTestRTypes, 2, 2, nullptr, kTestLatticeColors},
|
||||
{10, 10, 40, 40}, DlFilterMode::kNearest, false);}},
|
||||
}
|
||||
},
|
||||
{ "DrawAtlas", {
|
||||
{1, 48 + 32 + 8, -1, 48 + 32 + 32, [](DisplayListBuilder& b) {
|
||||
static SkRSXform xforms[] = { {1, 0, 0, 0}, {0, 1, 0, 0} };
|
||||
static SkRect texs[] = { { 10, 10, 20, 20 }, {20, 20, 30, 30} };
|
||||
b.drawAtlas(TestImage1, xforms, texs, nullptr, 2, DlBlendMode::kSrcIn,
|
||||
kNearestSampling, nullptr, false);}},
|
||||
{1, 48 + 32 + 8, -1, 48 + 32 + 32, [](DisplayListBuilder& b) {
|
||||
static SkRSXform xforms[] = { {1, 0, 0, 0}, {0, 1, 0, 0} };
|
||||
static SkRect texs[] = { { 10, 10, 20, 20 }, {20, 20, 30, 30} };
|
||||
b.drawAtlas(TestImage1, xforms, texs, nullptr, 2, DlBlendMode::kSrcIn,
|
||||
kNearestSampling, nullptr, true);}},
|
||||
{1, 48 + 32 + 8, -1, 48 + 32 + 32, [](DisplayListBuilder& b) {
|
||||
static SkRSXform xforms[] = { {0, 1, 0, 0}, {0, 1, 0, 0} };
|
||||
static SkRect texs[] = { { 10, 10, 20, 20 }, {20, 20, 30, 30} };
|
||||
b.drawAtlas(TestImage1, xforms, texs, nullptr, 2, DlBlendMode::kSrcIn,
|
||||
kNearestSampling, nullptr, false);}},
|
||||
{1, 48 + 32 + 8, -1, 48 + 32 + 32, [](DisplayListBuilder& b) {
|
||||
static SkRSXform xforms[] = { {1, 0, 0, 0}, {0, 1, 0, 0} };
|
||||
static SkRect texs[] = { { 10, 10, 20, 20 }, {20, 25, 30, 30} };
|
||||
b.drawAtlas(TestImage1, xforms, texs, nullptr, 2, DlBlendMode::kSrcIn,
|
||||
kNearestSampling, nullptr, false);}},
|
||||
{1, 48 + 32 + 8, -1, 48 + 32 + 32, [](DisplayListBuilder& b) {
|
||||
static SkRSXform xforms[] = { {1, 0, 0, 0}, {0, 1, 0, 0} };
|
||||
static SkRect texs[] = { { 10, 10, 20, 20 }, {20, 20, 30, 30} };
|
||||
b.drawAtlas(TestImage1, xforms, texs, nullptr, 2, DlBlendMode::kSrcIn,
|
||||
kLinearSampling, nullptr, false);}},
|
||||
{1, 48 + 32 + 8, -1, 48 + 32 + 32, [](DisplayListBuilder& b) {
|
||||
static SkRSXform xforms[] = { {1, 0, 0, 0}, {0, 1, 0, 0} };
|
||||
static SkRect texs[] = { { 10, 10, 20, 20 }, {20, 20, 30, 30} };
|
||||
b.drawAtlas(TestImage1, xforms, texs, nullptr, 2, DlBlendMode::kDstIn,
|
||||
kNearestSampling, nullptr, false);}},
|
||||
{1, 64 + 32 + 8, -1, 64 + 32 + 32, [](DisplayListBuilder& b) {
|
||||
static SkRSXform xforms[] = { {1, 0, 0, 0}, {0, 1, 0, 0} };
|
||||
static SkRect texs[] = { { 10, 10, 20, 20 }, {20, 20, 30, 30} };
|
||||
static SkRect cullRect = { 0, 0, 200, 200 };
|
||||
b.drawAtlas(TestImage2, xforms, texs, nullptr, 2, DlBlendMode::kSrcIn,
|
||||
kNearestSampling, &cullRect, false);}},
|
||||
{1, 48 + 32 + 8 + 8, -1, 48 + 32 + 32 + 8, [](DisplayListBuilder& b) {
|
||||
static SkRSXform xforms[] = { {1, 0, 0, 0}, {0, 1, 0, 0} };
|
||||
static SkRect texs[] = { { 10, 10, 20, 20 }, {20, 20, 30, 30} };
|
||||
static DlColor colors[] = { DlColor::kBlue(), DlColor::kGreen() };
|
||||
b.drawAtlas(TestImage1, xforms, texs, colors, 2, DlBlendMode::kSrcIn,
|
||||
kNearestSampling, nullptr, false);}},
|
||||
{1, 64 + 32 + 8 + 8, -1, 64 + 32 + 32 + 8, [](DisplayListBuilder& b) {
|
||||
static SkRSXform xforms[] = { {1, 0, 0, 0}, {0, 1, 0, 0} };
|
||||
static SkRect texs[] = { { 10, 10, 20, 20 }, {20, 20, 30, 30} };
|
||||
static DlColor colors[] = { DlColor::kBlue(), DlColor::kGreen() };
|
||||
static SkRect cullRect = { 0, 0, 200, 200 };
|
||||
b.drawAtlas(TestImage1, xforms, texs, colors, 2, DlBlendMode::kSrcIn,
|
||||
kNearestSampling, &cullRect, false);}},
|
||||
}
|
||||
},
|
||||
{ "DrawPicture", {
|
||||
// cv.drawPicture cannot be compared as SkCanvas may inline it
|
||||
{1, 16, -1, 16, [](DisplayListBuilder& b) {b.drawPicture(TestPicture1, nullptr, false);}},
|
||||
{1, 16, -1, 16, [](DisplayListBuilder& b) {b.drawPicture(TestPicture2, nullptr, false);}},
|
||||
{1, 16, -1, 16, [](DisplayListBuilder& b) {b.drawPicture(TestPicture1, nullptr, true);}},
|
||||
{1, 56, -1, 56, [](DisplayListBuilder& b) {b.drawPicture(TestPicture1, &kTestMatrix1, false);}},
|
||||
{1, 56, -1, 56, [](DisplayListBuilder& b) {b.drawPicture(TestPicture1, &kTestMatrix2, false);}},
|
||||
{1, 56, -1, 56, [](DisplayListBuilder& b) {b.drawPicture(TestPicture1, &kTestMatrix1, true);}},
|
||||
}
|
||||
},
|
||||
{ "DrawDisplayList", {
|
||||
// cv.drawDL does not exist
|
||||
{1, 16, -1, 16, [](DisplayListBuilder& b) {b.drawDisplayList(TestDisplayList1);}},
|
||||
{1, 16, -1, 16, [](DisplayListBuilder& b) {b.drawDisplayList(TestDisplayList2);}},
|
||||
}
|
||||
},
|
||||
{ "DrawTextBlob", {
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawTextBlob(TestBlob1, 10, 10);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawTextBlob(TestBlob1, 20, 10);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawTextBlob(TestBlob1, 10, 20);}},
|
||||
{1, 24, 1, 24, [](DisplayListBuilder& b) {b.drawTextBlob(TestBlob2, 10, 10);}},
|
||||
}
|
||||
},
|
||||
// The -1 op counts below are to indicate to the framework not to test
|
||||
// SkCanvas conversion of these ops as it converts the operation into a
|
||||
// format that is not exposed publicly and so we cannot recapture the
|
||||
// operation.
|
||||
// See: https://bugs.chromium.org/p/skia/issues/detail?id=12125
|
||||
{ "DrawShadow", {
|
||||
// cv shadows are turned into an opaque ShadowRec which is not exposed
|
||||
{1, 32, -1, 32, [](DisplayListBuilder& b) {b.drawShadow(kTestPath1, SK_ColorGREEN, 1.0, false, 1.0);}},
|
||||
{1, 32, -1, 32, [](DisplayListBuilder& b) {b.drawShadow(kTestPath2, SK_ColorGREEN, 1.0, false, 1.0);}},
|
||||
{1, 32, -1, 32, [](DisplayListBuilder& b) {b.drawShadow(kTestPath1, SK_ColorBLUE, 1.0, false, 1.0);}},
|
||||
{1, 32, -1, 32, [](DisplayListBuilder& b) {b.drawShadow(kTestPath1, SK_ColorGREEN, 2.0, false, 1.0);}},
|
||||
{1, 32, -1, 32, [](DisplayListBuilder& b) {b.drawShadow(kTestPath1, SK_ColorGREEN, 1.0, true, 1.0);}},
|
||||
{1, 32, -1, 32, [](DisplayListBuilder& b) {b.drawShadow(kTestPath1, SK_ColorGREEN, 1.0, false, 2.5);}},
|
||||
}
|
||||
},
|
||||
};
|
||||
static std::vector<testing::DisplayListInvocationGroup> allGroups =
|
||||
CreateAllGroups();
|
||||
|
||||
TEST(DisplayList, SingleOpSizes) {
|
||||
for (auto& group : allGroups) {
|
||||
|
||||
@ -13,4 +13,5 @@ set -ex
|
||||
./fml_benchmarks --benchmark_format=json > fml_benchmarks.json
|
||||
./shell_benchmarks --benchmark_format=json > shell_benchmarks.json
|
||||
./ui_benchmarks --benchmark_format=json > ui_benchmarks.json
|
||||
./display_list_builder_benchmarks --benchmark_format=json > display_list_builder_benchmarks.json
|
||||
|
||||
|
||||
@ -440,6 +440,10 @@ def RunEngineBenchmarks(build_dir, filter):
|
||||
|
||||
RunEngineExecutable(build_dir, 'ui_benchmarks', filter, icu_flags)
|
||||
|
||||
RunEngineExecutable(
|
||||
build_dir, 'display_list_builder_benchmarks', filter, icu_flags
|
||||
)
|
||||
|
||||
if IsLinux():
|
||||
RunEngineExecutable(build_dir, 'txt_benchmarks', filter, icu_flags)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user