blob: ffdbfee2043f2ff0aabee53b6542c4339663720c [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/display_list/testing/dl_test_snippets.h"
#include "flutter/display_list/dl_builder.h"
#include "flutter/display_list/dl_op_receiver.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "txt/platform.h"
namespace flutter {
namespace testing {
sk_sp<DisplayList> GetSampleDisplayList() {
DisplayListBuilder builder(SkRect::MakeWH(150, 100));
builder.DrawRect(SkRect::MakeXYWH(10, 10, 80, 80), DlPaint(DlColor::kRed()));
return builder.Build();
}
sk_sp<DisplayList> GetSampleNestedDisplayList() {
DisplayListBuilder builder(SkRect::MakeWH(150, 100));
DlPaint paint;
for (int y = 10; y <= 60; y += 10) {
for (int x = 10; x <= 60; x += 10) {
paint.setColor(((x + y) % 20) == 10 ? DlColor(SK_ColorRED)
: DlColor(SK_ColorBLUE));
builder.DrawRect(SkRect::MakeXYWH(x, y, 80, 80), paint);
}
}
DisplayListBuilder outer_builder(SkRect::MakeWH(150, 100));
outer_builder.DrawDisplayList(builder.Build());
return outer_builder.Build();
}
sk_sp<DisplayList> GetSampleDisplayList(int ops) {
DisplayListBuilder builder(SkRect::MakeWH(150, 100));
for (int i = 0; i < ops; i++) {
builder.DrawColor(DlColor::kRed(), DlBlendMode::kSrc);
}
return builder.Build();
}
// ---------------
// Test Suite data
// ---------------
std::vector<DisplayListInvocationGroup> CreateAllAttributesOps() {
return {
{"SetAntiAlias",
{
{0, 8, 0, [](DlOpReceiver& r) { r.setAntiAlias(true); }},
{0, 0, 0, [](DlOpReceiver& r) { r.setAntiAlias(false); }},
}},
{"SetInvertColors",
{
{0, 8, 0, [](DlOpReceiver& r) { r.setInvertColors(true); }},
{0, 0, 0, [](DlOpReceiver& r) { r.setInvertColors(false); }},
}},
{"SetStrokeCap",
{
{0, 8, 0,
[](DlOpReceiver& r) { r.setStrokeCap(DlStrokeCap::kRound); }},
{0, 8, 0,
[](DlOpReceiver& r) { r.setStrokeCap(DlStrokeCap::kSquare); }},
{0, 0, 0,
[](DlOpReceiver& r) { r.setStrokeCap(DlStrokeCap::kButt); }},
}},
{"SetStrokeJoin",
{
{0, 8, 0,
[](DlOpReceiver& r) { r.setStrokeJoin(DlStrokeJoin::kBevel); }},
{0, 8, 0,
[](DlOpReceiver& r) { r.setStrokeJoin(DlStrokeJoin::kRound); }},
{0, 0, 0,
[](DlOpReceiver& r) { r.setStrokeJoin(DlStrokeJoin::kMiter); }},
}},
{"SetStyle",
{
{0, 8, 0,
[](DlOpReceiver& r) { r.setDrawStyle(DlDrawStyle::kStroke); }},
{0, 8, 0,
[](DlOpReceiver& r) {
r.setDrawStyle(DlDrawStyle::kStrokeAndFill);
}},
{0, 0, 0,
[](DlOpReceiver& r) { r.setDrawStyle(DlDrawStyle::kFill); }},
}},
{"SetStrokeWidth",
{
{0, 8, 0, [](DlOpReceiver& r) { r.setStrokeWidth(1.0); }},
{0, 8, 0, [](DlOpReceiver& r) { r.setStrokeWidth(5.0); }},
{0, 0, 0, [](DlOpReceiver& r) { r.setStrokeWidth(0.0); }},
}},
{"SetStrokeMiter",
{
{0, 8, 0, [](DlOpReceiver& r) { r.setStrokeMiter(0.0); }},
{0, 8, 0, [](DlOpReceiver& r) { r.setStrokeMiter(5.0); }},
{0, 0, 0, [](DlOpReceiver& r) { r.setStrokeMiter(4.0); }},
}},
{"SetColor",
{
{0, 8, 0,
[](DlOpReceiver& r) { r.setColor(DlColor(SK_ColorGREEN)); }},
{0, 8, 0,
[](DlOpReceiver& r) { r.setColor(DlColor(SK_ColorBLUE)); }},
{0, 0, 0,
[](DlOpReceiver& r) { r.setColor(DlColor(SK_ColorBLACK)); }},
}},
{"SetBlendMode",
{
{0, 8, 0,
[](DlOpReceiver& r) { r.setBlendMode(DlBlendMode::kSrcIn); }},
{0, 8, 0,
[](DlOpReceiver& r) { r.setBlendMode(DlBlendMode::kDstIn); }},
{0, 0, 0,
[](DlOpReceiver& r) { r.setBlendMode(DlBlendMode::kSrcOver); }},
}},
{"SetColorSource",
{
{0, 96, 0, [](DlOpReceiver& r) { r.setColorSource(&kTestSource1); }},
// stop_count * (sizeof(float) + sizeof(uint32_t)) = 80
{0, 80 + 6 * 4, 0,
[](DlOpReceiver& r) { r.setColorSource(kTestSource2.get()); }},
{0, 80 + 6 * 4, 0,
[](DlOpReceiver& r) { r.setColorSource(kTestSource3.get()); }},
{0, 88 + 6 * 4, 0,
[](DlOpReceiver& r) { r.setColorSource(kTestSource4.get()); }},
{0, 80 + 6 * 4, 0,
[](DlOpReceiver& r) { r.setColorSource(kTestSource5.get()); }},
{0, 0, 0, [](DlOpReceiver& r) { r.setColorSource(nullptr); }},
}},
{"SetImageFilter",
{
{0, 32, 0,
[](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter1); }},
{0, 32, 0,
[](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter2); }},
{0, 32, 0,
[](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter3); }},
{0, 32, 0,
[](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter4); }},
{0, 24, 0,
[](DlOpReceiver& r) {
r.setImageFilter(&kTestDilateImageFilter1);
}},
{0, 24, 0,
[](DlOpReceiver& r) {
r.setImageFilter(&kTestDilateImageFilter2);
}},
{0, 24, 0,
[](DlOpReceiver& r) {
r.setImageFilter(&kTestDilateImageFilter3);
}},
{0, 24, 0,
[](DlOpReceiver& r) { r.setImageFilter(&kTestErodeImageFilter1); }},
{0, 24, 0,
[](DlOpReceiver& r) { r.setImageFilter(&kTestErodeImageFilter2); }},
{0, 24, 0,
[](DlOpReceiver& r) { r.setImageFilter(&kTestErodeImageFilter3); }},
{0, 64, 0,
[](DlOpReceiver& r) {
r.setImageFilter(&kTestMatrixImageFilter1);
}},
{0, 64, 0,
[](DlOpReceiver& r) {
r.setImageFilter(&kTestMatrixImageFilter2);
}},
{0, 64, 0,
[](DlOpReceiver& r) {
r.setImageFilter(&kTestMatrixImageFilter3);
}},
{0, 24, 0,
[](DlOpReceiver& r) {
r.setImageFilter(&kTestComposeImageFilter1);
}},
{0, 24, 0,
[](DlOpReceiver& r) {
r.setImageFilter(&kTestComposeImageFilter2);
}},
{0, 24, 0,
[](DlOpReceiver& r) {
r.setImageFilter(&kTestComposeImageFilter3);
}},
{0, 24, 0,
[](DlOpReceiver& r) { r.setImageFilter(&kTestCFImageFilter1); }},
{0, 24, 0,
[](DlOpReceiver& r) { r.setImageFilter(&kTestCFImageFilter2); }},
{0, 0, 0, [](DlOpReceiver& r) { r.setImageFilter(nullptr); }},
{0, 24, 0,
[](DlOpReceiver& r) {
r.setImageFilter(
kTestBlurImageFilter1
.makeWithLocalMatrix(SkMatrix::Translate(2, 2))
.get());
}},
}},
{"SetColorFilter",
{
{0, 24, 0,
[](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter1); }},
{0, 24, 0,
[](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter2); }},
{0, 24, 0,
[](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter3); }},
{0, 96, 0,
[](DlOpReceiver& r) {
r.setColorFilter(&kTestMatrixColorFilter1);
}},
{0, 96, 0,
[](DlOpReceiver& r) {
r.setColorFilter(&kTestMatrixColorFilter2);
}},
{0, 16, 0,
[](DlOpReceiver& r) {
r.setColorFilter(DlSrgbToLinearGammaColorFilter::kInstance.get());
}},
{0, 16, 0,
[](DlOpReceiver& r) {
r.setColorFilter(DlLinearToSrgbGammaColorFilter::kInstance.get());
}},
{0, 0, 0, [](DlOpReceiver& r) { r.setColorFilter(nullptr); }},
}},
{"SetPathEffect",
{
// sizeof(DlDashPathEffect) + 2 * sizeof(SkScalar)
{0, 32, 0,
[](DlOpReceiver& r) { r.setPathEffect(kTestPathEffect1.get()); }},
{0, 32, 0,
[](DlOpReceiver& r) { r.setPathEffect(kTestPathEffect2.get()); }},
{0, 0, 0, [](DlOpReceiver& r) { r.setPathEffect(nullptr); }},
}},
{"SetMaskFilter",
{
{0, 32, 0,
[](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter1); }, 0u,
2u},
{0, 32, 0,
[](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter2); }, 0u,
2u},
{0, 32, 0,
[](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter3); }, 0u,
2u},
{0, 32, 0,
[](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter4); }, 0u,
2u},
{0, 32, 0,
[](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter5); }, 0u,
2u},
{0, 0, 0, [](DlOpReceiver& r) { r.setMaskFilter(nullptr); }, 0u, 1u},
}},
};
}
std::vector<DisplayListInvocationGroup> CreateAllSaveRestoreOps() {
return {
{"Save(Layer)+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, 96, 2,
[](DlOpReceiver& r) {
r.save();
r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
r.drawRect({5, 5, 15, 15});
r.drawRect({10, 10, 20, 20});
r.restore();
}},
{5, 112, 3,
[](DlOpReceiver& r) {
r.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
r.drawRect({5, 5, 15, 15});
r.drawRect({10, 10, 20, 20});
r.restore();
}},
{5, 112, 3,
[](DlOpReceiver& r) {
r.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
r.drawRect({5, 5, 15, 15});
r.drawRect({10, 10, 20, 20});
r.restore();
}},
{5, 112, 3,
[](DlOpReceiver& r) {
r.saveLayer(&kTestBounds, SaveLayerOptions::kNoAttributes);
r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
r.drawRect({5, 5, 15, 15});
r.drawRect({10, 10, 20, 20});
r.restore();
}},
{5, 112, 3,
[](DlOpReceiver& r) {
r.saveLayer(&kTestBounds, SaveLayerOptions::kWithAttributes);
r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
r.drawRect({5, 5, 15, 15});
r.drawRect({10, 10, 20, 20});
r.restore();
}},
{5, 128, 3,
[](DlOpReceiver& r) {
r.saveLayer(nullptr, SaveLayerOptions::kNoAttributes,
&kTestCFImageFilter1);
r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
r.drawRect({5, 5, 15, 15});
r.drawRect({10, 10, 20, 20});
r.restore();
}},
{5, 128, 3,
[](DlOpReceiver& r) {
r.saveLayer(nullptr, SaveLayerOptions::kWithAttributes,
&kTestCFImageFilter1);
r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
r.drawRect({5, 5, 15, 15});
r.drawRect({10, 10, 20, 20});
r.restore();
}},
{5, 128, 3,
[](DlOpReceiver& r) {
r.saveLayer(&kTestBounds, SaveLayerOptions::kNoAttributes,
&kTestCFImageFilter1);
r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
r.drawRect({5, 5, 15, 15});
r.drawRect({10, 10, 20, 20});
r.restore();
}},
{5, 128, 3,
[](DlOpReceiver& r) {
r.saveLayer(&kTestBounds, SaveLayerOptions::kWithAttributes,
&kTestCFImageFilter1);
r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
r.drawRect({5, 5, 15, 15});
r.drawRect({10, 10, 20, 20});
r.restore();
}},
}},
};
}
std::vector<DisplayListInvocationGroup> CreateAllTransformOps() {
return {
{"Translate",
{
{1, 16, 0, [](DlOpReceiver& r) { r.translate(10, 10); }},
{1, 16, 0, [](DlOpReceiver& r) { r.translate(10, 15); }},
{1, 16, 0, [](DlOpReceiver& r) { r.translate(15, 10); }},
{0, 0, 0, [](DlOpReceiver& r) { r.translate(0, 0); }},
}},
{"Scale",
{
{1, 16, 0, [](DlOpReceiver& r) { r.scale(2, 2); }},
{1, 16, 0, [](DlOpReceiver& r) { r.scale(2, 3); }},
{1, 16, 0, [](DlOpReceiver& r) { r.scale(3, 2); }},
{0, 0, 0, [](DlOpReceiver& r) { r.scale(1, 1); }},
}},
{"Rotate",
{
{1, 8, 0, [](DlOpReceiver& r) { r.rotate(30); }},
{1, 8, 0, [](DlOpReceiver& r) { r.rotate(45); }},
{0, 0, 0, [](DlOpReceiver& r) { r.rotate(0); }},
{0, 0, 0, [](DlOpReceiver& r) { r.rotate(360); }},
}},
{"Skew",
{
{1, 16, 0, [](DlOpReceiver& r) { r.skew(0.1, 0.1); }},
{1, 16, 0, [](DlOpReceiver& r) { r.skew(0.1, 0.2); }},
{1, 16, 0, [](DlOpReceiver& r) { r.skew(0.2, 0.1); }},
{0, 0, 0, [](DlOpReceiver& r) { r.skew(0, 0); }},
}},
{"Transform2DAffine",
{
{1, 32, 0,
[](DlOpReceiver& r) { r.transform2DAffine(0, 1, 12, 1, 0, 33); }},
// r.transform(identity) is ignored
{0, 0, 0,
[](DlOpReceiver& r) { r.transform2DAffine(1, 0, 0, 0, 1, 0); }},
}},
{"TransformFullPerspective",
{
{1, 72, 0,
[](DlOpReceiver& r) {
r.transformFullPerspective(0, 1, 0, 12, 1, 0, 0, 33, 3, 2, 5, 29,
0, 0, 0, 12);
}},
// r.transform(2D affine) is reduced to 2x3
{1, 32, 0,
[](DlOpReceiver& r) {
r.transformFullPerspective(2, 1, 0, 4, 1, 3, 0, 5, 0, 0, 1, 0, 0,
0, 0, 1);
}},
// r.transform(identity) is ignored
{0, 0, 0,
[](DlOpReceiver& r) {
r.transformFullPerspective(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
0, 0, 1);
}},
}},
};
}
std::vector<DisplayListInvocationGroup> CreateAllClipOps() {
return {
{"ClipRect",
{
{1, 24, 0,
[](DlOpReceiver& r) {
r.clipRect(kTestBounds, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 24, 0,
[](DlOpReceiver& r) {
r.clipRect(kTestBounds.makeOffset(1, 1),
DlCanvas::ClipOp::kIntersect, true);
}},
{1, 24, 0,
[](DlOpReceiver& r) {
r.clipRect(kTestBounds, DlCanvas::ClipOp::kIntersect, false);
}},
{1, 24, 0,
[](DlOpReceiver& r) {
r.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, true);
}},
{1, 24, 0,
[](DlOpReceiver& r) {
r.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, false);
}},
}},
{"ClipRRect",
{
{1, 64, 0,
[](DlOpReceiver& r) {
r.clipRRect(kTestRRect, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 64, 0,
[](DlOpReceiver& r) {
r.clipRRect(kTestRRect.makeOffset(1, 1),
DlCanvas::ClipOp::kIntersect, true);
}},
{1, 64, 0,
[](DlOpReceiver& r) {
r.clipRRect(kTestRRect, DlCanvas::ClipOp::kIntersect, false);
}},
{1, 64, 0,
[](DlOpReceiver& r) {
r.clipRRect(kTestRRect, DlCanvas::ClipOp::kDifference, true);
}},
{1, 64, 0,
[](DlOpReceiver& r) {
r.clipRRect(kTestRRect, DlCanvas::ClipOp::kDifference, false);
}},
}},
{"ClipPath",
{
{1, 40, 0,
[](DlOpReceiver& r) {
r.clipPath(kTestPath1, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 40, 0,
[](DlOpReceiver& r) {
r.clipPath(kTestPath2, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 40, 0,
[](DlOpReceiver& r) {
r.clipPath(kTestPath3, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 40, 0,
[](DlOpReceiver& r) {
r.clipPath(kTestPath1, DlCanvas::ClipOp::kIntersect, false);
}},
{1, 40, 0,
[](DlOpReceiver& r) {
r.clipPath(kTestPath1, DlCanvas::ClipOp::kDifference, true);
}},
{1, 40, 0,
[](DlOpReceiver& r) {
r.clipPath(kTestPath1, DlCanvas::ClipOp::kDifference, false);
}},
// clipPath(rect) becomes clipRect
{1, 24, 0,
[](DlOpReceiver& r) {
r.clipPath(kTestPathRect, DlCanvas::ClipOp::kIntersect, true);
}},
// clipPath(oval) becomes clipRRect
{1, 64, 0,
[](DlOpReceiver& r) {
r.clipPath(kTestPathOval, DlCanvas::ClipOp::kIntersect, true);
}},
}},
};
}
std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
return {
{"DrawPaint",
{
{1, 8, 1, [](DlOpReceiver& r) { r.drawPaint(); }},
}},
{"DrawColor",
{
{1, 16, 1,
[](DlOpReceiver& r) {
r.drawColor(DlColor(SK_ColorBLUE), DlBlendMode::kSrcIn);
}},
{1, 16, 1,
[](DlOpReceiver& r) {
r.drawColor(DlColor(SK_ColorBLUE), DlBlendMode::kDstOut);
}},
{1, 16, 1,
[](DlOpReceiver& r) {
r.drawColor(DlColor(SK_ColorCYAN), DlBlendMode::kSrcIn);
}},
}},
{"DrawLine",
{
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawLine({0, 0}, {10, 10});
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawLine({0, 1}, {10, 10});
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawLine({0, 0}, {20, 10});
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawLine({0, 0}, {10, 20});
}},
}},
{"DrawRect",
{
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawRect({0, 0, 10, 10});
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawRect({0, 1, 10, 10});
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawRect({0, 0, 20, 10});
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawRect({0, 0, 10, 20});
}},
}},
{"DrawOval",
{
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawOval({0, 0, 10, 10});
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawOval({0, 1, 10, 10});
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawOval({0, 0, 20, 10});
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawOval({0, 0, 10, 20});
}},
}},
{"DrawCircle",
{
{1, 16, 1,
[](DlOpReceiver& r) {
r.drawCircle({0, 0}, 10);
}},
{1, 16, 1,
[](DlOpReceiver& r) {
r.drawCircle({0, 5}, 10);
}},
{1, 16, 1,
[](DlOpReceiver& r) {
r.drawCircle({0, 0}, 20);
}},
}},
{"DrawRRect",
{
{1, 56, 1, [](DlOpReceiver& r) { r.drawRRect(kTestRRect); }},
{1, 56, 1,
[](DlOpReceiver& r) { r.drawRRect(kTestRRect.makeOffset(5, 5)); }},
}},
{"DrawDRRect",
{
{1, 112, 1,
[](DlOpReceiver& r) { r.drawDRRect(kTestRRect, kTestInnerRRect); }},
{1, 112, 1,
[](DlOpReceiver& r) {
r.drawDRRect(kTestRRect.makeOffset(5, 5),
kTestInnerRRect.makeOffset(4, 4));
}},
}},
{"DrawPath",
{
{1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath1); }},
{1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath2); }},
{1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath3); }},
{1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }},
{1, 40, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }},
}},
{"DrawArc",
{
{1, 32, 1,
[](DlOpReceiver& r) { r.drawArc(kTestBounds, 45, 270, false); }},
{1, 32, 1,
[](DlOpReceiver& r) {
r.drawArc(kTestBounds.makeOffset(1, 1), 45, 270, false);
}},
{1, 32, 1,
[](DlOpReceiver& r) { r.drawArc(kTestBounds, 30, 270, false); }},
{1, 32, 1,
[](DlOpReceiver& r) { r.drawArc(kTestBounds, 45, 260, false); }},
{1, 32, 1,
[](DlOpReceiver& r) { r.drawArc(kTestBounds, 45, 270, true); }},
}},
{"DrawPoints",
{
{1, 8 + TestPointCount * 8, 1,
[](DlOpReceiver& r) {
r.drawPoints(DlCanvas::PointMode::kPoints, TestPointCount,
kTestPoints);
}},
{1, 8 + (TestPointCount - 1) * 8, 1,
[](DlOpReceiver& r) {
r.drawPoints(DlCanvas::PointMode::kPoints, TestPointCount - 1,
kTestPoints);
}},
{1, 8 + TestPointCount * 8, 1,
[](DlOpReceiver& r) {
r.drawPoints(DlCanvas::PointMode::kLines, TestPointCount,
kTestPoints);
}},
{1, 8 + TestPointCount * 8, 1,
[](DlOpReceiver& r) {
r.drawPoints(DlCanvas::PointMode::kPolygon, TestPointCount,
kTestPoints);
}},
}},
{"DrawVertices",
{
{1, 112, 1,
[](DlOpReceiver& r) {
r.drawVertices(TestVertices1.get(), DlBlendMode::kSrcIn);
}},
{1, 112, 1,
[](DlOpReceiver& r) {
r.drawVertices(TestVertices1.get(), DlBlendMode::kDstIn);
}},
{1, 112, 1,
[](DlOpReceiver& r) {
r.drawVertices(TestVertices2.get(), DlBlendMode::kSrcIn);
}},
}},
{"DrawImage",
{
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {10, 10}, kNearestSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {10, 10}, kNearestSampling, true);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {20, 10}, kNearestSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {10, 20}, kNearestSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {10, 10}, kLinearSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage2, {10, 10}, kNearestSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
r.drawImage(dl_image, {10, 10}, kNearestSampling, false);
}},
}},
{"DrawImageRect",
{
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
kNearestSampling, true,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kStrict);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
kLinearSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
r.drawImageRect(dl_image, {10, 10, 15, 15}, {10, 10, 80, 80},
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
}},
{"DrawImageNine",
{
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
DlFilterMode::kNearest, false);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
DlFilterMode::kNearest, true);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
DlFilterMode::kNearest, false);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
DlFilterMode::kNearest, false);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
DlFilterMode::kLinear, false);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
DlFilterMode::kNearest, false);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
r.drawImageNine(dl_image, {10, 10, 15, 15}, {10, 10, 80, 80},
DlFilterMode::kNearest, false);
}},
}},
{"DrawAtlas",
{
{1, 48 + 32 + 8, 1,
[](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
{1, 48 + 32 + 8, 1,
[](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr, true);
}},
{1, 48 + 32 + 8, 1,
[](DlOpReceiver& r) {
static SkRSXform xforms[] = {{0, 1, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
{1, 48 + 32 + 8, 1,
[](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 25, 30, 30}};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
{1, 48 + 32 + 8, 1,
[](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kLinearSampling, nullptr, false);
}},
{1, 48 + 32 + 8, 1,
[](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kDstIn, kNearestSampling, nullptr,
false);
}},
{1, 64 + 32 + 8, 1,
[](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
static SkRect cull_rect = {0, 0, 200, 200};
r.drawAtlas(TestImage2, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, &cull_rect,
false);
}},
{1, 48 + 32 + 8 + 8, 1,
[](DlOpReceiver& r) {
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()};
r.drawAtlas(TestImage1, xforms, texs, colors, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
{1, 64 + 32 + 8 + 8, 1,
[](DlOpReceiver& r) {
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 cull_rect = {0, 0, 200, 200};
r.drawAtlas(TestImage1, xforms, texs, colors, 2,
DlBlendMode::kSrcIn, kNearestSampling, &cull_rect,
false);
}},
{1, 48 + 32 + 8, 1,
[](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
r.drawAtlas(dl_image, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
}},
{"DrawDisplayList",
{
{1, 16, 1,
[](DlOpReceiver& r) { r.drawDisplayList(TestDisplayList1, 1.0); },
1u},
{1, 16, 1,
[](DlOpReceiver& r) { r.drawDisplayList(TestDisplayList1, 0.5); },
1u},
{1, 16, 1,
[](DlOpReceiver& r) { r.drawDisplayList(TestDisplayList2, 1.0); },
1u},
{1, 16, 1,
[](DlOpReceiver& r) {
r.drawDisplayList(MakeTestDisplayList(10, 10, SK_ColorRED), 1.0);
},
1u},
}},
{"DrawTextBlob",
{
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawTextBlob(GetTestTextBlob(1), 10, 10);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawTextBlob(GetTestTextBlob(1), 20, 10);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawTextBlob(GetTestTextBlob(1), 10, 20);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawTextBlob(GetTestTextBlob(2), 10, 10);
}},
}},
{"DrawShadow",
{
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawShadow(kTestPath1, DlColor(SK_ColorGREEN), 1.0, false, 1.0);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawShadow(kTestPath2, DlColor(SK_ColorGREEN), 1.0, false, 1.0);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawShadow(kTestPath1, DlColor(SK_ColorBLUE), 1.0, false, 1.0);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawShadow(kTestPath1, DlColor(SK_ColorGREEN), 2.0, false, 1.0);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawShadow(kTestPath1, DlColor(SK_ColorGREEN), 1.0, true, 1.0);
}},
{1, 48, 1,
[](DlOpReceiver& r) {
r.drawShadow(kTestPath1, DlColor(SK_ColorGREEN), 1.0, false, 2.5);
}},
}},
};
}
std::vector<DisplayListInvocationGroup> CreateAllGroups() {
std::vector<DisplayListInvocationGroup> result;
auto all_attribute_ops = CreateAllAttributesOps();
std::move(all_attribute_ops.begin(), all_attribute_ops.end(),
std::back_inserter(result));
auto all_save_restore_ops = CreateAllSaveRestoreOps();
std::move(all_save_restore_ops.begin(), all_save_restore_ops.end(),
std::back_inserter(result));
auto all_transform_ops = CreateAllTransformOps();
std::move(all_transform_ops.begin(), all_transform_ops.end(),
std::back_inserter(result));
auto all_clip_ops = CreateAllClipOps();
std::move(all_clip_ops.begin(), all_clip_ops.end(),
std::back_inserter(result));
auto all_rendering_ops = CreateAllRenderingOps();
std::move(all_rendering_ops.begin(), all_rendering_ops.end(),
std::back_inserter(result));
return result;
}
SkFont CreateTestFontOfSize(SkScalar scalar) {
static constexpr const char* kTestFontFixture = "Roboto-Regular.ttf";
auto mapping = flutter::testing::OpenFixtureAsSkData(kTestFontFixture);
FML_CHECK(mapping);
return SkFont{txt::GetDefaultFontManager()->makeFromData(mapping), scalar};
}
sk_sp<SkTextBlob> GetTestTextBlob(int index) {
static std::map<int, sk_sp<SkTextBlob>> text_blobs;
auto it = text_blobs.find(index);
if (it != text_blobs.end()) {
return it->second;
}
std::string text = "TestBlob" + std::to_string(index);
sk_sp<SkTextBlob> blob =
SkTextBlob::MakeFromText(text.c_str(), text.size(),
CreateTestFontOfSize(20), SkTextEncoding::kUTF8);
text_blobs.insert(std::make_pair(index, blob));
return blob;
}
} // namespace testing
} // namespace flutter