Migrate DisplayList unit tests to DL/Impeller geometry classes (#161453)

Address the first item in
https://github.com/flutter/flutter/issues/161456 (Unit tests in the
display_list/ directory)

Some new `DlPath::Make<Shape>` factories were added to make test writing
simpler.

`DlPath` is now bi-directional! You can construct one from either an
`SkPath` or an `impeller::Path` and it will auto-convert to the other as
needed. This allows unit tests with custom paths to rely on
`impeller::Path` for path construction instead of `SkPath` (as long as
only simple move/line/quad/curve verbs are needed).

`RoundRect` now normalizes the argument rect in all constructors to
match Flutter expectations and `SkRRect` legacy behavior. This behavior
was already being enforced in `ui.rrect` but the unit tests we have to
verify the behavior are written against the `RoundRect` object itself so
this was the simplest way to make the unit tests work right, while
ensuring that we maintain correct behavior for `ui` objects. Ideally
these issues would be tested at the `ui` native interface instead of as
unit tests on our internal objects and we should be allowed to decide
how we want our internal APIs to behave with regard to this concept.

Skia inverted path types are no longer allowed in `DlPath` and all use
of them should be eliminated in the engine (except to test if they crash
when used in a debug unit test)

A couple of unit tests for `DlOpSpy` and Impeller's interop package were
migrated here along for the ride even though this PR was focused
primarily on `display_list/` unit tests.
This commit is contained in:
Jim Graham 2025-01-13 11:28:57 -08:00 committed by GitHub
parent 8856ccb844
commit d80be471dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 1933 additions and 1889 deletions

View File

@ -103,8 +103,8 @@ void BM_DrawLine(benchmark::State& state,
state.counters["DrawCallCount"] = kLinesToDraw;
for (size_t i = 0; i < kLinesToDraw; i++) {
builder.DrawLine(SkPoint::Make(i % length, 0),
SkPoint::Make(length - i % length, length), paint);
builder.DrawLine(DlPoint(i % length, 0),
DlPoint(length - i % length, length), paint);
}
auto display_list = builder.Build();
@ -139,20 +139,20 @@ void BM_DrawRect(benchmark::State& state,
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
auto canvas = DlSkCanvasAdapter(surface->getCanvas());
// As rects have SkScalar dimensions, we want to ensure that we also
// As rects have DlScalar dimensions, we want to ensure that we also
// draw rects with non-integer position and size
const SkScalar offset = 0.5f;
SkRect rect = SkRect::MakeLTRB(0, 0, length, length);
const DlScalar offset = 0.5f;
DlRect rect = DlRect::MakeLTRB(0, 0, length, length);
state.counters["DrawCallCount"] = kRectsToDraw;
for (size_t i = 0; i < kRectsToDraw; i++) {
builder.DrawRect(rect, paint);
rect.offset(offset, offset);
if (rect.right() > canvas_size) {
rect.offset(-canvas_size, 0);
rect = rect.Shift(offset, offset);
if (rect.GetRight() > canvas_size) {
rect = rect.Shift(-canvas_size, 0);
}
if (rect.bottom() > canvas_size) {
rect.offset(0, -canvas_size);
if (rect.GetBottom() > canvas_size) {
rect = rect.Shift(0, -canvas_size);
}
}
@ -188,18 +188,18 @@ void BM_DrawOval(benchmark::State& state,
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkRect rect = SkRect::MakeXYWH(0, 0, length * 1.5f, length);
const SkScalar offset = 0.5f;
DlRect rect = DlRect::MakeXYWH(0, 0, length * 1.5f, length);
const DlScalar offset = 0.5f;
state.counters["DrawCallCount"] = kOvalsToDraw;
for (size_t i = 0; i < kOvalsToDraw; i++) {
builder.DrawOval(rect, paint);
rect.offset(offset, offset);
if (rect.right() > canvas_size) {
rect.offset(-canvas_size, 0);
rect = rect.Shift(offset, offset);
if (rect.GetRight() > canvas_size) {
rect = rect.Shift(-canvas_size, 0);
}
if (rect.bottom() > canvas_size) {
rect.offset(0, -canvas_size);
if (rect.GetBottom() > canvas_size) {
rect = rect.Shift(0, -canvas_size);
}
}
auto display_list = builder.Build();
@ -234,20 +234,21 @@ void BM_DrawCircle(benchmark::State& state,
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkScalar radius = length / 2.0f;
const SkScalar offset = 0.5f;
DlScalar radius = length / 2.0f;
const DlScalar offset = 0.5f;
SkPoint center = SkPoint::Make(radius, radius);
DlPoint center = DlPoint(radius, radius);
DlPoint shift = DlPoint(offset, offset);
state.counters["DrawCallCount"] = kCirclesToDraw;
for (size_t i = 0; i < kCirclesToDraw; i++) {
builder.DrawCircle(center, radius, paint);
center.offset(offset, offset);
if (center.x() + radius > canvas_size) {
center.set(radius, center.y());
center += shift;
if (center.x + radius > canvas_size) {
center.x = radius;
}
if (center.y() + radius > canvas_size) {
center.set(center.x(), radius);
if (center.y + radius > canvas_size) {
center.y = radius;
}
}
auto display_list = builder.Build();
@ -270,7 +271,7 @@ void BM_DrawCircle(benchmark::State& state,
void BM_DrawRRect(benchmark::State& state,
BackendType backend_type,
unsigned attributes,
SkRRect::Type type) {
RRectType type) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
DlPaint paint = GetPaintForRun(attributes);
@ -283,49 +284,45 @@ void BM_DrawRRect(benchmark::State& state,
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkVector radii[4] = {};
DlRoundingRadii radii;
switch (type) {
case SkRRect::Type::kSimple_Type:
radii[0] = SkVector::Make(5.0f, 5.0f);
radii[1] = SkVector::Make(5.0f, 5.0f);
radii[2] = SkVector::Make(5.0f, 5.0f);
radii[3] = SkVector::Make(5.0f, 5.0f);
case RRectType::kSimple:
radii.top_left = DlSize(5.0f, 5.0f);
radii.top_right = DlSize(5.0f, 5.0f);
radii.bottom_right = DlSize(5.0f, 5.0f);
radii.bottom_left = DlSize(5.0f, 5.0f);
break;
case SkRRect::Type::kNinePatch_Type:
radii[0] = SkVector::Make(5.0f, 2.0f);
radii[1] = SkVector::Make(3.0f, 2.0f);
radii[2] = SkVector::Make(3.0f, 4.0f);
radii[3] = SkVector::Make(5.0f, 4.0f);
case RRectType::kNinePatch:
radii.top_left = DlSize(5.0f, 2.0f);
radii.top_right = DlSize(3.0f, 2.0f);
radii.bottom_right = DlSize(3.0f, 4.0f);
radii.bottom_left = DlSize(5.0f, 4.0f);
break;
case SkRRect::Type::kComplex_Type:
radii[0] = SkVector::Make(5.0f, 4.0f);
radii[1] = SkVector::Make(4.0f, 5.0f);
radii[2] = SkVector::Make(3.0f, 6.0f);
radii[3] = SkVector::Make(2.0f, 7.0f);
case RRectType::kComplex:
radii.top_left = DlSize(5.0f, 4.0f);
radii.top_right = DlSize(4.0f, 5.0f);
radii.bottom_right = DlSize(3.0f, 6.0f);
radii.bottom_left = DlSize(2.0f, 7.0f);
break;
default:
break;
FML_UNREACHABLE();
}
const SkScalar offset = 0.5f;
const SkScalar multiplier = length / 16.0f;
SkRRect rrect;
const DlScalar offset = 0.5f;
const DlScalar multiplier = length / 16.0f;
SkVector set_radii[4];
for (size_t i = 0; i < 4; i++) {
set_radii[i] = radii[i] * multiplier;
}
rrect.setRectRadii(SkRect::MakeLTRB(0, 0, length, length), set_radii);
DlRoundRect rrect = DlRoundRect::MakeRectRadii(
DlRect::MakeLTRB(0, 0, length, length), radii * multiplier);
state.counters["DrawCallCount"] = kRRectsToDraw;
for (size_t i = 0; i < kRRectsToDraw; i++) {
builder.DrawRRect(rrect, paint);
rrect.offset(offset, offset);
if (rrect.rect().right() > canvas_size) {
rrect.offset(-canvas_size, 0);
builder.DrawRoundRect(rrect, paint);
rrect = rrect.Shift(offset, offset);
if (rrect.GetBounds().GetRight() > canvas_size) {
rrect = rrect.Shift(-canvas_size, 0);
}
if (rrect.rect().bottom() > canvas_size) {
rrect.offset(0, -canvas_size);
if (rrect.GetBounds().GetBottom() > canvas_size) {
rrect = rrect.Shift(0, -canvas_size);
}
}
auto display_list = builder.Build();
@ -351,7 +348,7 @@ void BM_DrawRRect(benchmark::State& state,
void BM_DrawDRRect(benchmark::State& state,
BackendType backend_type,
unsigned attributes,
SkRRect::Type type) {
RRectType type) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
DlPaint paint = GetPaintForRun(attributes);
@ -364,50 +361,51 @@ void BM_DrawDRRect(benchmark::State& state,
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkVector radii[4] = {};
DlRoundingRadii radii;
switch (type) {
case SkRRect::Type::kSimple_Type:
radii[0] = SkVector::Make(5.0f, 5.0f);
radii[1] = SkVector::Make(5.0f, 5.0f);
radii[2] = SkVector::Make(5.0f, 5.0f);
radii[3] = SkVector::Make(5.0f, 5.0f);
case RRectType::kSimple:
radii.top_left = DlSize(5.0f, 5.0f);
radii.top_right = DlSize(5.0f, 5.0f);
radii.bottom_right = DlSize(5.0f, 5.0f);
radii.bottom_left = DlSize(5.0f, 5.0f);
break;
case SkRRect::Type::kNinePatch_Type:
radii[0] = SkVector::Make(5.0f, 7.0f);
radii[1] = SkVector::Make(3.0f, 7.0f);
radii[2] = SkVector::Make(3.0f, 4.0f);
radii[3] = SkVector::Make(5.0f, 4.0f);
case RRectType::kNinePatch:
radii.top_left = DlSize(5.0f, 7.0f);
radii.top_right = DlSize(3.0f, 7.0f);
radii.bottom_right = DlSize(3.0f, 4.0f);
radii.bottom_left = DlSize(5.0f, 4.0f);
break;
case SkRRect::Type::kComplex_Type:
radii[0] = SkVector::Make(5.0f, 4.0f);
radii[1] = SkVector::Make(4.0f, 5.0f);
radii[2] = SkVector::Make(3.0f, 6.0f);
radii[3] = SkVector::Make(8.0f, 7.0f);
case RRectType::kComplex:
radii.top_left = DlSize(5.0f, 4.0f);
radii.top_right = DlSize(4.0f, 5.0f);
radii.bottom_right = DlSize(3.0f, 6.0f);
radii.bottom_left = DlSize(8.0f, 7.0f);
break;
default:
break;
FML_UNREACHABLE();
}
const SkScalar offset = 0.5f;
const SkScalar multiplier = length / 16.0f;
SkRRect rrect, rrect_2;
const DlScalar offset = 0.5f;
const DlScalar multiplier = length / 16.0f;
SkVector set_radii[4];
for (size_t i = 0; i < 4; i++) {
set_radii[i] = radii[i] * multiplier;
}
rrect.setRectRadii(SkRect::MakeLTRB(0, 0, length, length), set_radii);
DlRoundRect rrect = DlRoundRect::MakeRectRadii(
DlRect::MakeLTRB(0, 0, length, length), radii * multiplier);
DlRoundRect rrect_2 = DlRoundRect::MakeRectRadii(
DlRect::MakeLTRB(0, 0, length, length).Expand(-0.1f * length),
radii * multiplier);
state.counters["DrawCallCount"] = kDRRectsToDraw;
for (size_t i = 0; i < kDRRectsToDraw; i++) {
rrect.inset(0.1f * length, 0.1f * length, &rrect_2);
builder.DrawDRRect(rrect, rrect_2, paint);
rrect.offset(offset, offset);
if (rrect.rect().right() > canvas_size) {
rrect.offset(-canvas_size, 0);
builder.DrawDiffRoundRect(rrect, rrect_2, paint);
rrect = rrect.Shift(offset, offset);
rrect_2 = rrect_2.Shift(offset, offset);
if (rrect.GetBounds().GetRight() > canvas_size) {
rrect = rrect.Shift(-canvas_size, 0);
rrect_2 = rrect_2.Shift(-canvas_size, 0);
}
if (rrect.rect().bottom() > canvas_size) {
rrect.offset(0, -canvas_size);
if (rrect.GetBounds().GetBottom() > canvas_size) {
rrect = rrect.Shift(0, -canvas_size);
rrect_2 = rrect_2.Shift(0, -canvas_size);
}
}
auto display_list = builder.Build();
@ -439,27 +437,27 @@ void BM_DrawArc(benchmark::State& state,
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkScalar starting_angle = 0.0f;
SkScalar offset = 0.5f;
DlScalar starting_angle = 0.0f;
DlScalar offset = 0.5f;
// Just some random sweeps that will mostly circumnavigate the circle
std::vector<SkScalar> segment_sweeps = {5.5f, -10.0f, 42.0f, 71.7f, 90.0f,
std::vector<DlScalar> segment_sweeps = {5.5f, -10.0f, 42.0f, 71.7f, 90.0f,
37.5f, 17.9f, 32.0f, 379.4f};
SkRect bounds = SkRect::MakeLTRB(0, 0, length, length);
DlRect bounds = DlRect::MakeLTRB(0, 0, length, length);
state.counters["DrawCallCount"] = kArcSweepSetsToDraw * segment_sweeps.size();
for (size_t i = 0; i < kArcSweepSetsToDraw; i++) {
for (SkScalar sweep : segment_sweeps) {
for (DlScalar sweep : segment_sweeps) {
builder.DrawArc(bounds, starting_angle, sweep, false, paint);
starting_angle += sweep + 5.0f;
}
bounds.offset(offset, offset);
if (bounds.right() > canvas_size) {
bounds.offset(-canvas_size, 0);
bounds = bounds.Shift(offset, offset);
if (bounds.GetRight() > canvas_size) {
bounds = bounds.Shift(-canvas_size, 0);
}
if (bounds.bottom() > canvas_size) {
bounds.offset(0, -canvas_size);
if (bounds.GetBottom() > canvas_size) {
bounds = bounds.Shift(0, -canvas_size);
}
}
@ -478,9 +476,9 @@ void BM_DrawArc(benchmark::State& state,
// Returns a list of SkPoints that represent `n` points equally spaced out
// along the circumference of a circle with radius `r` and centered on `center`.
std::vector<SkPoint> GetPolygonPoints(size_t n, SkPoint center, SkScalar r) {
std::vector<SkPoint> GetPolygonPoints(size_t n, SkPoint center, DlScalar r) {
std::vector<SkPoint> points;
SkScalar x, y;
DlScalar x, y;
float angle;
float full_circle = 2.0f * M_PI;
for (size_t i = 0; i < n; i++) {

View File

@ -15,7 +15,6 @@
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkVertices.h"
namespace flutter {
namespace testing {
@ -28,6 +27,12 @@ enum BenchmarkAttributes {
kAntiAliasing = 1 << 3
};
enum class RRectType {
kSimple,
kNinePatch,
kComplex,
};
DlPaint GetPaintForRun(unsigned attributes);
using BackendType = DlSurfaceProvider::BackendType;
@ -52,11 +57,11 @@ void BM_DrawArc(benchmark::State& state,
void BM_DrawRRect(benchmark::State& state,
BackendType backend_type,
unsigned attributes,
SkRRect::Type type);
RRectType type);
void BM_DrawDRRect(benchmark::State& state,
BackendType backend_type,
unsigned attributes,
SkRRect::Type type);
RRectType type);
void BM_DrawPath(benchmark::State& state,
BackendType backend_type,
unsigned attributes,
@ -102,7 +107,7 @@ void BM_SaveLayer(benchmark::State& state,
// DrawLine
#define DRAW_LINE_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawLine, BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@ -112,7 +117,7 @@ void BM_SaveLayer(benchmark::State& state,
// DrawRect
#define DRAW_RECT_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawRect, BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@ -122,7 +127,7 @@ void BM_SaveLayer(benchmark::State& state,
// DrawOval
#define DRAW_OVAL_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawOval, BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@ -132,7 +137,7 @@ void BM_SaveLayer(benchmark::State& state,
// DrawCircle
#define DRAW_CIRCLE_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawCircle, BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES) \
->RangeMultiplier(2) \
->Range(16, 2048) \
@ -142,7 +147,7 @@ void BM_SaveLayer(benchmark::State& state,
// DrawArc
#define DRAW_ARC_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawArc, BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES) \
->RangeMultiplier(2) \
->Range(128, 2048) \
@ -153,7 +158,7 @@ void BM_SaveLayer(benchmark::State& state,
#define DRAW_PATH_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawPath, \
Lines/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkPath::Verb::kLine_Verb) \
->RangeMultiplier(2) \
@ -164,7 +169,7 @@ void BM_SaveLayer(benchmark::State& state,
\
BENCHMARK_CAPTURE(BM_DrawPath, \
Quads/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkPath::Verb::kQuad_Verb) \
->RangeMultiplier(2) \
@ -175,7 +180,7 @@ void BM_SaveLayer(benchmark::State& state,
\
BENCHMARK_CAPTURE(BM_DrawPath, \
Conics/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkPath::Verb::kConic_Verb) \
->RangeMultiplier(2) \
@ -186,7 +191,7 @@ void BM_SaveLayer(benchmark::State& state,
\
BENCHMARK_CAPTURE(BM_DrawPath, \
Cubics/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkPath::Verb::kCubic_Verb) \
->RangeMultiplier(2) \
@ -198,7 +203,7 @@ void BM_SaveLayer(benchmark::State& state,
// DrawPoints
#define DRAW_POINTS_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawPoints, Points/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlCanvas::PointMode::kPoints) \
->RangeMultiplier(2) \
@ -207,7 +212,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawPoints, Lines/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlCanvas::PointMode::kLines) \
->RangeMultiplier(2) \
@ -216,7 +221,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawPoints, Polygon/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlCanvas::PointMode::kPolygon) \
->RangeMultiplier(2) \
@ -228,7 +233,7 @@ void BM_SaveLayer(benchmark::State& state,
#define DRAW_VERTICES_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawVertices, \
TriangleStrip/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlVertexMode::kTriangleStrip) \
->RangeMultiplier(2) \
@ -239,7 +244,7 @@ void BM_SaveLayer(benchmark::State& state,
\
BENCHMARK_CAPTURE(BM_DrawVertices, \
TriangleFan/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlVertexMode::kTriangleFan) \
->RangeMultiplier(2) \
@ -250,7 +255,7 @@ void BM_SaveLayer(benchmark::State& state,
\
BENCHMARK_CAPTURE(BM_DrawVertices, \
Triangles/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlVertexMode::kTriangles) \
->RangeMultiplier(2) \
@ -262,27 +267,27 @@ void BM_SaveLayer(benchmark::State& state,
// DrawRRect
#define DRAW_RRECT_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawRRect, Symmetric/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkRRect::Type::kSimple_Type) \
RRectType::kSimple) \
->RangeMultiplier(2) \
->Range(16, 256) \
->UseRealTime() \
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawRRect, NinePatch/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkRRect::Type::kNinePatch_Type) \
RRectType::kNinePatch) \
->RangeMultiplier(2) \
->Range(16, 256) \
->UseRealTime() \
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawRRect, Complex/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkRRect::Type::kComplex_Type) \
RRectType::kComplex) \
->RangeMultiplier(2) \
->Range(16, 256) \
->UseRealTime() \
@ -291,27 +296,27 @@ void BM_SaveLayer(benchmark::State& state,
// DrawDRRect
#define DRAW_DRRECT_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawDRRect, Symmetric/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkRRect::Type::kSimple_Type) \
RRectType::kSimple) \
->RangeMultiplier(2) \
->Range(16, 256) \
->UseRealTime() \
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawDRRect, NinePatch/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkRRect::Type::kNinePatch_Type) \
RRectType::kNinePatch) \
->RangeMultiplier(2) \
->Range(16, 256) \
->UseRealTime() \
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawDRRect, Complex/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
SkRRect::Type::kComplex_Type) \
RRectType::kComplex) \
->RangeMultiplier(2) \
->Range(16, 256) \
->UseRealTime() \
@ -320,18 +325,18 @@ void BM_SaveLayer(benchmark::State& state,
// DrawImage
#define DRAW_IMAGE_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawImage, Texture/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlImageSampling::kNearestNeighbor, false) \
DlImageSampling::kNearestNeighbor, false) \
->RangeMultiplier(2) \
->Range(128, 512) \
->UseRealTime() \
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawImage, Upload/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlImageSampling::kNearestNeighbor, true) \
DlImageSampling::kNearestNeighbor, true) \
->RangeMultiplier(2) \
->Range(128, 512) \
->UseRealTime() \
@ -341,7 +346,7 @@ void BM_SaveLayer(benchmark::State& state,
#define DRAW_IMAGE_RECT_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE( \
BM_DrawImageRect, Texture/Strict/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlImageSampling::kNearestNeighbor, \
DlCanvas::SrcRectConstraint::kStrict, false) \
@ -352,7 +357,7 @@ void BM_SaveLayer(benchmark::State& state,
\
BENCHMARK_CAPTURE( \
BM_DrawImageRect, Texture/Fast/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlImageSampling::kNearestNeighbor, \
DlCanvas::SrcRectConstraint::kFast, false) \
@ -363,7 +368,7 @@ void BM_SaveLayer(benchmark::State& state,
\
BENCHMARK_CAPTURE( \
BM_DrawImageRect, Upload/Strict/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlImageSampling::kNearestNeighbor, \
DlCanvas::SrcRectConstraint::kStrict, true) \
@ -374,7 +379,7 @@ void BM_SaveLayer(benchmark::State& state,
\
BENCHMARK_CAPTURE( \
BM_DrawImageRect, Upload/Fast/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlImageSampling::kNearestNeighbor, \
DlCanvas::SrcRectConstraint::kFast, true) \
@ -386,7 +391,7 @@ void BM_SaveLayer(benchmark::State& state,
// DrawImageNine
#define DRAW_IMAGE_NINE_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawImageNine, Texture/Nearest/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlFilterMode::kNearest, false) \
->RangeMultiplier(2) \
@ -395,7 +400,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawImageNine, Upload/Nearest/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlFilterMode::kNearest, true) \
->RangeMultiplier(2) \
@ -404,7 +409,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawImageNine, Texture/Linear/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlFilterMode::kLinear, false) \
->RangeMultiplier(2) \
@ -413,7 +418,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawImageNine, Upload/Linear/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
DlFilterMode::kLinear, true) \
->RangeMultiplier(2) \
@ -424,7 +429,7 @@ void BM_SaveLayer(benchmark::State& state,
// DrawTextBlob
#define DRAW_TEXT_BLOB_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawTextBlob, BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES) \
->RangeMultiplier(2) \
->Range(1, 256) \
@ -435,7 +440,7 @@ void BM_SaveLayer(benchmark::State& state,
// DrawShadow
#define DRAW_SHADOW_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_DrawShadow, Lines/Transparent/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
true, \
SkPath::Verb::kLine_Verb) \
@ -445,7 +450,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Quads/Transparent/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
true, \
SkPath::Verb::kQuad_Verb) \
@ -455,7 +460,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Conics/Transparent/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
true, \
SkPath::Verb::kConic_Verb) \
@ -465,7 +470,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Cubics/Transparent/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
true, \
SkPath::Verb::kCubic_Verb) \
@ -475,7 +480,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Lines/Opaque/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
false, \
SkPath::Verb::kLine_Verb) \
@ -485,7 +490,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Quads/Opaque/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
false, \
SkPath::Verb::kQuad_Verb) \
@ -495,7 +500,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Conics/Opaque/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
false, \
SkPath::Verb::kConic_Verb) \
@ -505,7 +510,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_DrawShadow, Cubics/Opaque/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
false, \
SkPath::Verb::kCubic_Verb) \
@ -517,7 +522,7 @@ void BM_SaveLayer(benchmark::State& state,
// SaveLayer
#define SAVE_LAYER_BENCHMARKS(BACKEND, ATTRIBUTES) \
BENCHMARK_CAPTURE(BM_SaveLayer, Depth 1/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
1) \
->RangeMultiplier(2) \
@ -526,7 +531,7 @@ void BM_SaveLayer(benchmark::State& state,
->Unit(benchmark::kMillisecond); \
\
BENCHMARK_CAPTURE(BM_SaveLayer, Depth 8/BACKEND, \
BackendType::k##BACKEND##Backend, \
BackendType::k##BACKEND##Backend, \
ATTRIBUTES, \
8) \
->RangeMultiplier(2) \
@ -575,11 +580,11 @@ void BM_SaveLayer(benchmark::State& state,
STROKE_BENCHMARKS(BACKEND, kStrokedStyle | kAntiAliasing) \
STROKE_BENCHMARKS(BACKEND, kStrokedStyle | kHairlineStroke) \
STROKE_BENCHMARKS(BACKEND, kStrokedStyle | kHairlineStroke | \
kAntiAliasing) \
FILL_BENCHMARKS(BACKEND, kFilledStyle) \
FILL_BENCHMARKS(BACKEND, kFilledStyle | kAntiAliasing) \
ANTI_ALIASING_BENCHMARKS(BACKEND, kEmpty) \
ANTI_ALIASING_BENCHMARKS(BACKEND, kAntiAliasing) \
kAntiAliasing) \
FILL_BENCHMARKS(BACKEND, kFilledStyle) \
FILL_BENCHMARKS(BACKEND, kFilledStyle | kAntiAliasing) \
ANTI_ALIASING_BENCHMARKS(BACKEND, kEmpty) \
ANTI_ALIASING_BENCHMARKS(BACKEND, kAntiAliasing) \
OTHER_BENCHMARKS(BACKEND, kEmpty)
// clang-format on

View File

@ -127,7 +127,7 @@ static void BM_DisplayListBuilderWithPerspective(
static void BM_DisplayListBuilderWithClipRect(
benchmark::State& state,
DisplayListBuilderBenchmarkType type) {
SkRect clip_bounds = SkRect::MakeLTRB(6.5, 7.3, 90.2, 85.7);
DlRect clip_bounds = DlRect::MakeLTRB(6.5, 7.3, 90.2, 85.7);
bool prepare_rtree = NeedPrepareRTree(type);
while (state.KeepRunning()) {
DisplayListBuilder builder(prepare_rtree);
@ -183,7 +183,7 @@ static void BM_DisplayListBuilderWithSaveLayerAndImageFilter(
DisplayListBuilderBenchmarkType type) {
DlPaint layer_paint;
layer_paint.setImageFilter(&testing::kTestBlurImageFilter1);
SkRect layer_bounds = SkRect::MakeLTRB(6.5, 7.3, 35.2, 42.7);
DlRect layer_bounds = DlRect::MakeLTRB(6.5, 7.3, 35.2, 42.7);
bool prepare_rtree = NeedPrepareRTree(type);
while (state.KeepRunning()) {
DisplayListBuilder builder(prepare_rtree);
@ -191,7 +191,7 @@ static void BM_DisplayListBuilderWithSaveLayerAndImageFilter(
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);
builder.SaveLayer(layer_bounds, &layer_paint);
invocation.Invoke(receiver);
builder.Restore();
}
@ -282,8 +282,8 @@ static void BM_DisplayListDispatchCull(benchmark::State& state,
InvokeAllOps(builder);
}
auto display_list = builder.Build();
SkRect rect = SkRect::MakeLTRB(0, 0, 100, 100);
EXPECT_FALSE(rect.contains(display_list->bounds()));
DlRect rect = DlRect::MakeLTRB(0, 0, 100, 100);
EXPECT_FALSE(rect.Contains(display_list->GetBounds()));
DlOpReceiverIgnore receiver;
while (state.KeepRunning()) {
display_list->Dispatch(receiver, rect);

File diff suppressed because it is too large Load Diff

View File

@ -1034,7 +1034,7 @@ void DisplayListBuilder::ClipPath(const DlPath& path,
if (current_info().is_nop) {
return;
}
if (!path.IsInverseFillType()) {
{
DlRect rect;
if (path.IsRect(&rect)) {
ClipRect(rect, clip_op, is_aa);
@ -1221,9 +1221,7 @@ void DisplayListBuilder::drawPath(const DlPath& path) {
DisplayListAttributeFlags flags = kDrawPathFlags;
OpResult result = PaintResult(current_, flags);
if (result != OpResult::kNoEffect) {
bool is_visible = path.IsInverseFillType()
? AccumulateUnbounded()
: AccumulateOpBounds(path.GetBounds(), flags);
bool is_visible = AccumulateOpBounds(path.GetBounds(), flags);
if (is_visible) {
Push<DrawPathOp>(0, path);
CheckLayerOpacityHairlineCompatibility();

View File

@ -241,16 +241,6 @@ class DlCanvas {
SaveLayer(ToOptDlRect(bounds), paint, backdrop, backdrop_id);
}
void Transform(const SkMatrix* matrix) {
if (matrix) {
Transform(*matrix);
}
}
void Transform(const SkM44* matrix44) {
if (matrix44) {
Transform(*matrix44);
}
}
void Transform(const SkMatrix& matrix) { Transform(ToDlMatrix(matrix)); }
void Transform(const SkM44& m44) { Transform(ToDlMatrix(m44)); }
void SetTransform(const SkMatrix* matrix) {

View File

@ -181,12 +181,6 @@ struct DlColor {
bool operator!=(DlColor const& other) const {
return !this->operator==(other);
}
bool operator==(uint32_t const& other) const {
return argb() == other && color_space_ == DlColorSpace::kSRGB;
}
bool operator!=(uint32_t const& other) const {
return !this->operator==(other);
}
private:
DlScalar alpha_;

View File

@ -6,8 +6,6 @@
#include "flutter/testing/display_list_testing.h"
#include "flutter/testing/testing.h"
#include "third_party/skia/include/core/SkColor.h"
namespace flutter {
namespace testing {
@ -46,13 +44,6 @@ TEST(DisplayListColor, ArrayInterchangeableWithUint32) {
arraysEqual(ints, colors, 5);
}
TEST(DisplayListColor, DlColorDirectlyComparesToSkColor) {
EXPECT_EQ(DlColor::kBlack(), SK_ColorBLACK);
EXPECT_EQ(DlColor::kRed(), SK_ColorRED);
EXPECT_EQ(DlColor::kGreen(), SK_ColorGREEN);
EXPECT_EQ(DlColor::kBlue(), SK_ColorBLUE);
}
TEST(DisplayListColor, DlColorFloatConstructor) {
EXPECT_EQ(DlColor::ARGB(1.0f, 1.0f, 1.0f, 1.0f), DlColor(0xFFFFFFFF));
EXPECT_EQ(DlColor::ARGB(0.0f, 0.0f, 0.0f, 0.0f), DlColor(0x00000000));

View File

@ -5,6 +5,7 @@
#include "flutter/display_list/dl_paint.h"
#include "flutter/display_list/testing/dl_test_equality.h"
#include "flutter/display_list/testing/dl_test_snippets.h"
#include "flutter/display_list/utils/dl_comparable.h"
#include "gtest/gtest.h"
@ -155,14 +156,10 @@ TEST(DisplayListPaint, ChainingConstructor) {
}
TEST(DisplayListPaint, PaintDetectsRuntimeEffects) {
const auto runtime_effect = DlRuntimeEffect::MakeSkia(
SkRuntimeEffect::MakeForShader(
SkString("vec4 main(vec2 p) { return vec4(0); }"))
.effect);
auto color_source = DlColorSource::MakeRuntimeEffect(
runtime_effect, {}, std::make_shared<std::vector<uint8_t>>());
kTestRuntimeEffect1, {}, std::make_shared<std::vector<uint8_t>>());
auto image_filter = DlImageFilter::MakeRuntimeEffect(
runtime_effect, {}, std::make_shared<std::vector<uint8_t>>());
kTestRuntimeEffect1, {}, std::make_shared<std::vector<uint8_t>>());
DlPaint paint;
EXPECT_FALSE(paint.usesRuntimeEffect());

View File

@ -590,10 +590,10 @@ TEST(DisplayListVertices, BuildWithColorAndIndices) {
DlPoint(5, 6),
DlPoint(15, 20),
};
SkColor colors[3] = {
SK_ColorRED,
SK_ColorCYAN,
SK_ColorGREEN,
uint32_t colors[3] = {
0xffff0000,
0xff00ffff,
0xff00ff00,
};
uint16_t indices[6] = {
2, 1, 0, //
@ -618,7 +618,7 @@ TEST(DisplayListVertices, BuildWithColorAndIndices) {
ASSERT_EQ(vertices->vertex_count(), 3);
for (int i = 0; i < 3; i++) {
ASSERT_EQ(vertices->vertex_data()[i], coords[i]);
ASSERT_EQ(vertices->colors()[i], colors[i]);
ASSERT_EQ(vertices->colors()[i].argb(), colors[i]);
}
ASSERT_EQ(vertices->index_count(), 6);
for (int i = 0; i < 6; i++) {
@ -742,10 +742,10 @@ TEST(DisplayListVertices, BuildWithColor) {
DlPoint(5, 6),
DlPoint(15, 20),
};
SkColor colors[3] = {
SK_ColorRED,
SK_ColorCYAN,
SK_ColorGREEN,
uint32_t colors[3] = {
0xffff0000,
0xff00ffff,
0xff00ff00,
};
Builder builder(DlVertexMode::kTriangles, 3, //
@ -765,7 +765,7 @@ TEST(DisplayListVertices, BuildWithColor) {
ASSERT_EQ(vertices->vertex_count(), 3);
for (int i = 0; i < 3; i++) {
ASSERT_EQ(vertices->vertex_data()[i], coords[i]);
ASSERT_EQ(vertices->colors()[i], colors[i]);
ASSERT_EQ(vertices->colors()[i].argb(), colors[i]);
}
ASSERT_EQ(vertices->index_count(), 0);
}

View File

@ -11,41 +11,15 @@
#include "flutter/display_list/effects/dl_runtime_effect.h"
#include "flutter/display_list/image/dl_image.h"
#include "flutter/display_list/testing/dl_test_equality.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "flutter/display_list/testing/dl_test_snippets.h"
namespace flutter {
namespace testing {
static sk_sp<DlImage> MakeTestImage(int w, int h, SkColor color) {
sk_sp<SkSurface> surface;
if (SkColorGetA(color) < 255) {
surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(w, h));
} else {
SkImageInfo info =
SkImageInfo::MakeN32(w, h, SkAlphaType::kOpaque_SkAlphaType);
surface = SkSurfaces::Raster(info);
}
SkCanvas* canvas = surface->getCanvas();
canvas->drawColor(color);
return DlImage::Make(surface->makeImageSnapshot());
}
static const sk_sp<DlRuntimeEffect> kTestRuntimeEffect1 =
DlRuntimeEffect::MakeSkia(
SkRuntimeEffect::MakeForShader(
SkString("vec4 main(vec2 p) { return vec4(0); }"))
.effect);
static const sk_sp<DlRuntimeEffect> kTestRuntimeEffect2 =
DlRuntimeEffect::MakeSkia(
SkRuntimeEffect::MakeForShader(
SkString("vec4 main(vec2 p) { return vec4(1); }"))
.effect);
static const sk_sp<DlImage> kTestImage1 = MakeTestImage(10, 10, SK_ColorGREEN);
static const sk_sp<DlImage> kTestAlphaImage1 =
MakeTestImage(10, 10, SK_ColorTRANSPARENT);
static const sk_sp<DlImage> kTestOpaqueImage =
MakeTestImage(10, 10, DlColor::kGreen());
static const sk_sp<DlImage> kTestAlphaImage =
MakeTestImage(10, 10, DlColor::kTransparent());
// clang-format off
static const DlMatrix kTestMatrix1 =
DlMatrix::MakeRow(2, 0, 0, 10,
@ -79,7 +53,7 @@ static constexpr float kTestStops2[kTestStopCount] = {
0.3f,
1.0f,
};
static constexpr DlPoint kTestPoints[2] = {
static constexpr DlPoint kTestPoints1[2] = {
DlPoint(5, 15),
DlPoint(7, 18),
};
@ -89,20 +63,23 @@ static constexpr DlPoint kTestPoints2[2] = {
};
TEST(DisplayListColorSource, ImageConstructor) {
DlImageColorSource source(kTestImage1, DlTileMode::kClamp, DlTileMode::kClamp,
DlImageSampling::kLinear, &kTestMatrix1);
DlImageColorSource source(kTestOpaqueImage, DlTileMode::kClamp,
DlTileMode::kClamp, DlImageSampling::kLinear,
&kTestMatrix1);
}
TEST(DisplayListColorSource, ImageShared) {
DlImageColorSource source(kTestImage1, DlTileMode::kClamp, DlTileMode::kClamp,
DlImageSampling::kLinear, &kTestMatrix1);
DlImageColorSource source(kTestOpaqueImage, DlTileMode::kClamp,
DlTileMode::kClamp, DlImageSampling::kLinear,
&kTestMatrix1);
ASSERT_NE(source.shared().get(), &source);
ASSERT_EQ(*source.shared(), source);
}
TEST(DisplayListColorSource, ImageAsImage) {
DlImageColorSource source(kTestImage1, DlTileMode::kClamp, DlTileMode::kClamp,
DlImageSampling::kLinear, &kTestMatrix1);
DlImageColorSource source(kTestOpaqueImage, DlTileMode::kClamp,
DlTileMode::kClamp, DlImageSampling::kLinear,
&kTestMatrix1);
ASSERT_NE(source.asImage(), nullptr);
ASSERT_EQ(source.asImage(), &source);
@ -114,10 +91,10 @@ TEST(DisplayListColorSource, ImageAsImage) {
}
TEST(DisplayListColorSource, ImageContents) {
DlImageColorSource source(kTestImage1, DlTileMode::kRepeat,
DlImageColorSource source(kTestOpaqueImage, DlTileMode::kRepeat,
DlTileMode::kMirror, DlImageSampling::kLinear,
&kTestMatrix1);
ASSERT_EQ(source.image(), kTestImage1);
ASSERT_EQ(source.image(), kTestOpaqueImage);
ASSERT_EQ(source.horizontal_tile_mode(), DlTileMode::kRepeat);
ASSERT_EQ(source.vertical_tile_mode(), DlTileMode::kMirror);
ASSERT_EQ(source.sampling(), DlImageSampling::kLinear);
@ -126,10 +103,10 @@ TEST(DisplayListColorSource, ImageContents) {
}
TEST(DisplayListColorSource, AlphaImageContents) {
DlImageColorSource source(kTestAlphaImage1, DlTileMode::kRepeat,
DlImageColorSource source(kTestAlphaImage, DlTileMode::kRepeat,
DlTileMode::kMirror, DlImageSampling::kLinear,
&kTestMatrix1);
ASSERT_EQ(source.image(), kTestAlphaImage1);
ASSERT_EQ(source.image(), kTestAlphaImage);
ASSERT_EQ(source.horizontal_tile_mode(), DlTileMode::kRepeat);
ASSERT_EQ(source.vertical_tile_mode(), DlTileMode::kMirror);
ASSERT_EQ(source.sampling(), DlImageSampling::kLinear);
@ -138,45 +115,45 @@ TEST(DisplayListColorSource, AlphaImageContents) {
}
TEST(DisplayListColorSource, ImageEquals) {
DlImageColorSource source1(kTestImage1, DlTileMode::kClamp,
DlImageColorSource source1(kTestOpaqueImage, DlTileMode::kClamp,
DlTileMode::kMirror, DlImageSampling::kLinear,
&kTestMatrix1);
DlImageColorSource source2(kTestImage1, DlTileMode::kClamp,
DlImageColorSource source2(kTestOpaqueImage, DlTileMode::kClamp,
DlTileMode::kMirror, DlImageSampling::kLinear,
&kTestMatrix1);
TestEquals(source1, source2);
}
TEST(DisplayListColorSource, ImageNotEquals) {
DlImageColorSource source1(kTestImage1, DlTileMode::kClamp,
DlImageColorSource source1(kTestOpaqueImage, DlTileMode::kClamp,
DlTileMode::kMirror, DlImageSampling::kLinear,
&kTestMatrix1);
{
DlImageColorSource source2(kTestAlphaImage1, DlTileMode::kClamp,
DlImageColorSource source2(kTestAlphaImage, DlTileMode::kClamp,
DlTileMode::kMirror, DlImageSampling::kLinear,
&kTestMatrix1);
TestNotEquals(source1, source2, "Image differs");
}
{
DlImageColorSource source2(kTestImage1, DlTileMode::kRepeat,
DlImageColorSource source2(kTestOpaqueImage, DlTileMode::kRepeat,
DlTileMode::kMirror, DlImageSampling::kLinear,
&kTestMatrix1);
TestNotEquals(source1, source2, "hTileMode differs");
}
{
DlImageColorSource source2(kTestImage1, DlTileMode::kClamp,
DlImageColorSource source2(kTestOpaqueImage, DlTileMode::kClamp,
DlTileMode::kRepeat, DlImageSampling::kLinear,
&kTestMatrix1);
TestNotEquals(source1, source2, "vTileMode differs");
}
{
DlImageColorSource source2(kTestImage1, DlTileMode::kClamp,
DlImageColorSource source2(kTestOpaqueImage, DlTileMode::kClamp,
DlTileMode::kMirror, DlImageSampling::kCubic,
&kTestMatrix1);
TestNotEquals(source1, source2, "Sampling differs");
}
{
DlImageColorSource source2(kTestImage1, DlTileMode::kClamp,
DlImageColorSource source2(kTestOpaqueImage, DlTileMode::kClamp,
DlTileMode::kMirror, DlImageSampling::kLinear,
&kTestMatrix2);
TestNotEquals(source1, source2, "Matrix differs");
@ -185,7 +162,7 @@ TEST(DisplayListColorSource, ImageNotEquals) {
TEST(DisplayListColorSource, LinearGradientConstructor) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
}
@ -198,12 +175,12 @@ TEST(DisplayListColorSource, LinearGradientARGBConstructor) {
colors[i * 4 + 3] = kTestColors[i].getBlueF();
}
std::shared_ptr<DlColorSource> source = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, colors.data(), kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
kTestPoints1[0], kTestPoints1[1], kTestStopCount, colors.data(),
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
ASSERT_TRUE(source);
ASSERT_TRUE(source->asLinearGradient());
EXPECT_EQ(source->asLinearGradient()->start_point(), kTestPoints[0]);
EXPECT_EQ(source->asLinearGradient()->end_point(), kTestPoints[1]);
EXPECT_EQ(source->asLinearGradient()->start_point(), kTestPoints1[0]);
EXPECT_EQ(source->asLinearGradient()->end_point(), kTestPoints1[1]);
EXPECT_EQ(source->asLinearGradient()->stop_count(), kTestStopCount);
for (int i = 0; i < kTestStopCount; i++) {
EXPECT_EQ(source->asLinearGradient()->colors()[i],
@ -217,7 +194,7 @@ TEST(DisplayListColorSource, LinearGradientARGBConstructor) {
TEST(DisplayListColorSource, LinearGradientShared) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_NE(source->shared().get(), source.get());
ASSERT_EQ(*source->shared().get(), *source.get());
@ -225,7 +202,7 @@ TEST(DisplayListColorSource, LinearGradientShared) {
TEST(DisplayListColorSource, LinearGradientAsLinear) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_NE(source->asLinearGradient(), nullptr);
ASSERT_EQ(source->asLinearGradient(), source.get());
@ -239,10 +216,10 @@ TEST(DisplayListColorSource, LinearGradientAsLinear) {
TEST(DisplayListColorSource, LinearGradientContents) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_EQ(source->asLinearGradient()->start_point(), kTestPoints[0]);
ASSERT_EQ(source->asLinearGradient()->end_point(), kTestPoints[1]);
ASSERT_EQ(source->asLinearGradient()->start_point(), kTestPoints1[0]);
ASSERT_EQ(source->asLinearGradient()->end_point(), kTestPoints1[1]);
ASSERT_EQ(source->asLinearGradient()->stop_count(), kTestStopCount);
for (int i = 0; i < kTestStopCount; i++) {
ASSERT_EQ(source->asLinearGradient()->colors()[i], kTestColors[i]);
@ -255,10 +232,10 @@ TEST(DisplayListColorSource, LinearGradientContents) {
TEST(DisplayListColorSource, AlphaLinearGradientContents) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestAlphaColors,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestAlphaColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
ASSERT_EQ(source->asLinearGradient()->start_point(), kTestPoints[0]);
ASSERT_EQ(source->asLinearGradient()->end_point(), kTestPoints[1]);
ASSERT_EQ(source->asLinearGradient()->start_point(), kTestPoints1[0]);
ASSERT_EQ(source->asLinearGradient()->end_point(), kTestPoints1[1]);
ASSERT_EQ(source->asLinearGradient()->stop_count(), kTestStopCount);
for (int i = 0; i < kTestStopCount; i++) {
ASSERT_EQ(source->asLinearGradient()->colors()[i], kTestAlphaColors[i]);
@ -271,65 +248,65 @@ TEST(DisplayListColorSource, AlphaLinearGradientContents) {
TEST(DisplayListColorSource, LinearGradientEquals) {
std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
TestEquals(*source1, *source2);
}
TEST(DisplayListColorSource, LinearGradientNotEquals) {
std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeLinear(
kTestPoints2[0], kTestPoints[1], kTestStopCount, kTestColors,
kTestPoints2[0], kTestPoints1[1], kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Point 0 differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints2[1], kTestStopCount, kTestColors,
kTestPoints1[0], kTestPoints2[1], kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Point 1 differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], 2, kTestColors, kTestStops, //
kTestPoints1[0], kTestPoints1[1], 2, kTestColors, kTestStops, //
DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Stop count differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestAlphaColors,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestAlphaColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Colors differ");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors,
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors,
kTestStops2, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Stops differ");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors, kTestStops,
DlTileMode::kMirror, &kTestMatrix1);
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors,
kTestStops, DlTileMode::kMirror, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Tile Mode differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeLinear(
kTestPoints[0], kTestPoints[1], kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix2);
kTestPoints1[0], kTestPoints1[1], kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix2);
TestNotEquals(*source1, *source2, "Matrix differs");
}
}
TEST(DisplayListColorSource, RadialGradientConstructor) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
}
@ -342,11 +319,11 @@ TEST(DisplayListColorSource, RadialGradientARGBConstructor) {
colors[i * 4 + 3] = kTestColors[i].getBlueF();
}
std::shared_ptr<DlColorSource> source = DlColorSource::MakeRadial(
kTestPoints[0], 10.f, kTestStopCount, colors.data(), kTestStops,
kTestPoints1[0], 10.f, kTestStopCount, colors.data(), kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_TRUE(source);
ASSERT_TRUE(source->asRadialGradient());
EXPECT_EQ(source->asRadialGradient()->center(), kTestPoints[0]);
EXPECT_EQ(source->asRadialGradient()->center(), kTestPoints1[0]);
EXPECT_EQ(source->asRadialGradient()->radius(), 10.f);
EXPECT_EQ(source->asRadialGradient()->stop_count(), kTestStopCount);
for (int i = 0; i < kTestStopCount; i++) {
@ -361,7 +338,7 @@ TEST(DisplayListColorSource, RadialGradientARGBConstructor) {
TEST(DisplayListColorSource, RadialGradientShared) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_NE(source->shared().get(), source.get());
ASSERT_EQ(*source->shared().get(), *source.get());
@ -369,7 +346,7 @@ TEST(DisplayListColorSource, RadialGradientShared) {
TEST(DisplayListColorSource, RadialGradientAsRadial) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_NE(source->asRadialGradient(), nullptr);
ASSERT_EQ(source->asRadialGradient(), source.get());
@ -383,9 +360,9 @@ TEST(DisplayListColorSource, RadialGradientAsRadial) {
TEST(DisplayListColorSource, RadialGradientContents) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_EQ(source->asRadialGradient()->center(), kTestPoints[0]);
ASSERT_EQ(source->asRadialGradient()->center(), kTestPoints1[0]);
ASSERT_EQ(source->asRadialGradient()->radius(), 10.0);
ASSERT_EQ(source->asRadialGradient()->stop_count(), kTestStopCount);
for (int i = 0; i < kTestStopCount; i++) {
@ -399,9 +376,9 @@ TEST(DisplayListColorSource, RadialGradientContents) {
TEST(DisplayListColorSource, AlphaRadialGradientContents) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestAlphaColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestAlphaColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_EQ(source->asRadialGradient()->center(), kTestPoints[0]);
ASSERT_EQ(source->asRadialGradient()->center(), kTestPoints1[0]);
ASSERT_EQ(source->asRadialGradient()->radius(), 10.0);
ASSERT_EQ(source->asRadialGradient()->stop_count(), kTestStopCount);
for (int i = 0; i < kTestStopCount; i++) {
@ -415,17 +392,17 @@ TEST(DisplayListColorSource, AlphaRadialGradientContents) {
TEST(DisplayListColorSource, RadialGradientEquals) {
std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
TestEquals(*source1, *source2);
}
TEST(DisplayListColorSource, RadialGradientNotEquals) {
std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeRadial(
@ -435,37 +412,37 @@ TEST(DisplayListColorSource, RadialGradientNotEquals) {
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeRadial(
kTestPoints[0], 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Radius differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, 2, kTestColors, kTestStops, //
kTestPoints1[0], 10.0, 2, kTestColors, kTestStops, //
DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Stop count differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestAlphaColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestAlphaColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Colors differ");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops2,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops2,
DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Stops differ");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kMirror, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Tile Mode differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeRadial(
kTestPoints[0], 10.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix2);
TestNotEquals(*source1, *source2, "Matrix differs");
}
@ -473,7 +450,7 @@ TEST(DisplayListColorSource, RadialGradientNotEquals) {
TEST(DisplayListColorSource, ConicalGradientConstructor) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
}
@ -486,13 +463,13 @@ TEST(DisplayListColorSource, ConicalGradientARGBConstructor) {
colors[i * 4 + 3] = kTestColors[i].getBlueF();
}
std::shared_ptr<DlColorSource> source = DlColorSource::MakeConical(
kTestPoints[0], 10.f, kTestPoints[1], 20.f, kTestStopCount, colors.data(),
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
kTestPoints1[0], 10.f, kTestPoints1[1], 20.f, kTestStopCount,
colors.data(), kTestStops, DlTileMode::kClamp, &kTestMatrix1);
ASSERT_TRUE(source);
ASSERT_TRUE(source->asConicalGradient());
EXPECT_EQ(source->asConicalGradient()->start_center(), kTestPoints[0]);
EXPECT_EQ(source->asConicalGradient()->start_center(), kTestPoints1[0]);
EXPECT_EQ(source->asConicalGradient()->start_radius(), 10.f);
EXPECT_EQ(source->asConicalGradient()->end_center(), kTestPoints[1]);
EXPECT_EQ(source->asConicalGradient()->end_center(), kTestPoints1[1]);
EXPECT_EQ(source->asConicalGradient()->end_radius(), 20.f);
EXPECT_EQ(source->asConicalGradient()->stop_count(), kTestStopCount);
for (int i = 0; i < kTestStopCount; i++) {
@ -507,7 +484,7 @@ TEST(DisplayListColorSource, ConicalGradientARGBConstructor) {
TEST(DisplayListColorSource, ConicalGradientShared) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
ASSERT_NE(source->shared().get(), source.get());
ASSERT_EQ(*source->shared().get(), *source.get());
@ -515,7 +492,7 @@ TEST(DisplayListColorSource, ConicalGradientShared) {
TEST(DisplayListColorSource, ConicalGradientAsConical) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
ASSERT_NE(source->asConicalGradient(), nullptr);
ASSERT_EQ(source->asConicalGradient(), source.get());
@ -529,11 +506,11 @@ TEST(DisplayListColorSource, ConicalGradientAsConical) {
TEST(DisplayListColorSource, ConicalGradientContents) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
ASSERT_EQ(source->asConicalGradient()->start_center(), kTestPoints[0]);
ASSERT_EQ(source->asConicalGradient()->start_center(), kTestPoints1[0]);
ASSERT_EQ(source->asConicalGradient()->start_radius(), 10.0);
ASSERT_EQ(source->asConicalGradient()->end_center(), kTestPoints[1]);
ASSERT_EQ(source->asConicalGradient()->end_center(), kTestPoints1[1]);
ASSERT_EQ(source->asConicalGradient()->end_radius(), 20.0);
ASSERT_EQ(source->asConicalGradient()->stop_count(), kTestStopCount);
for (int i = 0; i < kTestStopCount; i++) {
@ -547,11 +524,11 @@ TEST(DisplayListColorSource, ConicalGradientContents) {
TEST(DisplayListColorSource, AlphaConicalGradientContents) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount,
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount,
kTestAlphaColors, kTestStops, DlTileMode::kClamp, &kTestMatrix1);
ASSERT_EQ(source->asConicalGradient()->start_center(), kTestPoints[0]);
ASSERT_EQ(source->asConicalGradient()->start_center(), kTestPoints1[0]);
ASSERT_EQ(source->asConicalGradient()->start_radius(), 10.0);
ASSERT_EQ(source->asConicalGradient()->end_center(), kTestPoints[1]);
ASSERT_EQ(source->asConicalGradient()->end_center(), kTestPoints1[1]);
ASSERT_EQ(source->asConicalGradient()->end_radius(), 20.0);
ASSERT_EQ(source->asConicalGradient()->stop_count(), kTestStopCount);
for (int i = 0; i < kTestStopCount; i++) {
@ -565,77 +542,77 @@ TEST(DisplayListColorSource, AlphaConicalGradientContents) {
TEST(DisplayListColorSource, ConicalGradientEquals) {
std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestEquals(*source1, *source2);
}
TEST(DisplayListColorSource, ConicalGradientNotEquals) {
std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints2[0], 10.0, kTestPoints[1], 20.0, kTestStopCount,
kTestPoints2[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount,
kTestColors, kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Start Center differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints[0], 15.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
kTestPoints1[0], 15.0, kTestPoints1[1], 20.0, kTestStopCount,
kTestColors, kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Start Radius differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints2[1], 20.0, kTestStopCount,
kTestPoints1[0], 10.0, kTestPoints2[1], 20.0, kTestStopCount,
kTestColors, kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "End Center differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 25.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
kTestPoints1[0], 10.0, kTestPoints1[1], 25.0, kTestStopCount,
kTestColors, kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "End Radius differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, 2, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, 2, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Stop count differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount,
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount,
kTestAlphaColors, kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Colors differ");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestStops2, DlTileMode::kClamp, &kTestMatrix1);
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount,
kTestColors, kTestStops2, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Stops differ");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kMirror, &kTestMatrix1);
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount,
kTestColors, kTestStops, DlTileMode::kMirror, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Tile Mode differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeConical(
kTestPoints[0], 10.0, kTestPoints[1], 20.0, kTestStopCount, kTestColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix2);
kTestPoints1[0], 10.0, kTestPoints1[1], 20.0, kTestStopCount,
kTestColors, kTestStops, DlTileMode::kClamp, &kTestMatrix2);
TestNotEquals(*source1, *source2, "Matrix differs");
}
}
TEST(DisplayListColorSource, SweepGradientConstructor) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
}
@ -648,11 +625,11 @@ TEST(DisplayListColorSource, SweepGradientARGBConstructor) {
colors[i * 4 + 3] = kTestColors[i].getBlueF();
}
std::shared_ptr<DlColorSource> source = DlColorSource::MakeSweep(
kTestPoints[0], 10.f, 20.f, kTestStopCount, colors.data(), kTestStops,
kTestPoints1[0], 10.f, 20.f, kTestStopCount, colors.data(), kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_TRUE(source);
ASSERT_TRUE(source->asSweepGradient());
EXPECT_EQ(source->asSweepGradient()->center(), kTestPoints[0]);
EXPECT_EQ(source->asSweepGradient()->center(), kTestPoints1[0]);
EXPECT_EQ(source->asSweepGradient()->start(), 10.f);
EXPECT_EQ(source->asSweepGradient()->end(), 20.f);
EXPECT_EQ(source->asSweepGradient()->stop_count(), kTestStopCount);
@ -668,7 +645,7 @@ TEST(DisplayListColorSource, SweepGradientARGBConstructor) {
TEST(DisplayListColorSource, SweepGradientShared) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_NE(source->shared().get(), source.get());
ASSERT_EQ(*source->shared().get(), *source.get());
@ -676,7 +653,7 @@ TEST(DisplayListColorSource, SweepGradientShared) {
TEST(DisplayListColorSource, SweepGradientAsSweep) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_NE(source->asSweepGradient(), nullptr);
ASSERT_EQ(source->asSweepGradient(), source.get());
@ -690,9 +667,9 @@ TEST(DisplayListColorSource, SweepGradientAsSweep) {
TEST(DisplayListColorSource, SweepGradientContents) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_EQ(source->asSweepGradient()->center(), kTestPoints[0]);
ASSERT_EQ(source->asSweepGradient()->center(), kTestPoints1[0]);
ASSERT_EQ(source->asSweepGradient()->start(), 10.0);
ASSERT_EQ(source->asSweepGradient()->end(), 20.0);
ASSERT_EQ(source->asSweepGradient()->stop_count(), kTestStopCount);
@ -707,9 +684,9 @@ TEST(DisplayListColorSource, SweepGradientContents) {
TEST(DisplayListColorSource, AlphaSweepGradientContents) {
std::shared_ptr<DlColorSource> source = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestAlphaColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestAlphaColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
ASSERT_EQ(source->asSweepGradient()->center(), kTestPoints[0]);
ASSERT_EQ(source->asSweepGradient()->center(), kTestPoints1[0]);
ASSERT_EQ(source->asSweepGradient()->start(), 10.0);
ASSERT_EQ(source->asSweepGradient()->end(), 20.0);
ASSERT_EQ(source->asSweepGradient()->stop_count(), kTestStopCount);
@ -724,17 +701,17 @@ TEST(DisplayListColorSource, AlphaSweepGradientContents) {
TEST(DisplayListColorSource, SweepGradientEquals) {
std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
TestEquals(*source1, *source2);
}
TEST(DisplayListColorSource, SweepGradientNotEquals) {
std::shared_ptr<DlColorSource> source1 = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeSweep(
@ -744,43 +721,43 @@ TEST(DisplayListColorSource, SweepGradientNotEquals) {
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeSweep(
kTestPoints[0], 15.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 15.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Start Angle differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 25.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 25.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "End Angle differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, 2, kTestColors, kTestStops, //
kTestPoints1[0], 10.0, 20.0, 2, kTestColors, kTestStops, //
DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Stop count differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestAlphaColors,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestAlphaColors,
kTestStops, DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Colors differ");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops2,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops2,
DlTileMode::kClamp, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Stops differ");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kMirror, &kTestMatrix1);
TestNotEquals(*source1, *source2, "Tile Mode differs");
}
{
std::shared_ptr<DlColorSource> source2 = DlColorSource::MakeSweep(
kTestPoints[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
kTestPoints1[0], 10.0, 20.0, kTestStopCount, kTestColors, kTestStops,
DlTileMode::kClamp, &kTestMatrix2);
TestNotEquals(*source1, *source2, "Matrix differs");
}
@ -806,8 +783,8 @@ TEST(DisplayListColorSource, RuntimeEffect) {
TestEquals(source1, source1);
TestEquals(source3, source3);
TestNotEquals(source1, source2, "SkRuntimeEffect differs");
TestNotEquals(source2, source3, "SkRuntimeEffect differs");
TestNotEquals(source1, source2, "RuntimeEffect differs");
TestNotEquals(source2, source3, "RuntimeEffect differs");
}
} // namespace testing

View File

@ -6,6 +6,7 @@
#define FLUTTER_DISPLAY_LIST_GEOMETRY_DL_GEOMETRY_TYPES_H_
#include "flutter/impeller/geometry/matrix.h"
#include "flutter/impeller/geometry/path.h"
#include "flutter/impeller/geometry/rect.h"
#include "flutter/impeller/geometry/round_rect.h"
#include "flutter/impeller/geometry/scalar.h"
@ -30,6 +31,7 @@ using DlISize = impeller::ISize32;
using DlRect = impeller::Rect;
using DlIRect = impeller::IRect32;
using DlRoundRect = impeller::RoundRect;
using DlRoundingRadii = impeller::RoundingRadii;
using DlMatrix = impeller::Matrix;
using DlQuad = impeller::Quad;

View File

@ -10,7 +10,13 @@
namespace flutter {
DlPath DlPath::MakeRect(DlRect rect) {
using Path = impeller::Path;
using PathBuilder = impeller::PathBuilder;
using FillType = impeller::FillType;
using Convexity = impeller::Convexity;
using ComponentType = impeller::Path::ComponentType;
DlPath DlPath::MakeRect(const DlRect& rect) {
return DlPath(SkPath::Rect(ToSkRect(rect)));
}
@ -28,7 +34,7 @@ DlPath DlPath::MakeRectXYWH(DlScalar x,
return DlPath(SkPath().addRect(SkRect::MakeXYWH(x, y, width, height)));
}
DlPath DlPath::MakeOval(DlRect bounds) {
DlPath DlPath::MakeOval(const DlRect& bounds) {
return DlPath(SkPath::Oval(ToSkRect(bounds)));
}
@ -39,86 +45,238 @@ DlPath DlPath::MakeOvalLTRB(DlScalar left,
return DlPath(SkPath::Oval(SkRect::MakeLTRB(left, top, right, bottom)));
}
const SkPath& DlPath::GetSkPath() const {
return data_->sk_path;
DlPath DlPath::MakeCircle(const DlPoint& center, DlScalar radius) {
return DlPath(SkPath::Circle(center.x, center.y, radius));
}
impeller::Path DlPath::GetPath() const {
if (!data_->path.has_value()) {
data_->path = ConvertToImpellerPath(data_->sk_path);
}
DlPath DlPath::MakeRoundRect(const DlRoundRect& rrect) {
return DlPath(SkPath::RRect(ToSkRRect(rrect)));
}
// Covered by check above.
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
return data_->path.value();
DlPath DlPath::MakeRoundRectXY(const DlRect& rect,
DlScalar x_radius,
DlScalar y_radius,
bool counter_clock_wise) {
return DlPath(SkPath::RRect(
ToSkRect(rect), x_radius, y_radius,
counter_clock_wise ? SkPathDirection::kCCW : SkPathDirection::kCW));
}
const SkPath& DlPath::GetSkPath() const {
auto& sk_path = data_->sk_path;
auto& path = data_->path;
if (sk_path.has_value()) {
return sk_path.value();
}
if (path.has_value()) {
sk_path.emplace(ConvertToSkiaPath(path.value()));
if (data_->render_count >= kMaxVolatileUses) {
sk_path.value().setIsVolatile(false);
}
return sk_path.value();
}
sk_path.emplace();
return sk_path.value();
}
Path DlPath::GetPath() const {
auto& sk_path = data_->sk_path;
auto& path = data_->path;
if (path.has_value()) {
return path.value();
}
if (sk_path.has_value()) {
path.emplace(ConvertToImpellerPath(sk_path.value()));
return path.value();
}
path.emplace();
return path.value();
}
void DlPath::WillRenderSkPath() const {
if (data_->render_count >= kMaxVolatileUses) {
data_->sk_path.setIsVolatile(false);
auto& sk_path = data_->sk_path;
if (sk_path.has_value()) {
sk_path.value().setIsVolatile(false);
}
} else {
data_->render_count++;
}
}
bool DlPath::IsInverseFillType() const {
return data_->sk_path.isInverseFillType();
[[nodiscard]] DlPath DlPath::WithOffset(const DlPoint& offset) const {
if (offset.IsZero()) {
return *this;
}
if (!offset.IsFinite()) {
return DlPath();
}
auto& path = data_->path;
if (path.has_value()) {
PathBuilder builder;
builder.AddPath(path.value());
builder.Shift(offset);
return DlPath(builder.TakePath());
}
auto& sk_path = data_->sk_path;
if (sk_path.has_value()) {
SkPath path = sk_path.value();
path = path.offset(offset.x, offset.y);
return DlPath(path);
}
return *this;
}
[[nodiscard]] DlPath DlPath::WithFillType(DlPathFillType type) const {
auto& path = data_->path;
if (path.has_value()) {
if (path.value().GetFillType() == type) {
return *this;
}
PathBuilder builder;
builder.AddPath(path.value());
return DlPath(builder.TakePath(type));
}
auto& sk_path = data_->sk_path;
if (sk_path.has_value()) {
SkPathFillType sk_type = ToSkFillType(type);
if (sk_path.value().getFillType() == sk_type) {
return *this;
}
SkPath path = sk_path.value();
path.setFillType(sk_type);
return DlPath(path);
}
return *this;
}
bool DlPath::IsRect(DlRect* rect, bool* is_closed) const {
return data_->sk_path.isRect(ToSkRect(rect), is_closed);
return GetSkPath().isRect(ToSkRect(rect), is_closed);
}
bool DlPath::IsOval(DlRect* bounds) const {
return data_->sk_path.isOval(ToSkRect(bounds));
return GetSkPath().isOval(ToSkRect(bounds));
}
bool DlPath::IsRoundRect(DlRoundRect* rrect) const {
SkRRect sk_rrect;
bool ret = GetSkPath().isRRect(rrect ? &sk_rrect : nullptr);
if (rrect) {
*rrect = ToDlRoundRect(sk_rrect);
}
return ret;
}
bool DlPath::IsSkRect(SkRect* rect, bool* is_closed) const {
return data_->sk_path.isRect(rect, is_closed);
return GetSkPath().isRect(rect, is_closed);
}
bool DlPath::IsSkOval(SkRect* bounds) const {
return data_->sk_path.isOval(bounds);
return GetSkPath().isOval(bounds);
}
bool DlPath::IsSkRRect(SkRRect* rrect) const {
return data_->sk_path.isRRect(rrect);
return GetSkPath().isRRect(rrect);
}
bool DlPath::Contains(const DlPoint& point) const {
return GetSkPath().contains(point.x, point.y);
}
SkRect DlPath::GetSkBounds() const {
return data_->sk_path.getBounds();
return GetSkPath().getBounds();
}
DlRect DlPath::GetBounds() const {
return ToDlRect(data_->sk_path.getBounds());
auto& path = data_->path;
if (path.has_value()) {
return path.value().GetBoundingBox().value_or(DlRect());
}
return ToDlRect(GetSkPath().getBounds());
}
bool DlPath::operator==(const DlPath& other) const {
return data_->sk_path == other.data_->sk_path;
return GetSkPath() == other.GetSkPath();
}
bool DlPath::IsConverted() const {
return data_->path.has_value();
return data_->path.has_value() && data_->sk_path.has_value();
}
bool DlPath::IsVolatile() const {
return data_->sk_path.isVolatile();
return GetSkPath().isVolatile();
}
DlPath DlPath::operator+(const DlPath& other) const {
SkPath path = data_->sk_path;
path.addPath(other.data_->sk_path);
SkPath path = GetSkPath();
path.addPath(other.GetSkPath());
return DlPath(path);
}
using Path = impeller::Path;
using PathBuilder = impeller::PathBuilder;
using FillType = impeller::FillType;
using Convexity = impeller::Convexity;
DlPath::Data::Data(const SkPath& path) : sk_path(path) {
FML_DCHECK(!SkPathFillType_IsInverse(path.getFillType()));
}
SkPath DlPath::ConvertToSkiaPath(const Path& path, const DlPoint& shift) {
SkPath sk_path;
sk_path.setFillType(ToSkFillType(path.GetFillType()));
bool subpath_needs_close = false;
std::optional<DlPoint> pending_moveto;
auto resolve_moveto = [&pending_moveto, &sk_path]() {
if (pending_moveto.has_value()) {
sk_path.moveTo(ToSkPoint(pending_moveto.value()));
pending_moveto.reset();
}
};
size_t count = path.GetComponentCount();
for (size_t i = 0; i < count; i++) {
switch (path.GetComponentTypeAtIndex(i)) {
case ComponentType::kContour: {
impeller::ContourComponent contour;
path.GetContourComponentAtIndex(i, contour);
if (subpath_needs_close) {
sk_path.close();
}
pending_moveto = contour.destination;
subpath_needs_close = contour.IsClosed();
break;
}
case ComponentType::kLinear: {
impeller::LinearPathComponent linear;
path.GetLinearComponentAtIndex(i, linear);
resolve_moveto();
sk_path.lineTo(ToSkPoint(linear.p2));
break;
}
case ComponentType::kQuadratic: {
impeller::QuadraticPathComponent quadratic;
path.GetQuadraticComponentAtIndex(i, quadratic);
resolve_moveto();
sk_path.quadTo(ToSkPoint(quadratic.cp), ToSkPoint(quadratic.p2));
break;
}
case ComponentType::kCubic: {
impeller::CubicPathComponent cubic;
path.GetCubicComponentAtIndex(i, cubic);
resolve_moveto();
sk_path.cubicTo(ToSkPoint(cubic.cp1), ToSkPoint(cubic.cp2),
ToSkPoint(cubic.p2));
break;
}
}
}
if (subpath_needs_close) {
sk_path.close();
}
return sk_path;
}
Path DlPath::ConvertToImpellerPath(const SkPath& path, const DlPoint& shift) {
if (path.isEmpty()) {
return impeller::Path{};
if (path.isEmpty() || !shift.IsFinite()) {
return Path{};
}
auto iterator = SkPath::Iter(path, false);
@ -190,14 +348,13 @@ Path DlPath::ConvertToImpellerPath(const SkPath& path, const DlPoint& shift) {
break;
case SkPathFillType::kInverseWinding:
case SkPathFillType::kInverseEvenOdd:
// Flutter doesn't expose these path fill types. These are only visible
// via the receiver interface. We should never get here.
fill_type = FillType::kNonZero;
break;
FML_UNREACHABLE();
}
builder.SetConvexity(path.isConvex() ? Convexity::kConvex
: Convexity::kUnknown);
builder.Shift(shift);
if (!shift.IsZero()) {
builder.Shift(shift);
}
auto sk_bounds = path.getBounds().makeOutset(shift.x, shift.y);
builder.SetBounds(ToDlRect(sk_bounds));
return builder.TakePath(fill_type);

View File

@ -7,15 +7,19 @@
#include "flutter/display_list/geometry/dl_geometry_types.h"
#include "flutter/impeller/geometry/path.h"
#include "flutter/impeller/geometry/path_builder.h"
#include "flutter/third_party/skia/include/core/SkPath.h"
namespace flutter {
using DlPathFillType = impeller::FillType;
using DlPathBuilder = impeller::PathBuilder;
class DlPath {
public:
static constexpr uint32_t kMaxVolatileUses = 2;
static DlPath MakeRect(DlRect rect);
static DlPath MakeRect(const DlRect& rect);
static DlPath MakeRectLTRB(DlScalar left,
DlScalar top,
DlScalar right,
@ -25,14 +29,24 @@ class DlPath {
DlScalar width,
DlScalar height);
static DlPath MakeOval(DlRect bounds);
static DlPath MakeOval(const DlRect& bounds);
static DlPath MakeOvalLTRB(DlScalar left,
DlScalar top,
DlScalar right,
DlScalar bottom);
static DlPath MakeCircle(const DlPoint& center, DlScalar radius);
static DlPath MakeRoundRect(const DlRoundRect& rrect);
static DlPath MakeRoundRectXY(const DlRect& rect,
DlScalar x_radius,
DlScalar y_radius,
bool counter_clock_wise = false);
DlPath() : data_(std::make_shared<Data>(SkPath())) {}
explicit DlPath(const SkPath& path) : data_(std::make_shared<Data>(path)) {}
explicit DlPath(const impeller::Path& path)
: data_(std::make_shared<Data>(path)) {}
DlPath(const DlPath& path) = default;
DlPath(DlPath&& path) = default;
@ -49,15 +63,19 @@ class DlPath {
/// @see |kMaxVolatileUses|
void WillRenderSkPath() const;
bool IsInverseFillType() const;
[[nodiscard]] DlPath WithOffset(const DlPoint& offset) const;
[[nodiscard]] DlPath WithFillType(DlPathFillType type) const;
bool IsRect(DlRect* rect, bool* is_closed = nullptr) const;
bool IsOval(DlRect* bounds) const;
bool IsRect(DlRect* rect = nullptr, bool* is_closed = nullptr) const;
bool IsOval(DlRect* bounds = nullptr) const;
bool IsRoundRect(DlRoundRect* rrect = nullptr) const;
bool IsSkRect(SkRect* rect, bool* is_closed = nullptr) const;
bool IsSkOval(SkRect* bounds) const;
bool IsSkRRect(SkRRect* rrect) const;
bool Contains(const DlPoint& point) const;
SkRect GetSkBounds() const;
DlRect GetBounds() const;
@ -66,20 +84,46 @@ class DlPath {
bool IsConverted() const;
bool IsVolatile() const;
bool IsEvenOdd() const;
DlPath operator+(const DlPath& other) const;
private:
struct Data {
explicit Data(const SkPath& path) : sk_path(path) {}
explicit Data(const SkPath& path);
explicit Data(const impeller::Path& path) : path(path) {}
SkPath sk_path;
std::optional<SkPath> sk_path;
std::optional<impeller::Path> path;
uint32_t render_count = 0u;
};
inline constexpr static DlPathFillType ToDlFillType(SkPathFillType sk_type) {
switch (sk_type) {
case SkPathFillType::kEvenOdd:
return impeller::FillType::kOdd;
case SkPathFillType::kWinding:
return impeller::FillType::kNonZero;
case SkPathFillType::kInverseEvenOdd:
case SkPathFillType::kInverseWinding:
FML_UNREACHABLE();
}
}
inline constexpr static SkPathFillType ToSkFillType(DlPathFillType dl_type) {
switch (dl_type) {
case impeller::FillType::kOdd:
return SkPathFillType::kEvenOdd;
case impeller::FillType::kNonZero:
return SkPathFillType::kWinding;
}
}
std::shared_ptr<Data> data_;
static SkPath ConvertToSkiaPath(const impeller::Path& path,
const DlPoint& shift = DlPoint());
static impeller::Path ConvertToImpellerPath(const SkPath& path,
const DlPoint& shift = DlPoint());
};

View File

@ -13,11 +13,39 @@ namespace testing {
TEST(DisplayListPath, DefaultConstruction) {
DlPath path;
EXPECT_FALSE(path.IsConverted());
EXPECT_EQ(path, DlPath());
EXPECT_EQ(path.GetSkPath(), SkPath());
EXPECT_TRUE(path.GetPath().IsEmpty());
EXPECT_TRUE(path.IsConverted());
EXPECT_FALSE(path.IsInverseFillType());
EXPECT_FALSE(path.IsVolatile());
bool is_closed = false;
EXPECT_FALSE(path.IsRect(nullptr));
EXPECT_FALSE(path.IsRect(nullptr, &is_closed));
EXPECT_FALSE(is_closed);
EXPECT_FALSE(path.IsOval(nullptr));
is_closed = false;
EXPECT_FALSE(path.IsSkRect(nullptr));
EXPECT_FALSE(path.IsSkRect(nullptr, &is_closed));
EXPECT_FALSE(is_closed);
EXPECT_FALSE(path.IsSkOval(nullptr));
EXPECT_FALSE(path.IsSkRRect(nullptr));
EXPECT_EQ(path.GetBounds(), DlRect());
EXPECT_EQ(path.GetSkBounds(), SkRect());
}
TEST(DisplayListPath, ConstructFromEmptySkiaPath) {
SkPath sk_path;
DlPath path(sk_path);
EXPECT_EQ(path, DlPath());
EXPECT_EQ(path.GetSkPath(), SkPath());
EXPECT_FALSE(path.IsConverted());
EXPECT_TRUE(path.GetPath().IsEmpty());
EXPECT_TRUE(path.IsConverted());
EXPECT_FALSE(path.IsVolatile());
@ -39,19 +67,19 @@ TEST(DisplayListPath, DefaultConstruction) {
EXPECT_EQ(path.GetSkBounds(), SkRect());
}
TEST(DisplayListPath, ConstructFromEmpty) {
SkPath sk_path;
DlPath path(sk_path);
TEST(DisplayListPath, ConstructFromEmptyImpellerPath) {
impeller::Path imp_path;
DlPath path(imp_path);
EXPECT_EQ(path, DlPath());
EXPECT_EQ(path.GetSkPath(), SkPath());
EXPECT_FALSE(path.IsInverseFillType());
EXPECT_FALSE(path.IsConverted());
EXPECT_TRUE(path.GetPath().IsEmpty());
EXPECT_FALSE(path.IsConverted());
EXPECT_EQ(path.GetSkPath(), SkPath());
EXPECT_TRUE(path.IsConverted());
EXPECT_FALSE(path.IsVolatile());
EXPECT_EQ(path, DlPath());
bool is_closed = false;
EXPECT_FALSE(path.IsRect(nullptr));
EXPECT_FALSE(path.IsRect(nullptr, &is_closed));
@ -78,7 +106,6 @@ TEST(DisplayListPath, CopyConstruct) {
EXPECT_EQ(path2, DlPath(SkPath::Oval(SkRect::MakeLTRB(10, 10, 20, 20))));
EXPECT_EQ(path2.GetSkPath(), SkPath::Oval(SkRect::MakeLTRB(10, 10, 20, 20)));
EXPECT_FALSE(path2.IsInverseFillType());
EXPECT_FALSE(path2.IsConverted());
EXPECT_FALSE(path2.IsVolatile());
@ -107,7 +134,6 @@ TEST(DisplayListPath, ConstructFromVolatile) {
EXPECT_EQ(path, DlPath());
EXPECT_EQ(path.GetSkPath(), SkPath());
EXPECT_FALSE(path.IsInverseFillType());
EXPECT_FALSE(path.IsConverted());
EXPECT_TRUE(path.GetPath().IsEmpty());
EXPECT_TRUE(path.IsConverted());
@ -217,8 +243,6 @@ TEST(DisplayListPath, EmbeddingSharedReference) {
SkPath::Oval(SkRect::MakeLTRB(10, 10, 20, 20)))
<< label;
EXPECT_FALSE(path_.IsInverseFillType()) << label;
bool is_closed = false;
EXPECT_FALSE(path_.IsRect(nullptr)) << label;
EXPECT_FALSE(path_.IsRect(nullptr, &is_closed)) << label;
@ -261,7 +285,6 @@ TEST(DisplayListPath, ConstructFromRect) {
EXPECT_EQ(path, DlPath(SkPath::Rect(SkRect::MakeLTRB(10, 10, 20, 20))));
EXPECT_EQ(path.GetSkPath(), SkPath::Rect(SkRect::MakeLTRB(10, 10, 20, 20)));
EXPECT_FALSE(path.IsInverseFillType());
EXPECT_FALSE(path.IsConverted());
EXPECT_FALSE(path.GetPath().IsEmpty());
EXPECT_TRUE(path.IsConverted());
@ -294,7 +317,6 @@ TEST(DisplayListPath, ConstructFromOval) {
EXPECT_EQ(path, DlPath(SkPath::Oval(SkRect::MakeLTRB(10, 10, 20, 20))));
EXPECT_EQ(path.GetSkPath(), SkPath::Oval(SkRect::MakeLTRB(10, 10, 20, 20)));
EXPECT_FALSE(path.IsInverseFillType());
EXPECT_FALSE(path.IsConverted());
EXPECT_FALSE(path.GetPath().IsEmpty());
EXPECT_TRUE(path.IsConverted());
@ -325,7 +347,6 @@ TEST(DisplayListPath, ConstructFromRRect) {
EXPECT_EQ(path.GetSkPath(),
SkPath::RRect(SkRect::MakeLTRB(10, 10, 20, 20), 1, 2));
EXPECT_FALSE(path.IsInverseFillType());
EXPECT_FALSE(path.IsConverted());
EXPECT_FALSE(path.GetPath().IsEmpty());
EXPECT_TRUE(path.IsConverted());
@ -361,7 +382,6 @@ TEST(DisplayListPath, ConstructFromPath) {
EXPECT_EQ(path, DlPath(sk_path2));
EXPECT_EQ(path.GetSkPath(), sk_path2);
EXPECT_FALSE(path.IsInverseFillType());
EXPECT_FALSE(path.IsConverted());
EXPECT_FALSE(path.GetPath().IsEmpty());
EXPECT_TRUE(path.IsConverted());
@ -376,38 +396,51 @@ TEST(DisplayListPath, ConstructFromPath) {
EXPECT_EQ(path.GetSkBounds(), SkRect::MakeLTRB(10, 10, 20, 20));
}
TEST(DisplayListPath, ConstructFromInversePath) {
SkPath sk_path1;
sk_path1.moveTo(10, 10);
sk_path1.lineTo(20, 20);
sk_path1.lineTo(20, 10);
sk_path1.setFillType(SkPathFillType::kInverseWinding);
SkPath sk_path2;
sk_path2.moveTo(10, 10);
sk_path2.lineTo(20, 20);
sk_path2.lineTo(20, 10);
sk_path2.setFillType(SkPathFillType::kInverseWinding);
DlPath path(sk_path1);
TEST(DisplayListPath, ConstructFromImpellerEqualsConstructFromSkia) {
DlPathBuilder path_builder;
path_builder.MoveTo({0, 0});
path_builder.LineTo({100, 0});
path_builder.LineTo({0, 100});
path_builder.Close();
ASSERT_EQ(sk_path1, sk_path2);
SkPath sk_path;
sk_path.setFillType(SkPathFillType::kWinding);
sk_path.moveTo(0, 0);
sk_path.lineTo(100, 0);
sk_path.lineTo(0, 100);
sk_path.lineTo(0, 0); // Shouldn't be needed, but PathBuilder draws this
sk_path.close();
EXPECT_EQ(path, DlPath(sk_path2));
EXPECT_EQ(path.GetSkPath(), sk_path2);
EXPECT_TRUE(path.IsInverseFillType());
EXPECT_FALSE(path.IsConverted());
EXPECT_FALSE(path.GetPath().IsEmpty());
EXPECT_TRUE(path.IsConverted());
EXPECT_FALSE(path.IsRect(nullptr));
EXPECT_FALSE(path.IsOval(nullptr));
EXPECT_FALSE(path.IsSkRect(nullptr));
EXPECT_FALSE(path.IsSkOval(nullptr));
EXPECT_FALSE(path.IsSkRRect(nullptr));
EXPECT_EQ(path.GetBounds(), DlRect::MakeLTRB(10, 10, 20, 20));
EXPECT_EQ(path.GetSkBounds(), SkRect::MakeLTRB(10, 10, 20, 20));
EXPECT_EQ(DlPath(path_builder.TakePath(DlPathFillType::kNonZero)),
DlPath(sk_path));
}
#ifndef NDEBUG
// Tests that verify we don't try to use inverse path modes as they aren't
// supported by either Flutter public APIs or Impeller
TEST(DisplayListPath, CannotConstructFromSkiaInverseWinding) {
SkPath sk_path;
sk_path.setFillType(SkPathFillType::kInverseWinding);
sk_path.moveTo(0, 0);
sk_path.lineTo(100, 0);
sk_path.lineTo(0, 100);
sk_path.close();
EXPECT_DEATH_IF_SUPPORTED(new DlPath(sk_path), "SkPathFillType_IsInverse");
}
TEST(DisplayListPath, CannotConstructFromSkiaInverseEvenOdd) {
SkPath sk_path;
sk_path.setFillType(SkPathFillType::kInverseEvenOdd);
sk_path.moveTo(0, 0);
sk_path.lineTo(100, 0);
sk_path.lineTo(0, 100);
sk_path.close();
EXPECT_DEATH_IF_SUPPORTED(new DlPath(sk_path), "SkPathFillType_IsInverse");
}
#endif
} // namespace testing
} // namespace flutter

View File

@ -5,6 +5,7 @@
#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 "flutter/display_list/skia/dl_sk_canvas.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "txt/platform.h"
@ -13,34 +14,68 @@ 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()));
DisplayListBuilder builder(DlRect::MakeWH(150, 100));
builder.DrawRect(DlRect::MakeXYWH(10, 10, 80, 80), DlPaint(DlColor::kRed()));
return builder.Build();
}
sk_sp<DisplayList> GetSampleNestedDisplayList() {
DisplayListBuilder builder(SkRect::MakeWH(150, 100));
DisplayListBuilder builder(DlRect::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);
builder.DrawRect(DlRect::MakeXYWH(x, y, 80, 80), paint);
}
}
DisplayListBuilder outer_builder(SkRect::MakeWH(150, 100));
DisplayListBuilder outer_builder(DlRect::MakeWH(150, 100));
outer_builder.DrawDisplayList(builder.Build());
return outer_builder.Build();
}
sk_sp<DisplayList> GetSampleDisplayList(int ops) {
DisplayListBuilder builder(SkRect::MakeWH(150, 100));
DisplayListBuilder builder(DlRect::MakeWH(150, 100));
for (int i = 0; i < ops; i++) {
builder.DrawColor(DlColor::kRed(), DlBlendMode::kSrc);
}
return builder.Build();
}
sk_sp<DlImage> MakeTestImage(int w, int h, int checker_size) {
sk_sp<SkSurface> surface =
SkSurfaces::Raster(SkImageInfo::MakeN32Premul(w, h));
DlSkCanvasAdapter canvas(surface->getCanvas());
DlPaint p0, p1;
p0.setDrawStyle(DlDrawStyle::kFill);
p0.setColor(DlColor::kGreen());
p1.setDrawStyle(DlDrawStyle::kFill);
p1.setColor(DlColor::kBlue());
p1.setAlpha(128);
for (int y = 0; y < w; y += checker_size) {
for (int x = 0; x < h; x += checker_size) {
DlPaint& cellp = ((x + y) & 1) == 0 ? p0 : p1;
canvas.DrawRect(DlRect::MakeXYWH(x, y, checker_size, checker_size),
cellp);
}
}
return DlImage::Make(surface->makeImageSnapshot());
}
sk_sp<DlImage> MakeTestImage(int w, int h, DlColor color) {
sk_sp<SkSurface> surface;
if (!color.isOpaque()) {
surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(w, h));
} else {
SkImageInfo info =
SkImageInfo::MakeN32(w, h, SkAlphaType::kOpaque_SkAlphaType);
surface = SkSurfaces::Raster(info);
}
SkCanvas* canvas = surface->getCanvas();
canvas->drawColor(color.argb());
return DlImage::Make(surface->makeImageSnapshot());
}
// ---------------
// Test Suite data
// ---------------
@ -734,22 +769,22 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
{1, 8 + TestPointCount * 8, 1,
[](DlOpReceiver& r) {
r.drawPoints(DlCanvas::PointMode::kPoints, TestPointCount,
ToDlPoints(kTestPoints));
kTestPoints);
}},
{1, 8 + (TestPointCount - 1) * 8, 1,
[](DlOpReceiver& r) {
r.drawPoints(DlCanvas::PointMode::kPoints, TestPointCount - 1,
ToDlPoints(kTestPoints));
kTestPoints);
}},
{1, 8 + TestPointCount * 8, 1,
[](DlOpReceiver& r) {
r.drawPoints(DlCanvas::PointMode::kLines, TestPointCount,
ToDlPoints(kTestPoints));
kTestPoints);
}},
{1, 8 + TestPointCount * 8, 1,
[](DlOpReceiver& r) {
r.drawPoints(DlCanvas::PointMode::kPolygon, TestPointCount,
ToDlPoints(kTestPoints));
kTestPoints);
}},
}},
{"DrawVertices",
@ -771,31 +806,31 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
{
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {10, 10}, kNearestSampling, false);
r.drawImage(kTestImage1, {10, 10}, kNearestSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {10, 10}, kNearestSampling, true);
r.drawImage(kTestImage1, {10, 10}, kNearestSampling, true);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {20, 10}, kNearestSampling, false);
r.drawImage(kTestImage1, {20, 10}, kNearestSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {10, 20}, kNearestSampling, false);
r.drawImage(kTestImage1, {10, 20}, kNearestSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage1, {10, 10}, kLinearSampling, false);
r.drawImage(kTestImage1, {10, 10}, kLinearSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
r.drawImage(TestImage2, {10, 10}, kNearestSampling, false);
r.drawImage(kTestImage2, {10, 10}, kNearestSampling, false);
}},
{1, 24, 1,
[](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
auto dl_image = DlImage::Make(kTestSkImage);
r.drawImage(dl_image, {10, 10}, kNearestSampling, false);
}},
}},
@ -803,55 +838,55 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
{
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
r.drawImageRect(kTestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(10, 10, 80, 80),
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
r.drawImageRect(kTestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(10, 10, 80, 80),
kNearestSampling, true,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
r.drawImageRect(kTestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(10, 10, 80, 80),
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kStrict);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, DlRect::MakeLTRB(10, 10, 25, 20),
r.drawImageRect(kTestImage1, DlRect::MakeLTRB(10, 10, 25, 20),
DlRect::MakeLTRB(10, 10, 80, 80),
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
r.drawImageRect(kTestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(10, 10, 85, 80),
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
r.drawImageRect(kTestImage1, DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(10, 10, 80, 80), kLinearSampling,
false, DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
r.drawImageRect(TestImage2, DlRect::MakeLTRB(10, 10, 15, 15),
r.drawImageRect(kTestImage2, DlRect::MakeLTRB(10, 10, 15, 15),
DlRect::MakeLTRB(10, 10, 80, 80),
kNearestSampling, false,
DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, 1,
[](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
auto dl_image = DlImage::Make(kTestSkImage);
r.drawImageRect(dl_image, DlRect::MakeLTRB(10, 10, 15, 15),
DlRect::MakeLTRB(10, 10, 80, 80),
kNearestSampling, false,
@ -862,43 +897,43 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
{
{1, 48, 9,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, DlIRect::MakeLTRB(10, 10, 20, 20),
r.drawImageNine(kTestImage1, DlIRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(10, 10, 80, 80),
DlFilterMode::kNearest, false);
}},
{1, 48, 9,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, DlIRect::MakeLTRB(10, 10, 20, 20),
r.drawImageNine(kTestImage1, DlIRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(10, 10, 80, 80),
DlFilterMode::kNearest, true);
}},
{1, 48, 9,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, DlIRect::MakeLTRB(10, 10, 25, 20),
r.drawImageNine(kTestImage1, DlIRect::MakeLTRB(10, 10, 25, 20),
DlRect::MakeLTRB(10, 10, 80, 80),
DlFilterMode::kNearest, false);
}},
{1, 48, 9,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, DlIRect::MakeLTRB(10, 10, 20, 20),
r.drawImageNine(kTestImage1, DlIRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(10, 10, 85, 80),
DlFilterMode::kNearest, false);
}},
{1, 48, 9,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage1, DlIRect::MakeLTRB(10, 10, 20, 20),
r.drawImageNine(kTestImage1, DlIRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(10, 10, 80, 80),
DlFilterMode::kLinear, false);
}},
{1, 48, 9,
[](DlOpReceiver& r) {
r.drawImageNine(TestImage2, DlIRect::MakeLTRB(10, 10, 15, 15),
r.drawImageNine(kTestImage2, DlIRect::MakeLTRB(10, 10, 15, 15),
DlRect::MakeLTRB(10, 10, 80, 80),
DlFilterMode::kNearest, false);
}},
{1, 48, 9,
[](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
auto dl_image = DlImage::Make(kTestSkImage);
r.drawImageNine(dl_image, DlIRect::MakeLTRB(10, 10, 15, 15),
DlRect::MakeLTRB(10, 10, 80, 80),
DlFilterMode::kNearest, false);
@ -911,7 +946,7 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static DlRect texs[] = {DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(20, 20, 30, 30)};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
r.drawAtlas(kTestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
@ -920,7 +955,7 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static DlRect texs[] = {DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(20, 20, 30, 30)};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
r.drawAtlas(kTestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr, true);
}},
{1, 48 + 32 + 8, 1,
@ -928,7 +963,7 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
static SkRSXform xforms[] = {{0, 1, 0, 0}, {0, 1, 0, 0}};
static DlRect texs[] = {DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(20, 20, 30, 30)};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
r.drawAtlas(kTestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
@ -937,7 +972,7 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static DlRect texs[] = {DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(20, 25, 30, 30)};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
r.drawAtlas(kTestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
@ -946,7 +981,7 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static DlRect texs[] = {DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(20, 20, 30, 30)};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
r.drawAtlas(kTestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kLinearSampling, nullptr, false);
}},
{1, 48 + 32 + 8, 1,
@ -954,7 +989,7 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static DlRect texs[] = {DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(20, 20, 30, 30)};
r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
r.drawAtlas(kTestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kDstIn, kNearestSampling, nullptr,
false);
}},
@ -964,7 +999,7 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
static DlRect texs[] = {DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(20, 20, 30, 30)};
static DlRect cull_rect = DlRect::MakeLTRB(0, 0, 200, 200);
r.drawAtlas(TestImage2, xforms, texs, nullptr, 2,
r.drawAtlas(kTestImage2, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, &cull_rect,
false);
}},
@ -974,7 +1009,7 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
static DlRect texs[] = {DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(20, 20, 30, 30)};
static DlColor colors[] = {DlColor::kBlue(), DlColor::kGreen()};
r.drawAtlas(TestImage1, xforms, texs, colors, 2,
r.drawAtlas(kTestImage1, xforms, texs, colors, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
@ -985,13 +1020,13 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
DlRect::MakeLTRB(20, 20, 30, 30)};
static DlColor colors[] = {DlColor::kBlue(), DlColor::kGreen()};
static DlRect cull_rect = DlRect::MakeLTRB(0, 0, 200, 200);
r.drawAtlas(TestImage1, xforms, texs, colors, 2,
r.drawAtlas(kTestImage1, xforms, texs, colors, 2,
DlBlendMode::kSrcIn, kNearestSampling, &cull_rect,
false);
}},
{1, 48 + 32 + 8, 1,
[](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
auto dl_image = DlImage::Make(kTestSkImage);
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static DlRect texs[] = {DlRect::MakeLTRB(10, 10, 20, 20),
DlRect::MakeLTRB(20, 20, 30, 30)};
@ -1086,7 +1121,7 @@ std::vector<DisplayListInvocationGroup> CreateAllGroups() {
return result;
}
SkFont CreateTestFontOfSize(SkScalar scalar) {
SkFont CreateTestFontOfSize(DlScalar scalar) {
static constexpr const char* kTestFontFixture = "Roboto-Regular.ttf";
auto mapping = flutter::testing::OpenFixtureAsSkData(kTestFontFixture);
FML_CHECK(mapping);
@ -1100,12 +1135,16 @@ sk_sp<SkTextBlob> GetTestTextBlob(int index) {
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);
auto blob = GetTestTextBlob(text);
text_blobs.insert(std::make_pair(index, blob));
return blob;
}
sk_sp<SkTextBlob> GetTestTextBlob(const std::string& text, DlScalar font_size) {
return SkTextBlob::MakeFromText(text.c_str(), text.size(),
CreateTestFontOfSize(font_size),
SkTextEncoding::kUTF8);
}
} // namespace testing
} // namespace flutter

View File

@ -23,6 +23,8 @@ namespace testing {
sk_sp<DisplayList> GetSampleDisplayList();
sk_sp<DisplayList> GetSampleDisplayList(int ops);
sk_sp<DisplayList> GetSampleNestedDisplayList();
sk_sp<DlImage> MakeTestImage(int w, int h, int checker_size);
sk_sp<DlImage> MakeTestImage(int w, int h, DlColor color);
typedef const std::function<void(DlOpReceiver&)> DlInvoker;
@ -56,7 +58,7 @@ constexpr float kInvertColorMatrix[20] = {
};
// clang-format on
constexpr SkPoint kTestPoints[] = {
constexpr DlPoint kTestPoints[] = {
{10, 10},
{20, 20},
{10, 20},
@ -67,32 +69,12 @@ constexpr SkPoint kTestPoints[] = {
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 =
SkSurfaces::Raster(SkImageInfo::MakeN32Premul(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 auto TestSkImage = MakeTestImage(30, 30, 5)->skia_image();
static auto kTestImage1 = MakeTestImage(40, 40, 5);
static auto kTestImage2 = MakeTestImage(50, 50, 5);
static auto kTestSkImage = MakeTestImage(30, 30, 5)->skia_image();
static const std::shared_ptr<DlColorSource> kTestSource1 =
DlColorSource::MakeImage(TestImage1,
DlColorSource::MakeImage(kTestImage1,
DlTileMode::kClamp,
DlTileMode::kMirror,
kLinearSampling);
@ -203,19 +185,17 @@ static const DlPath kTestPath2 =
DlPath(SkPath::Polygon({{0, 0}, {10, 10}, {0, 10}, {10, 0}}, true));
static const DlPath kTestPath3 =
DlPath(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 const std::shared_ptr<DlVertices> kTestVertices1 =
DlVertices::Make(DlVertexMode::kTriangles, //
3,
ToDlPoints(kTestPoints),
kTestPoints,
nullptr,
kColors);
static const std::shared_ptr<DlVertices> kTestVertices2 =
DlVertices::Make(DlVertexMode::kTriangleFan, //
3,
ToDlPoints(kTestPoints),
kTestPoints,
nullptr,
kColors);
@ -229,8 +209,21 @@ static sk_sp<DisplayList> TestDisplayList1 =
static sk_sp<DisplayList> TestDisplayList2 =
MakeTestDisplayList(25, 25, SK_ColorBLUE);
SkFont CreateTestFontOfSize(SkScalar scalar);
static const sk_sp<DlRuntimeEffect> kTestRuntimeEffect1 =
DlRuntimeEffect::MakeSkia(
SkRuntimeEffect::MakeForShader(
SkString("vec4 main(vec2 p) { return vec4(0); }"))
.effect);
static const sk_sp<DlRuntimeEffect> kTestRuntimeEffect2 =
DlRuntimeEffect::MakeSkia(
SkRuntimeEffect::MakeForShader(
SkString("vec4 main(vec2 p) { return vec4(1); }"))
.effect);
SkFont CreateTestFontOfSize(DlScalar scalar);
sk_sp<SkTextBlob> GetTestTextBlob(const std::string& str,
DlScalar font_size = 20.0f);
sk_sp<SkTextBlob> GetTestTextBlob(int index);
struct DisplayListInvocation {

View File

@ -137,19 +137,6 @@ void DisplayListMatrixClipState::clipRRect(const DlRoundRect& rrect,
void DisplayListMatrixClipState::clipPath(const DlPath& path,
ClipOp op,
bool is_aa) {
// Map "kDifference of inverse path" to "kIntersect of the original path" and
// map "kIntersect of inverse path" to "kDifference of the original path"
if (path.IsInverseFillType()) {
switch (op) {
case ClipOp::kIntersect:
op = ClipOp::kDifference;
break;
case ClipOp::kDifference:
op = ClipOp::kIntersect;
break;
}
}
DlRect bounds = path.GetBounds();
if (path.IsRect(nullptr)) {
return clipRect(bounds, op, is_aa);

View File

@ -574,30 +574,6 @@ TEST(DisplayListMatrixClipState, ClipDifference) {
reducing(SkRect::MakeLTRB(15, 15, 45, 45), SkRect::MakeEmpty(), "Smothering");
}
TEST(DisplayListMatrixClipState, ClipPathWithInvertFillType) {
SkRect cull_rect = SkRect::MakeLTRB(0, 0, 100.0, 100.0);
DisplayListMatrixClipState state(cull_rect, SkMatrix::I());
SkPath clip = SkPath().addCircle(10.2, 11.3, 2).addCircle(20.4, 25.7, 2);
clip.setFillType(SkPathFillType::kInverseWinding);
state.clipPath(clip, DlCanvas::ClipOp::kIntersect, false);
EXPECT_EQ(state.local_cull_rect(), cull_rect);
EXPECT_EQ(state.device_cull_rect(), cull_rect);
}
TEST(DisplayListMatrixClipState, DiffClipPathWithInvertFillType) {
SkRect cull_rect = SkRect::MakeLTRB(0, 0, 100.0, 100.0);
DisplayListMatrixClipState state(cull_rect, SkMatrix::I());
SkPath clip = SkPath().addCircle(10.2, 11.3, 2).addCircle(20.4, 25.7, 2);
clip.setFillType(SkPathFillType::kInverseWinding);
SkRect clip_bounds = SkRect::MakeLTRB(8.2, 9.3, 22.4, 27.7);
state.clipPath(clip, DlCanvas::ClipOp::kDifference, false);
EXPECT_EQ(state.local_cull_rect(), clip_bounds);
EXPECT_EQ(state.device_cull_rect(), clip_bounds);
}
TEST(DisplayListMatrixClipState, MapAndClipRectTranslation) {
DlRect cull_rect = DlRect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
DlMatrix matrix = DlMatrix::MakeTranslation({10.0f, 20.0f, 1.0f});

View File

@ -170,6 +170,11 @@ void Path::WritePolyline(Scalar scale, VertexWriter& writer) const {
}
}
Path::ComponentType Path::GetComponentTypeAtIndex(size_t index) const {
auto& components = data_->components;
return components[index];
}
bool Path::GetLinearComponentAtIndex(size_t index,
LinearPathComponent& linear) const {
auto& components = data_->components;

View File

@ -157,6 +157,8 @@ class Path {
/// @brief Whether the line contains a single contour.
bool IsSingleContour() const;
ComponentType GetComponentTypeAtIndex(size_t index) const;
bool GetLinearComponentAtIndex(size_t index,
LinearPathComponent& linear) const;

View File

@ -23,11 +23,16 @@ static inline void AdjustScale(Scalar& radius1,
}
}
RoundRect RoundRect::MakeRectRadii(const Rect& bounds,
RoundRect RoundRect::MakeRectRadii(const Rect& in_bounds,
const RoundingRadii& in_radii) {
if (bounds.IsEmpty() || !bounds.IsFinite() || //
if (!in_bounds.IsFinite()) {
return {};
}
Rect bounds = in_bounds.GetPositive();
if (bounds.IsEmpty() || //
in_radii.AreAllCornersEmpty() || !in_radii.IsFinite()) {
// preserve the empty bounds as they might be strokable
// pass along the bounds even if empty as it would still have a valid
// location and/or 1-dimensional size which might appear when stroked
return RoundRect(bounds, RoundingRadii());
}

View File

@ -360,15 +360,15 @@ TEST(RoundRectTest, DefaultConstructor) {
}
TEST(RoundRectTest, EmptyRectConstruction) {
RoundRect round_rect = RoundRect::MakeRectXY(
Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f), 10.0f, 10.0f);
RoundRect round_rect =
RoundRect::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
EXPECT_TRUE(round_rect.IsEmpty());
EXPECT_FALSE(round_rect.IsRect());
EXPECT_FALSE(round_rect.IsOval());
EXPECT_TRUE(round_rect.IsFinite());
EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f));
EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
EXPECT_EQ(round_rect.GetRadii().top_left, Size());
EXPECT_EQ(round_rect.GetRadii().top_right, Size());
EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
@ -391,6 +391,38 @@ TEST(RoundRectTest, RectConstructor) {
EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
}
TEST(RoundRectTest, InvertedRectConstruction) {
RoundRect round_rect =
RoundRect::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f));
EXPECT_FALSE(round_rect.IsEmpty());
EXPECT_TRUE(round_rect.IsRect());
EXPECT_FALSE(round_rect.IsOval());
EXPECT_TRUE(round_rect.IsFinite());
EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
EXPECT_EQ(round_rect.GetRadii().top_left, Size());
EXPECT_EQ(round_rect.GetRadii().top_right, Size());
EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
}
TEST(RoundRectTest, EmptyOvalConstruction) {
RoundRect round_rect = RoundRect::MakeRectXY(
Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f), 10.0f, 10.0f);
EXPECT_TRUE(round_rect.IsEmpty());
EXPECT_FALSE(round_rect.IsRect());
EXPECT_FALSE(round_rect.IsOval());
EXPECT_TRUE(round_rect.IsFinite());
EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
EXPECT_EQ(round_rect.GetRadii().top_left, Size());
EXPECT_EQ(round_rect.GetRadii().top_right, Size());
EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
}
TEST(RoundRectTest, OvalConstructor) {
RoundRect round_rect =
RoundRect::MakeOval(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
@ -407,6 +439,22 @@ TEST(RoundRectTest, OvalConstructor) {
EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(5.0f, 5.0f));
}
TEST(RoundRectTest, InvertedOvalConstruction) {
RoundRect round_rect = RoundRect::MakeRectXY(
Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f), 10.0f, 10.0f);
EXPECT_FALSE(round_rect.IsEmpty());
EXPECT_FALSE(round_rect.IsRect());
EXPECT_TRUE(round_rect.IsOval());
EXPECT_TRUE(round_rect.IsFinite());
EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
EXPECT_EQ(round_rect.GetRadii().top_left, Size(5.0f, 5.0f));
EXPECT_EQ(round_rect.GetRadii().top_right, Size(5.0f, 5.0f));
EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(5.0f, 5.0f));
EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(5.0f, 5.0f));
}
TEST(RoundRectTest, RectRadiusConstructor) {
RoundRect round_rect = RoundRect::MakeRectRadius(
Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), 2.0f);

View File

@ -20,9 +20,8 @@ void DisplayListBuilder::Save() {
void DisplayListBuilder::SaveLayer(const Rect& bounds,
const Paint* paint,
const ImageFilter* backdrop) {
const auto sk_bounds = ToSkiaType(bounds);
builder_.SaveLayer(
&sk_bounds, //
bounds, //
paint == nullptr ? nullptr : &paint->GetPaint(), //
backdrop == nullptr ? nullptr : backdrop->GetImageFilter().get());
}
@ -44,19 +43,15 @@ void DisplayListBuilder::Translate(Point translation) {
}
Matrix DisplayListBuilder::GetTransform() const {
Matrix matrix;
builder_.GetTransformFullPerspective().getColMajor(matrix.m);
return matrix;
return builder_.GetMatrix();
}
void DisplayListBuilder::SetTransform(const Matrix& matrix) {
const auto sk_matrix = SkM44::ColMajor(matrix.m);
builder_.SetTransform(&sk_matrix);
builder_.SetTransform(matrix);
}
void DisplayListBuilder::Transform(const Matrix& matrix) {
const auto sk_matrix = SkM44::ColMajor(matrix.m);
builder_.Transform(&sk_matrix);
builder_.Transform(matrix);
}
void DisplayListBuilder::ResetTransform() {
@ -73,37 +68,38 @@ void DisplayListBuilder::RestoreToCount(uint32_t count) {
void DisplayListBuilder::ClipRect(const Rect& rect,
flutter::DlCanvas::ClipOp op) {
builder_.ClipRect(ToSkiaType(rect), op);
builder_.ClipRect(rect, op);
}
void DisplayListBuilder::ClipOval(const Rect& rect,
flutter::DlCanvas::ClipOp op) {
builder_.ClipOval(ToSkiaType(rect), op);
builder_.ClipOval(rect, op);
}
void DisplayListBuilder::ClipRoundedRect(const Rect& rect,
const RoundingRadii& radii,
flutter::DlCanvas::ClipOp op) {
builder_.ClipRRect(ToSkiaType(rect, radii), op);
builder_.ClipRoundRect(RoundRect::MakeRectRadii(rect, radii), op);
}
void DisplayListBuilder::ClipPath(const Path& path,
flutter::DlCanvas::ClipOp op) {
builder_.ClipPath(path.GetPath(), op);
builder_.ClipPath(flutter::DlPath(path.GetPath()), op);
}
void DisplayListBuilder::DrawRect(const Rect& rect, const Paint& paint) {
builder_.DrawRect(ToSkiaType(rect), paint.GetPaint());
builder_.DrawRect(rect, paint.GetPaint());
}
void DisplayListBuilder::DrawOval(const Rect& oval_bounds, const Paint& paint) {
builder_.DrawOval(ToSkiaType(oval_bounds), paint.GetPaint());
builder_.DrawOval(oval_bounds, paint.GetPaint());
}
void DisplayListBuilder::DrawRoundedRect(const Rect& rect,
const RoundingRadii& radii,
const Paint& paint) {
builder_.DrawRRect(ToSkiaType(rect, radii), paint.GetPaint());
builder_.DrawRoundRect(RoundRect::MakeRectRadii(rect, radii),
paint.GetPaint());
}
void DisplayListBuilder::DrawRoundedRectDifference(
@ -112,14 +108,15 @@ void DisplayListBuilder::DrawRoundedRectDifference(
const Rect& inner_rect,
const RoundingRadii& inner_radii,
const Paint& paint) {
builder_.DrawDRRect(ToSkiaType(outer_rect, outer_radii), //
ToSkiaType(inner_rect, inner_radii), //
paint.GetPaint() //
builder_.DrawDiffRoundRect(
RoundRect::MakeRectRadii(outer_rect, outer_radii), //
RoundRect::MakeRectRadii(inner_rect, inner_radii), //
paint.GetPaint() //
);
}
void DisplayListBuilder::DrawPath(const Path& path, const Paint& paint) {
builder_.DrawPath(path.GetPath(), paint.GetPaint());
builder_.DrawPath(flutter::DlPath(path.GetPath()), paint.GetPaint());
}
void DisplayListBuilder::DrawPaint(const Paint& paint) {
@ -129,7 +126,7 @@ void DisplayListBuilder::DrawPaint(const Paint& paint) {
void DisplayListBuilder::DrawLine(const Point& from,
const Point& to,
const Paint& paint) {
builder_.DrawLine(ToSkiaType(from), ToSkiaType(to), paint.GetPaint());
builder_.DrawLine(from, to, paint.GetPaint());
}
void DisplayListBuilder::DrawDashedLine(const Point& from,
@ -159,7 +156,7 @@ void DisplayListBuilder::DrawTexture(const Texture& texture,
flutter::DlImageSampling sampling,
const Paint* paint) {
builder_.DrawImage(texture.MakeImage(), //
ToSkiaType(point), //
point, //
sampling, //
paint == nullptr ? nullptr : &paint->GetPaint() //
);
@ -171,8 +168,8 @@ void DisplayListBuilder::DrawTextureRect(const Texture& texture,
flutter::DlImageSampling sampling,
const Paint* paint) {
builder_.DrawImageRect(texture.MakeImage(), //
ToSkiaType(src_rect), //
ToSkiaType(dst_rect), //
src_rect, //
dst_rect, //
sampling, //
paint == nullptr ? nullptr : &paint->GetPaint() //
);

View File

@ -7,8 +7,6 @@
#include "flutter/display_list/testing/dl_test_snippets.h"
#include "flutter/shell/common/dl_op_spy.h"
#include "flutter/testing/testing.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkFont.h"
#include "third_party/skia/include/core/SkRSXform.h"
namespace flutter {
@ -47,7 +45,7 @@ TEST(DlOpSpy, SetColor) {
{ // No Color set.
DisplayListBuilder builder;
DlPaint paint;
builder.DrawRect(SkRect::MakeWH(5, 5), paint);
builder.DrawRect(DlRect::MakeWH(5, 5), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -56,7 +54,7 @@ TEST(DlOpSpy, SetColor) {
{ // Set transparent color.
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
builder.DrawRect(SkRect::MakeWH(5, 5), paint);
builder.DrawRect(DlRect::MakeWH(5, 5), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -65,7 +63,7 @@ TEST(DlOpSpy, SetColor) {
{ // Set black color.
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
builder.DrawRect(SkRect::MakeWH(5, 5), paint);
builder.DrawRect(DlRect::MakeWH(5, 5), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -78,7 +76,7 @@ TEST(DlOpSpy, SetColorSource) {
DisplayListBuilder builder;
DlPaint paint;
paint.setColorSource(nullptr);
builder.DrawRect(SkRect::MakeWH(5, 5), paint);
builder.DrawRect(DlRect::MakeWH(5, 5), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -162,7 +160,7 @@ TEST(DlOpSpy, DrawLine) {
{ // black
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
builder.DrawLine(SkPoint::Make(0, 1), SkPoint::Make(1, 2), paint);
builder.DrawLine(DlPoint(0, 1), DlPoint(1, 2), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -171,7 +169,7 @@ TEST(DlOpSpy, DrawLine) {
{ // transparent
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
builder.DrawLine(SkPoint::Make(0, 1), SkPoint::Make(1, 2), paint);
builder.DrawLine(DlPoint(0, 1), DlPoint(1, 2), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -204,7 +202,7 @@ TEST(DlOpSpy, DrawRect) {
{ // black
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
builder.DrawRect(SkRect::MakeWH(5, 5), paint);
builder.DrawRect(DlRect::MakeWH(5, 5), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -213,7 +211,7 @@ TEST(DlOpSpy, DrawRect) {
{ // transparent
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
builder.DrawRect(SkRect::MakeWH(5, 5), paint);
builder.DrawRect(DlRect::MakeWH(5, 5), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -225,7 +223,7 @@ TEST(DlOpSpy, DrawOval) {
{ // black
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
builder.DrawOval(SkRect::MakeWH(5, 5), paint);
builder.DrawOval(DlRect::MakeWH(5, 5), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -234,7 +232,7 @@ TEST(DlOpSpy, DrawOval) {
{ // transparent
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
builder.DrawOval(SkRect::MakeWH(5, 5), paint);
builder.DrawOval(DlRect::MakeWH(5, 5), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -246,7 +244,7 @@ TEST(DlOpSpy, DrawCircle) {
{ // black
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
builder.DrawCircle(SkPoint::Make(5, 5), 1.0, paint);
builder.DrawCircle(DlPoint(5, 5), 1.0, paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -255,7 +253,7 @@ TEST(DlOpSpy, DrawCircle) {
{ // transparent
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
builder.DrawCircle(SkPoint::Make(5, 5), 1.0, paint);
builder.DrawCircle(DlPoint(5, 5), 1.0, paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -267,7 +265,7 @@ TEST(DlOpSpy, DrawRRect) {
{ // black
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
builder.DrawRRect(SkRRect::MakeRect(SkRect::MakeWH(5, 5)), paint);
builder.DrawRoundRect(DlRoundRect::MakeRect(DlRect::MakeWH(5, 5)), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -276,7 +274,7 @@ TEST(DlOpSpy, DrawRRect) {
{ // transparent
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
builder.DrawRRect(SkRRect::MakeRect(SkRect::MakeWH(5, 5)), paint);
builder.DrawRoundRect(DlRoundRect::MakeRect(DlRect::MakeWH(5, 5)), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -289,8 +287,10 @@ TEST(DlOpSpy, DrawPath) {
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
paint.setDrawStyle(DlDrawStyle::kStroke);
builder.DrawPath(SkPath::Line(SkPoint::Make(0, 1), SkPoint::Make(1, 1)),
paint);
DlPathBuilder path_builder;
path_builder.MoveTo({0, 1});
path_builder.LineTo({1, 1});
builder.DrawPath(DlPath(path_builder.TakePath()), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -299,11 +299,11 @@ TEST(DlOpSpy, DrawPath) {
{ // triangle
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
SkPath path;
path.moveTo({0, 0});
path.lineTo({1, 0});
path.lineTo({0, 1});
builder.DrawPath(path, paint);
DlPathBuilder path_builder;
path_builder.MoveTo({0, 0});
path_builder.LineTo({1, 0});
path_builder.LineTo({0, 1});
builder.DrawPath(DlPath(path_builder.TakePath()), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -313,8 +313,10 @@ TEST(DlOpSpy, DrawPath) {
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
paint.setDrawStyle(DlDrawStyle::kStroke);
builder.DrawPath(SkPath::Line(SkPoint::Make(0, 1), SkPoint::Make(1, 1)),
paint);
DlPathBuilder path_builder;
path_builder.MoveTo({0, 1});
path_builder.LineTo({1, 1});
builder.DrawPath(DlPath(path_builder.TakePath()), paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -326,7 +328,7 @@ TEST(DlOpSpy, DrawArc) {
{ // black
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
builder.DrawArc(SkRect::MakeWH(5, 5), 0, 1, true, paint);
builder.DrawArc(DlRect::MakeWH(5, 5), 0, 1, true, paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -335,7 +337,7 @@ TEST(DlOpSpy, DrawArc) {
{ // transparent
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
builder.DrawArc(SkRect::MakeWH(5, 5), 0, 1, true, paint);
builder.DrawArc(DlRect::MakeWH(5, 5), 0, 1, true, paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -347,7 +349,7 @@ TEST(DlOpSpy, DrawPoints) {
{ // black
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
const SkPoint points[] = {SkPoint::Make(5, 4)};
const DlPoint points[] = {DlPoint(5, 4)};
builder.DrawPoints(DlCanvas::PointMode::kPoints, 1, points, paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
@ -357,7 +359,7 @@ TEST(DlOpSpy, DrawPoints) {
{ // transparent
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
const SkPoint points[] = {SkPoint::Make(5, 4)};
const DlPoint points[] = {DlPoint(5, 4)};
builder.DrawPoints(DlCanvas::PointMode::kPoints, 1, points, paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
@ -425,14 +427,7 @@ TEST(DlOpSpy, Images) {
{ // DrawImage
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
SkImageInfo info =
SkImageInfo::Make(50, 50, SkColorType::kRGBA_8888_SkColorType,
SkAlphaType::kPremul_SkAlphaType);
SkBitmap bitmap;
bitmap.allocPixels(info, 0);
auto sk_image = SkImages::RasterFromBitmap(bitmap);
builder.DrawImage(DlImage::Make(sk_image), SkPoint::Make(5, 5),
DlImageSampling::kLinear);
builder.DrawImage(kTestImage1, DlPoint(5, 5), DlImageSampling::kLinear);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -441,14 +436,8 @@ TEST(DlOpSpy, Images) {
{ // DrawImageRect
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
SkImageInfo info =
SkImageInfo::Make(50, 50, SkColorType::kRGBA_8888_SkColorType,
SkAlphaType::kPremul_SkAlphaType);
SkBitmap bitmap;
bitmap.allocPixels(info, 0);
auto sk_image = SkImages::RasterFromBitmap(bitmap);
builder.DrawImageRect(DlImage::Make(sk_image), SkRect::MakeWH(5, 5),
SkRect::MakeWH(5, 5), DlImageSampling::kLinear);
builder.DrawImageRect(kTestImage1, DlRect::MakeWH(5, 5),
DlRect::MakeWH(5, 5), DlImageSampling::kLinear);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -457,14 +446,8 @@ TEST(DlOpSpy, Images) {
{ // DrawImageNine
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
SkImageInfo info =
SkImageInfo::Make(50, 50, SkColorType::kRGBA_8888_SkColorType,
SkAlphaType::kPremul_SkAlphaType);
SkBitmap bitmap;
bitmap.allocPixels(info, 0);
auto sk_image = SkImages::RasterFromBitmap(bitmap);
builder.DrawImageNine(DlImage::Make(sk_image), SkIRect::MakeWH(5, 5),
SkRect::MakeWH(5, 5), DlFilterMode::kLinear);
builder.DrawImageNine(kTestImage1, DlIRect::MakeWH(5, 5),
DlRect::MakeWH(5, 5), DlFilterMode::kLinear);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -473,17 +456,11 @@ TEST(DlOpSpy, Images) {
{ // DrawAtlas
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
SkImageInfo info =
SkImageInfo::Make(50, 50, SkColorType::kRGBA_8888_SkColorType,
SkAlphaType::kPremul_SkAlphaType);
SkBitmap bitmap;
bitmap.allocPixels(info, 0);
auto sk_image = SkImages::RasterFromBitmap(bitmap);
const SkRSXform xform[] = {SkRSXform::Make(1, 0, 0, 0)};
const SkRect tex[] = {SkRect::MakeXYWH(10, 10, 10, 10)};
SkRect cull_rect = SkRect::MakeWH(5, 5);
builder.DrawAtlas(DlImage::Make(sk_image), xform, tex, nullptr, 1,
DlBlendMode::kSrc, DlImageSampling::kLinear, &cull_rect);
const DlRect tex[] = {DlRect::MakeXYWH(10, 10, 10, 10)};
DlRect cull_rect = DlRect::MakeWH(5, 5);
builder.DrawAtlas(kTestImage1, xform, tex, nullptr, 1, DlBlendMode::kSrc,
DlImageSampling::kLinear, &cull_rect);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -565,9 +542,7 @@ TEST(DlOpSpy, DrawTextBlob) {
DisplayListBuilder builder;
DlPaint paint(DlColor::kBlack());
std::string string = "xx";
SkFont font = CreateTestFontOfSize(12);
auto text_blob = SkTextBlob::MakeFromString(string.c_str(), font);
builder.DrawTextBlob(text_blob, 1, 1, paint);
builder.DrawTextBlob(GetTestTextBlob(42), 1, 1, paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -577,9 +552,7 @@ TEST(DlOpSpy, DrawTextBlob) {
DisplayListBuilder builder;
DlPaint paint(DlColor::kTransparent());
std::string string = "xx";
SkFont font = CreateTestFontOfSize(12);
auto text_blob = SkTextBlob::MakeFromString(string.c_str(), font);
builder.DrawTextBlob(text_blob, 1, 1, paint);
builder.DrawTextBlob(GetTestTextBlob(43), 1, 1, paint);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -592,8 +565,7 @@ TEST(DlOpSpy, DrawShadow) {
DisplayListBuilder builder;
DlPaint paint;
DlColor color = DlColor::kBlack();
SkPath path = SkPath::Line(SkPoint::Make(0, 1), SkPoint::Make(1, 1));
builder.DrawShadow(path, color, 1, false, 1);
builder.DrawShadow(kTestPath1, color, 1, false, 1);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);
@ -603,8 +575,7 @@ TEST(DlOpSpy, DrawShadow) {
DisplayListBuilder builder;
DlPaint paint;
DlColor color = DlColor::kTransparent();
SkPath path = SkPath::Line(SkPoint::Make(0, 1), SkPoint::Make(1, 1));
builder.DrawShadow(path, color, 1, false, 1);
builder.DrawShadow(kTestPath1, color, 1, false, 1);
sk_sp<DisplayList> dl = builder.Build();
DlOpSpy dl_op_spy;
dl->Dispatch(dl_op_spy);