blob: 506e3970da4c83c1fff31f3bb36a954521b11c4a [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "impeller/display_list/dl_golden_unittests.h"
#include "flutter/display_list/dl_builder.h"
#include "flutter/testing/testing.h"
#include "gtest/gtest.h"
namespace flutter {
namespace testing {
using impeller::Degrees;
using impeller::PlaygroundBackend;
using impeller::PlaygroundTest;
using impeller::Point;
using impeller::Radians;
using impeller::Scalar;
INSTANTIATE_PLAYGROUND_SUITE(DlGoldenTest);
TEST_P(DlGoldenTest, CanDrawPaint) {
auto draw = [](DlCanvas* canvas,
const std::vector<std::unique_ptr<DlImage>>& images) {
canvas->Scale(0.2, 0.2);
DlPaint paint;
paint.setColor(DlColor::kCyan());
canvas->DrawPaint(paint);
};
DisplayListBuilder builder;
draw(&builder, /*images=*/{});
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(DlGoldenTest, CanRenderImage) {
auto draw = [](DlCanvas* canvas, const std::vector<sk_sp<DlImage>>& images) {
FML_CHECK(images.size() >= 1);
DlPaint paint;
paint.setColor(DlColor::kRed());
canvas->DrawImage(images[0], SkPoint::Make(100.0, 100.0),
DlImageSampling::kLinear, &paint);
};
DisplayListBuilder builder;
std::vector<sk_sp<DlImage>> images;
images.emplace_back(CreateDlImageForFixture("kalimba.jpg"));
draw(&builder, images);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
// Asserts that subpass rendering of MatrixImageFilters works.
// https://github.com/flutter/flutter/issues/147807
TEST_P(DlGoldenTest, Bug147807) {
Point content_scale = GetContentScale();
auto draw = [content_scale](DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>& images) {
canvas->Scale(content_scale.x, content_scale.y);
DlPaint paint;
paint.setColor(DlColor(0xfffef7ff));
canvas->DrawRect(SkRect::MakeLTRB(0, 0, 375, 667), paint);
paint.setColor(DlColor(0xffff9800));
canvas->DrawRect(SkRect::MakeLTRB(0, 0, 187.5, 333.5), paint);
paint.setColor(DlColor(0xff9c27b0));
canvas->DrawRect(SkRect::MakeLTRB(187.5, 0, 375, 333.5), paint);
paint.setColor(DlColor(0xff4caf50));
canvas->DrawRect(SkRect::MakeLTRB(0, 333.5, 187.5, 667), paint);
paint.setColor(DlColor(0xfff44336));
canvas->DrawRect(SkRect::MakeLTRB(187.5, 333.5, 375, 667), paint);
canvas->Save();
{
canvas->ClipRRect(
SkRRect::MakeOval(SkRect::MakeLTRB(201.25, 10, 361.25, 170)),
DlCanvas::ClipOp::kIntersect, true);
SkRect save_layer_bounds = SkRect::MakeLTRB(201.25, 10, 361.25, 170);
DlMatrixImageFilter backdrop(SkMatrix::MakeAll(3, 0, -280, //
0, 3, -920, //
0, 0, 1),
DlImageSampling::kLinear);
canvas->SaveLayer(&save_layer_bounds, /*paint=*/nullptr, &backdrop);
{
canvas->Translate(201.25, 10);
auto paint = DlPaint()
.setAntiAlias(true)
.setColor(DlColor(0xff2196f3))
.setStrokeWidth(5)
.setDrawStyle(DlDrawStyle::kStroke);
canvas->DrawCircle(SkPoint::Make(80, 80), 80, paint);
}
canvas->Restore();
}
canvas->Restore();
};
DisplayListBuilder builder;
std::vector<sk_sp<DlImage>> images;
draw(&builder, images);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
namespace {
void DrawBlurGrid(DlCanvas* canvas) {
DlPaint paint;
paint.setColor(DlColor(0xfffef7ff));
Scalar width = 150;
Scalar height = 150;
Scalar gap = 80;
std::vector<Scalar> blur_radii = {10, 30, 50};
for (size_t i = 0; i < blur_radii.size(); ++i) {
Scalar blur_radius = blur_radii[i];
auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
flutter::DlBlurStyle::kNormal, blur_radius);
paint.setMaskFilter(blur_filter);
SkRRect rrect;
Scalar yval = gap + i * (gap + height);
rrect.setNinePatch(SkRect::MakeXYWH(gap, yval, width, height), 10, 10, 10,
10);
canvas->DrawRRect(rrect, paint);
rrect.setNinePatch(SkRect::MakeXYWH(2.0 * gap + width, yval, width, height),
9, 10, 10, 10);
canvas->DrawRRect(rrect, paint);
}
}
} // namespace
TEST_P(DlGoldenTest, GaussianVsRRectBlur) {
Point content_scale = GetContentScale();
auto draw = [content_scale](DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>& images) {
canvas->Scale(content_scale.x, content_scale.y);
canvas->DrawPaint(DlPaint().setColor(DlColor(0xff112233)));
DrawBlurGrid(canvas);
};
DisplayListBuilder builder;
std::vector<sk_sp<DlImage>> images;
draw(&builder, images);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(DlGoldenTest, GaussianVsRRectBlurScaled) {
Point content_scale = GetContentScale();
auto draw = [content_scale](DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>& images) {
canvas->Scale(content_scale.x, content_scale.y);
canvas->DrawPaint(DlPaint().setColor(DlColor(0xff112233)));
canvas->Scale(0.33, 0.33);
DrawBlurGrid(canvas);
};
DisplayListBuilder builder;
std::vector<sk_sp<DlImage>> images;
draw(&builder, images);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(DlGoldenTest, GaussianVsRRectBlurScaledRotated) {
Point content_scale = GetContentScale();
auto draw = [content_scale](DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>& images) {
canvas->Scale(content_scale.x, content_scale.y);
canvas->Translate(200, 200);
canvas->DrawPaint(DlPaint().setColor(DlColor(0xff112233)));
canvas->Scale(0.33, 0.33);
canvas->Translate(300, 300);
canvas->Rotate(45);
canvas->Translate(-300, -300);
DrawBlurGrid(canvas);
};
DisplayListBuilder builder;
std::vector<sk_sp<DlImage>> images;
draw(&builder, images);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(DlGoldenTest, DashedLinesTest) {
Point content_scale = GetContentScale();
auto draw = [content_scale](DlCanvas* canvas,
const std::vector<sk_sp<DlImage>>& images) {
canvas->Scale(content_scale.x, content_scale.y);
canvas->DrawPaint(DlPaint().setColor(DlColor::kWhite()));
auto draw_one = [canvas](DlStrokeCap cap, Scalar x, Scalar y,
Scalar dash_on, Scalar dash_off) {
Point center = Point(x, y);
Scalar inner = 20.0f;
Scalar outer = 100.0f;
DlPaint thick_paint = DlPaint()
.setColor(DlColor::kBlue())
.setStrokeCap(cap)
.setStrokeWidth(8.0f);
DlPaint middle_paint = DlPaint()
.setColor(DlColor::kGreen())
.setStrokeCap(cap)
.setStrokeWidth(5.0f);
DlPaint thin_paint = DlPaint()
.setColor(DlColor::kMagenta())
.setStrokeCap(cap)
.setStrokeWidth(2.0f);
for (int degrees = 0; degrees < 360; degrees += 30) {
Point delta = Point(1.0f, 0.0f).Rotate(Degrees(degrees));
canvas->DrawDashedLine(center + inner * delta, center + outer * delta,
dash_on, dash_off, thick_paint);
canvas->DrawDashedLine(center + inner * delta, center + outer * delta,
dash_on, dash_off, middle_paint);
canvas->DrawDashedLine(center + inner * delta, center + outer * delta,
dash_on, dash_off, thin_paint);
}
};
draw_one(DlStrokeCap::kButt, 150.0f, 150.0f, 15.0f, 10.0f);
draw_one(DlStrokeCap::kSquare, 400.0f, 150.0f, 15.0f, 10.0f);
draw_one(DlStrokeCap::kRound, 150.0f, 400.0f, 15.0f, 10.0f);
draw_one(DlStrokeCap::kRound, 400.0f, 400.0f, 0.0f, 11.0f);
// Make sure the rendering op responds appropriately to clipping
canvas->Save();
SkPath clip_path = SkPath();
clip_path.moveTo(275.0f, 225.0f);
clip_path.lineTo(325.0f, 275.0f);
clip_path.lineTo(275.0f, 325.0f);
clip_path.lineTo(225.0f, 275.0f);
canvas->ClipPath(clip_path);
canvas->DrawColor(DlColor::kYellow());
draw_one(DlStrokeCap::kRound, 275.0f, 275.0f, 15.0f, 10.0f);
canvas->Restore();
};
DisplayListBuilder builder;
std::vector<sk_sp<DlImage>> images;
draw(&builder, images);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
} // namespace testing
} // namespace flutter