Skip to content

Commit 40c779f

Browse files
committed
[Impeller] Fix new convex path shadow generation in perspective
1 parent f88f18c commit 40c779f

2 files changed

Lines changed: 94 additions & 2 deletions

File tree

engine/src/flutter/impeller/display_list/aiks_dl_shadow_unittests.cc

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,5 +930,89 @@ TEST_P(AiksTest,
930930
ASSERT_TRUE(OpenPlaygroundHere(dl));
931931
}
932932

933+
TEST_P(AiksTest, CanDrawPerspectiveConvexShadow) {
934+
DisplayListBuilder builder;
935+
builder.Clear(DlColor::kWhite());
936+
builder.Scale(GetContentScale().x, GetContentScale().y);
937+
938+
// The rect path should be optimized to a rect-specific shadow shader.
939+
DlPath rect_path = DlPath::MakeRectLTRB(-50, -50, 50, 75);
940+
941+
// The pentagon path should go through the general convex path shadow
942+
// tessellator.
943+
DlPathBuilder path_builder;
944+
path_builder.MoveTo(DlPoint(-50, -50));
945+
path_builder.LineTo(DlPoint(50, -50));
946+
path_builder.LineTo(DlPoint(50, 50));
947+
path_builder.LineTo(DlPoint(0, 75));
948+
path_builder.LineTo(DlPoint(-50, 50));
949+
path_builder.Close();
950+
DlPath pentagon_path = path_builder.TakePath();
951+
952+
Matrix simple_y_rotate_matrix = Matrix::MakeRotationY(Degrees(45));
953+
954+
Matrix perspective_matrix;
955+
perspective_matrix.e[2][3] = 0.0015f;
956+
perspective_matrix = perspective_matrix * simple_y_rotate_matrix;
957+
958+
auto draw_paths_and_shadows = [&builder](const DlPath& path,
959+
const DlColor& color,
960+
const Matrix& matrix) {
961+
builder.Save();
962+
963+
DlPaint paint;
964+
paint.setColor(color.withAlphaF(0.25f));
965+
966+
DlPaint shadow_paint;
967+
shadow_paint.setMaskFilter(
968+
DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 10.0f));
969+
970+
builder.Save();
971+
builder.Transform(matrix);
972+
builder.DrawPath(path, paint);
973+
builder.Restore();
974+
975+
builder.Translate(150, 0);
976+
977+
builder.Save();
978+
builder.Transform(matrix);
979+
builder.DrawPath(path, shadow_paint);
980+
builder.Restore();
981+
982+
builder.Translate(150, 0);
983+
984+
builder.Save();
985+
builder.Transform(matrix);
986+
builder.DrawPath(path, shadow_paint);
987+
builder.DrawPath(path, paint);
988+
builder.Restore();
989+
990+
builder.Restore();
991+
};
992+
993+
auto draw_test = [&](const DlPath& path) {
994+
builder.Save();
995+
996+
builder.Translate(0, 75);
997+
builder.DrawPath(path, DlPaint(DlColor::kPurple()));
998+
999+
builder.Translate(150, -75);
1000+
draw_paths_and_shadows(path, DlColor::kGreen(), simple_y_rotate_matrix);
1001+
builder.Translate(0, 175);
1002+
draw_paths_and_shadows(path, DlColor::kBlue(), perspective_matrix);
1003+
1004+
builder.Restore();
1005+
};
1006+
1007+
builder.Translate(100, 100);
1008+
1009+
draw_test(rect_path);
1010+
builder.Translate(0, 350);
1011+
draw_test(pentagon_path);
1012+
1013+
auto dl = builder.Build();
1014+
ASSERT_TRUE(OpenPlaygroundHere(dl));
1015+
}
1016+
9331017
} // namespace testing
9341018
} // namespace impeller

engine/src/flutter/impeller/entity/geometry/shadow_path_geometry.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,17 @@ PolygonInfo::PolygonInfo(Scalar occluder_height)
494494

495495
const std::shared_ptr<ShadowVertices> PolygonInfo::CalculateConvexShadowMesh(
496496
const impeller::PathSource& source,
497-
const Matrix& matrix,
497+
const Matrix& incoming_matrix,
498498
const Tessellator::Trigs& trigs) {
499-
if (!matrix.IsInvertible()) {
499+
// We are operating in "2D device space" with respect to scale and there
500+
// is no need to involve translations or Z or perspective in the various
501+
// calculations, so we extract the incoming matrix's 2D Bases and just
502+
// use those measurements to guide our tessellation.
503+
Scalar x_scale = incoming_matrix.GetBasisX().GetLength();
504+
Scalar y_scale = incoming_matrix.GetBasisY().GetLength();
505+
Matrix matrix = Matrix::MakeScale({x_scale, y_scale, 1.0f});
506+
507+
if (!incoming_matrix.IsInvertible() || !matrix.IsInvertible()) {
500508
return ShadowVertices::kEmpty;
501509
}
502510

0 commit comments

Comments
 (0)