9#include "gtest/gtest.h"
11#include "flutter/third_party/skia/src/core/SkVerticesPriv.h"
12#include "flutter/third_party/skia/src/utils/SkShadowTessellator.h"
14#define SHADOW_UNITTEST_SHOW_VERTICES false
26#if SHADOW_UNITTEST_SHOW_VERTICES
27void ShowVertices(
const std::string& label,
28 const std::shared_ptr<ShadowVertices>& shadow_vertices) {
29 auto vertices = shadow_vertices->GetVertices();
30 auto alphas = shadow_vertices->GetGaussians();
31 auto indices = shadow_vertices->GetIndices();
32 FML_LOG(ERROR) << label <<
"[" << indices.size() / 3 <<
"] = {";
33 for (
size_t i = 0u;
i < indices.size();
i += 3) {
36 <<
" (" << vertices[indices[
i + 0]] <<
", " << alphas[indices[
i + 0]] <<
"), "
37 <<
" (" << vertices[indices[
i + 1]] <<
", " << alphas[indices[
i + 1]] <<
"), "
38 <<
" (" << vertices[indices[
i + 2]] <<
", " << alphas[indices[
i + 2]] <<
")";
41 FML_LOG(ERROR) <<
"} // " << label;
45constexpr Scalar kEpsilonSquared =
48bool SimilarPoint(Point p1, Point p2) {
49 return p1.GetDistanceSquared(p2) < kEpsilonSquared;
52bool SimilarPointPair(std::array<Point, 2> pair1, std::array<Point, 2> pair2) {
53 if (SimilarPoint(pair1[1], pair2[1]) && SimilarPoint(pair1[2], pair2[2])) {
56 if (SimilarPoint(pair1[1], pair2[2]) && SimilarPoint(pair1[2], pair2[1])) {
62bool SimilarPointTrio(std::array<Point, 3> trio1, std::array<Point, 3> trio2) {
63 if (SimilarPoint(trio1[1], trio2[1]) &&
64 SimilarPointPair({trio1[2], trio1[3]}, {trio2[2], trio2[3]})) {
67 if (SimilarPoint(trio1[1], trio2[2]) &&
68 SimilarPointPair({trio1[2], trio1[3]}, {trio2[1], trio2[3]})) {
71 if (SimilarPoint(trio1[1], trio2[3]) &&
72 SimilarPointPair({trio1[2], trio1[3]}, {trio2[1], trio2[2]})) {
78size_t CountDuplicateVertices(
79 const std::shared_ptr<ShadowVertices>& shadow_vertices) {
80 size_t duplicate_vertices = 0u;
81 auto vertices = shadow_vertices->GetVertices();
82 size_t vertex_count = vertices.size();
84 for (
size_t i = 1u;
i < vertex_count;
i++) {
85 Point& vertex = vertices[
i];
86 for (
size_t j = 0u; j <
i; j++) {
87 if (SimilarPoint(vertex, vertices[j])) {
93 return duplicate_vertices;
96size_t CountDuplicateTriangles(
97 const std::shared_ptr<ShadowVertices>& shadow_vertices) {
98 size_t duplicate_triangles = 0u;
99 auto vertices = shadow_vertices->GetVertices();
100 auto indices = shadow_vertices->GetIndices();
101 size_t index_count = indices.size();
103 for (
size_t i = 3u;
i < index_count;
i += 3) {
105 vertices[indices[
i + 0]],
106 vertices[indices[
i + 1]],
107 vertices[indices[
i + 2]],
109 for (
size_t j = 0; j <
i; j += 3) {
111 vertices[indices[j + 0]],
112 vertices[indices[j + 1]],
113 vertices[indices[j + 2]],
115 if (SimilarPointTrio(trio1, trio2)) {
116 duplicate_triangles++;
121 return duplicate_triangles;
124bool IsPointInsideTriangle(Point p, std::array<Point, 3> triangle) {
125 if (SimilarPoint(p, triangle[0]) ||
126 SimilarPoint(p, triangle[1]) ||
127 SimilarPoint(p, triangle[2])) {
132 return direction *
Point::Cross(p, triangle[1], triangle[2]) > 0 &&
133 direction *
Point::Cross(p, triangle[2], triangle[0]) > 0;
140bool DoTrianglesOverlap(
141 const std::shared_ptr<ShadowVertices>& shadow_vertices) {
142 auto vertices = shadow_vertices->GetVertices();
143 auto indices = shadow_vertices->GetIndices();
144 size_t index_count = indices.size();
145 size_t vertex_count = vertices.size();
147 for (
size_t i = 0u;
i < index_count;
i += 3) {
148 std::array triangle = {
149 vertices[indices[
i + 0]],
150 vertices[indices[
i + 1]],
151 vertices[indices[
i + 2]],
156 for (
size_t j = 0; j < vertex_count; j++) {
157 if (IsPointInsideTriangle(vertices[j], triangle)) {
158 FML_LOG(ERROR) <<
"Point " << vertices[j] <<
" inside triangle ["
159 << triangle[0] <<
", "
160 << triangle[1] <<
", "
161 << triangle[2] <<
"]";
162 FML_LOG(ERROR) <<
"Point - corner[0] == " << vertices[j] - triangle[0];
163 FML_LOG(ERROR) <<
"Point - corner[1] == " << vertices[j] - triangle[1];
164 FML_LOG(ERROR) <<
"Point - corner[2] == " << vertices[j] - triangle[2];
175TEST(ShadowPathGeometryTest, EmptyPathTest) {
182 std::shared_ptr<ShadowVertices> shadow_vertices =
186 ASSERT_NE(shadow_vertices,
nullptr);
187 EXPECT_TRUE(shadow_vertices->IsEmpty());
190TEST(ShadowPathGeometryTest, MoveToOnlyTest) {
198 std::shared_ptr<ShadowVertices> shadow_vertices =
202 ASSERT_NE(shadow_vertices,
nullptr);
203 EXPECT_TRUE(shadow_vertices->IsEmpty());
206TEST(ShadowPathGeometryTest, OnePathSegmentTest) {
215 std::shared_ptr<ShadowVertices> shadow_vertices =
219 ASSERT_NE(shadow_vertices,
nullptr);
220 EXPECT_TRUE(shadow_vertices->IsEmpty());
223TEST(ShadowPathGeometryTest, TwoColinearSegmentsTest) {
233 std::shared_ptr<ShadowVertices> shadow_vertices =
237 ASSERT_NE(shadow_vertices,
nullptr);
238 EXPECT_TRUE(shadow_vertices->IsEmpty());
241TEST(ShadowPathGeometryTest, EmptyRectTest) {
247 path_builder.
Close();
253 std::shared_ptr<ShadowVertices> shadow_vertices =
257 ASSERT_NE(shadow_vertices,
nullptr);
258 EXPECT_TRUE(shadow_vertices->IsEmpty());
261TEST(ShadowPathGeometryTest, GetAndTakeVertices) {
269 for (
int i = 0;
i < 10;
i++) {
270 EXPECT_TRUE(geometry.GetShadowVertices());
274 EXPECT_TRUE(geometry.TakeShadowVertices());
277 EXPECT_FALSE(geometry.GetShadowVertices());
278 EXPECT_FALSE(geometry.TakeShadowVertices());
281TEST(ShadowPathGeometryTest, ClockwiseTriangleTest) {
286 path_builder.
Close();
292 std::shared_ptr<ShadowVertices> shadow_vertices =
296 ASSERT_NE(shadow_vertices,
nullptr);
297 EXPECT_FALSE(shadow_vertices->IsEmpty());
298 EXPECT_EQ(shadow_vertices->GetVertexCount(), 33u);
299 EXPECT_EQ(shadow_vertices->GetIndexCount(), 102u);
300 EXPECT_EQ(shadow_vertices->GetVertices().size(), 33u);
301 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 33u);
302 EXPECT_EQ(shadow_vertices->GetIndices().size(), 102u);
303 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
306 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 2u);
307 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
308 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
310#if SHADOW_UNITTEST_SHOW_VERTICES
311 ShowVertices(
"Impeller Vertices", shadow_vertices);
315TEST(ShadowPathGeometryTest, CounterClockwiseTriangleTest) {
320 path_builder.
Close();
326 std::shared_ptr<ShadowVertices> shadow_vertices =
330 ASSERT_NE(shadow_vertices,
nullptr);
331 EXPECT_FALSE(shadow_vertices->IsEmpty());
332 EXPECT_EQ(shadow_vertices->GetVertexCount(), 33u);
333 EXPECT_EQ(shadow_vertices->GetIndexCount(), 102u);
334 EXPECT_EQ(shadow_vertices->GetVertices().size(), 33u);
335 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 33u);
336 EXPECT_EQ(shadow_vertices->GetIndices().size(), 102u);
337 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
340 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 2u);
341 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
342 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
344#if SHADOW_UNITTEST_SHOW_VERTICES
345 ShowVertices(
"Impeller Vertices", shadow_vertices);
349TEST(ShadowPathGeometryTest, ClockwiseRectTest) {
355 path_builder.
Close();
361 std::shared_ptr<ShadowVertices> shadow_vertices =
365 ASSERT_NE(shadow_vertices,
nullptr);
366 EXPECT_FALSE(shadow_vertices->IsEmpty());
367 EXPECT_EQ(shadow_vertices->GetVertexCount(), 34u);
368 EXPECT_EQ(shadow_vertices->GetIndexCount(), 108u);
369 EXPECT_EQ(shadow_vertices->GetVertices().size(), 34u);
370 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 34u);
371 EXPECT_EQ(shadow_vertices->GetIndices().size(), 108u);
372 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
374 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
375 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
376 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
378#if SHADOW_UNITTEST_SHOW_VERTICES
379 ShowVertices(
"Impeller Vertices", shadow_vertices);
383TEST(ShadowPathGeometryTest, CounterClockwiseRectTest) {
389 path_builder.
Close();
395 std::shared_ptr<ShadowVertices> shadow_vertices =
399 ASSERT_NE(shadow_vertices,
nullptr);
400 EXPECT_FALSE(shadow_vertices->IsEmpty());
401 EXPECT_EQ(shadow_vertices->GetVertexCount(), 34u);
402 EXPECT_EQ(shadow_vertices->GetIndexCount(), 108u);
403 EXPECT_EQ(shadow_vertices->GetVertices().size(), 34u);
404 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 34u);
405 EXPECT_EQ(shadow_vertices->GetIndices().size(), 108u);
406 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
408 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
409 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
410 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
412#if SHADOW_UNITTEST_SHOW_VERTICES
413 ShowVertices(
"Impeller Vertices", shadow_vertices);
417TEST(ShadowPathGeometryTest, ClockwiseRectExtraColinearPointsTest) {
431 path_builder.
Close();
437 std::shared_ptr<ShadowVertices> shadow_vertices =
441 ASSERT_NE(shadow_vertices,
nullptr);
442 EXPECT_FALSE(shadow_vertices->IsEmpty());
443 EXPECT_EQ(shadow_vertices->GetVertexCount(), 34u);
444 EXPECT_EQ(shadow_vertices->GetIndexCount(), 108u);
445 EXPECT_EQ(shadow_vertices->GetVertices().size(), 34u);
446 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 34u);
447 EXPECT_EQ(shadow_vertices->GetIndices().size(), 108u);
448 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
450 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
451 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
452 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
454#if SHADOW_UNITTEST_SHOW_VERTICES
455 ShowVertices(
"Impeller Vertices", shadow_vertices);
459TEST(ShadowPathGeometryTest, CounterClockwiseRectExtraColinearPointsTest) {
473 path_builder.
Close();
479 std::shared_ptr<ShadowVertices> shadow_vertices =
483 ASSERT_NE(shadow_vertices,
nullptr);
484 EXPECT_FALSE(shadow_vertices->IsEmpty());
485 EXPECT_EQ(shadow_vertices->GetVertexCount(), 34u);
486 EXPECT_EQ(shadow_vertices->GetIndexCount(), 108u);
487 EXPECT_EQ(shadow_vertices->GetVertices().size(), 34u);
488 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 34u);
489 EXPECT_EQ(shadow_vertices->GetIndices().size(), 108u);
490 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
492 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
493 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
494 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
496#if SHADOW_UNITTEST_SHOW_VERTICES
497 ShowVertices(
"Impeller Vertices", shadow_vertices);
501TEST(ShadowPathGeometryTest, ClockwiseRectTrickyColinearPointsTest) {
514 path_builder.
Close();
520 std::shared_ptr<ShadowVertices> shadow_vertices =
524 ASSERT_NE(shadow_vertices,
nullptr);
525 EXPECT_FALSE(shadow_vertices->IsEmpty());
526 EXPECT_EQ(shadow_vertices->GetVertexCount(), 34u);
527 EXPECT_EQ(shadow_vertices->GetIndexCount(), 108u);
528 EXPECT_EQ(shadow_vertices->GetVertices().size(), 34u);
529 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 34u);
530 EXPECT_EQ(shadow_vertices->GetIndices().size(), 108u);
531 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
533 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
534 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
535 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
537#if SHADOW_UNITTEST_SHOW_VERTICES
538 ShowVertices(
"Impeller Vertices", shadow_vertices);
542TEST(ShadowPathGeometryTest, CounterClockwiseRectTrickyColinearPointsTest) {
555 path_builder.
Close();
561 std::shared_ptr<ShadowVertices> shadow_vertices =
565 ASSERT_NE(shadow_vertices,
nullptr);
566 EXPECT_FALSE(shadow_vertices->IsEmpty());
567 EXPECT_EQ(shadow_vertices->GetVertexCount(), 34u);
568 EXPECT_EQ(shadow_vertices->GetIndexCount(), 108u);
569 EXPECT_EQ(shadow_vertices->GetVertices().size(), 34u);
570 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 34u);
571 EXPECT_EQ(shadow_vertices->GetIndices().size(), 108u);
572 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
574 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
575 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
576 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
578#if SHADOW_UNITTEST_SHOW_VERTICES
579 ShowVertices(
"Impeller Vertices", shadow_vertices);
583TEST(ShadowPathGeometryTest, ClockwiseRectTrickyDupColinearPointsTest) {
602 path_builder.
Close();
608 std::shared_ptr<ShadowVertices> shadow_vertices =
612 ASSERT_NE(shadow_vertices,
nullptr);
613 EXPECT_FALSE(shadow_vertices->IsEmpty());
614 EXPECT_EQ(shadow_vertices->GetVertexCount(), 34u);
615 EXPECT_EQ(shadow_vertices->GetIndexCount(), 108u);
616 EXPECT_EQ(shadow_vertices->GetVertices().size(), 34u);
617 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 34u);
618 EXPECT_EQ(shadow_vertices->GetIndices().size(), 108u);
619 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
621 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
622 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
623 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
625#if SHADOW_UNITTEST_SHOW_VERTICES
626 ShowVertices(
"Impeller Vertices", shadow_vertices);
630TEST(ShadowPathGeometryTest, CounterClockwiseRectTrickyDupColinearPointsTest) {
649 path_builder.
Close();
655 std::shared_ptr<ShadowVertices> shadow_vertices =
659 ASSERT_NE(shadow_vertices,
nullptr);
660 EXPECT_FALSE(shadow_vertices->IsEmpty());
661 EXPECT_EQ(shadow_vertices->GetVertexCount(), 34u);
662 EXPECT_EQ(shadow_vertices->GetIndexCount(), 108u);
663 EXPECT_EQ(shadow_vertices->GetVertices().size(), 34u);
664 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 34u);
665 EXPECT_EQ(shadow_vertices->GetIndices().size(), 108u);
666 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
668 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
669 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
670 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
672#if SHADOW_UNITTEST_SHOW_VERTICES
673 ShowVertices(
"Impeller Vertices", shadow_vertices);
677TEST(ShadowPathGeometryTest, ClockwiseRectNearlyColinearPointsTest) {
691 path_builder.
Close();
697 std::shared_ptr<ShadowVertices> shadow_vertices =
701 ASSERT_NE(shadow_vertices,
nullptr);
702 EXPECT_FALSE(shadow_vertices->IsEmpty());
703 EXPECT_EQ(shadow_vertices->GetVertexCount(), 37u);
704 EXPECT_EQ(shadow_vertices->GetIndexCount(), 120u);
705 EXPECT_EQ(shadow_vertices->GetVertices().size(), 37u);
706 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 37u);
707 EXPECT_EQ(shadow_vertices->GetIndices().size(), 120u);
708 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
710 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
711 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
712 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
714#if SHADOW_UNITTEST_SHOW_VERTICES
715 ShowVertices(
"Impeller Vertices", shadow_vertices);
719TEST(ShadowPathGeometryTest, CounterClockwiseRectNearlyColinearPointsTest) {
733 path_builder.
Close();
739 std::shared_ptr<ShadowVertices> shadow_vertices =
743 ASSERT_NE(shadow_vertices,
nullptr);
744 EXPECT_FALSE(shadow_vertices->IsEmpty());
745 EXPECT_EQ(shadow_vertices->GetVertexCount(), 37u);
746 EXPECT_EQ(shadow_vertices->GetIndexCount(), 120u);
747 EXPECT_EQ(shadow_vertices->GetVertices().size(), 37u);
748 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 37u);
749 EXPECT_EQ(shadow_vertices->GetIndices().size(), 120u);
750 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
752 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
753 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
754 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
756#if SHADOW_UNITTEST_SHOW_VERTICES
757 ShowVertices(
"Impeller Vertices", shadow_vertices);
761TEST(ShadowPathGeometryTest, ScaledRectTest) {
767 std::shared_ptr<ShadowVertices> shadow_vertices =
771 ASSERT_NE(shadow_vertices,
nullptr);
772 EXPECT_FALSE(shadow_vertices->IsEmpty());
773 EXPECT_EQ(shadow_vertices->GetVertexCount(), 34u);
774 EXPECT_EQ(shadow_vertices->GetIndexCount(), 108u);
775 EXPECT_EQ(shadow_vertices->GetVertices().size(), 34u);
776 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 34u);
777 EXPECT_EQ(shadow_vertices->GetIndices().size(), 108u);
778 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
780 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
781 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
782 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
784#if SHADOW_UNITTEST_SHOW_VERTICES
785 ShowVertices(
"Impeller Vertices", shadow_vertices);
789TEST(ShadowPathGeometryTest, EllipseTest) {
795 std::shared_ptr<ShadowVertices> shadow_vertices =
799 ASSERT_NE(shadow_vertices,
nullptr);
800 EXPECT_FALSE(shadow_vertices->IsEmpty());
801 EXPECT_EQ(shadow_vertices->GetVertexCount(), 122u);
802 EXPECT_EQ(shadow_vertices->GetIndexCount(), 480u);
803 EXPECT_EQ(shadow_vertices->GetVertices().size(), 122u);
804 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 122u);
805 EXPECT_EQ(shadow_vertices->GetIndices().size(), 480u);
806 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
808 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 1u);
809 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
810 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
813TEST(ShadowPathGeometryTest, RoundRectTest) {
819 std::shared_ptr<ShadowVertices> shadow_vertices =
823 ASSERT_NE(shadow_vertices,
nullptr);
824 EXPECT_FALSE(shadow_vertices->IsEmpty());
825 EXPECT_EQ(shadow_vertices->GetVertexCount(), 55u);
826 EXPECT_EQ(shadow_vertices->GetIndexCount(), 168u);
827 EXPECT_EQ(shadow_vertices->GetVertices().size(), 55u);
828 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 55u);
829 EXPECT_EQ(shadow_vertices->GetIndices().size(), 168u);
830 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
833 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 2u);
834 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
835 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
838TEST(ShadowPathGeometryTest, HourglassSelfIntersectingTest) {
844 path_builder.
Close();
850 std::shared_ptr<ShadowVertices> shadow_vertices =
854 EXPECT_EQ(shadow_vertices,
nullptr);
857TEST(ShadowPathGeometryTest, ReverseHourglassSelfIntersectingTest) {
863 path_builder.
Close();
869 std::shared_ptr<ShadowVertices> shadow_vertices =
873 EXPECT_EQ(shadow_vertices,
nullptr);
876TEST(ShadowPathGeometryTest, InnerToOuterOverturningSpiralTest) {
883 for (
int i = 1;
i < step_count * 2;
i++) {
885 Scalar radius = 80.0f + std::abs(
i - step_count);
887 std::sin(angle) * radius));
889 path_builder.
Close();
893 std::shared_ptr<ShadowVertices> shadow_vertices =
897 EXPECT_EQ(shadow_vertices,
nullptr);
900TEST(ShadowPathGeometryTest, ReverseInnerToOuterOverturningSpiralTest) {
907 for (
int i = 1;
i < step_count * 2;
i++) {
909 Scalar radius = 80.0f + std::abs(
i - step_count);
911 std::sin(angle) * radius));
913 path_builder.
Close();
917 std::shared_ptr<ShadowVertices> shadow_vertices =
921 EXPECT_EQ(shadow_vertices,
nullptr);
924TEST(ShadowPathGeometryTest, OuterToInnerOverturningSpiralTest) {
931 for (
int i = 1;
i < step_count * 2;
i++) {
933 Scalar radius = 100.0f - std::abs(
i - step_count);
935 std::sin(angle) * radius));
937 path_builder.
Close();
941 std::shared_ptr<ShadowVertices> shadow_vertices =
945 EXPECT_EQ(shadow_vertices,
nullptr);
948TEST(ShadowPathGeometryTest, ReverseOuterToInnerOverturningSpiralTest) {
955 for (
int i = 1;
i < step_count * 2;
i++) {
957 Scalar radius = 100.0f - std::abs(
i - step_count);
959 std::sin(angle) * radius));
961 path_builder.
Close();
965 std::shared_ptr<ShadowVertices> shadow_vertices =
969 EXPECT_EQ(shadow_vertices,
nullptr);
972TEST(ShadowPathGeometryTest, ClockwiseOctagonCollapsedUmbraPolygonTest) {
985 path_builder.
Close();
989 std::shared_ptr<ShadowVertices> shadow_vertices =
993 ASSERT_NE(shadow_vertices,
nullptr);
994 EXPECT_FALSE(shadow_vertices->IsEmpty());
995 EXPECT_EQ(shadow_vertices->GetVertexCount(), 87u);
996 EXPECT_EQ(shadow_vertices->GetIndexCount(), 267u);
997 EXPECT_EQ(shadow_vertices->GetVertices().size(), 87u);
998 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 87u);
999 EXPECT_EQ(shadow_vertices->GetIndices().size(), 267u);
1000 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
1003 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 3u);
1004 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
1005 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
1008TEST(ShadowPathGeometryTest, CounterClockwiseOctagonCollapsedUmbraPolygonTest) {
1021 path_builder.
Close();
1025 std::shared_ptr<ShadowVertices> shadow_vertices =
1029 ASSERT_NE(shadow_vertices,
nullptr);
1030 EXPECT_FALSE(shadow_vertices->IsEmpty());
1031 EXPECT_EQ(shadow_vertices->GetVertexCount(), 88u);
1032 EXPECT_EQ(shadow_vertices->GetIndexCount(), 267u);
1033 EXPECT_EQ(shadow_vertices->GetVertices().size(), 88u);
1034 EXPECT_EQ(shadow_vertices->GetGaussians().size(), 88u);
1035 EXPECT_EQ(shadow_vertices->GetIndices().size(), 267u);
1036 EXPECT_EQ((shadow_vertices->GetIndices().size() % 3u), 0u);
1039 EXPECT_LE(CountDuplicateVertices(shadow_vertices), 3u);
1040 EXPECT_EQ(CountDuplicateTriangles(shadow_vertices), 0u);
1041 EXPECT_FALSE(DoTrianglesOverlap(shadow_vertices));
1044TEST(ShadowPathGeometryTest, MultipleContoursTest) {
1052 path_builder.
Close();
1056 path_builder.
Close();
1060 std::shared_ptr<ShadowVertices> shadow_vertices =
1064 EXPECT_EQ(shadow_vertices,
nullptr);
DlPathBuilder & LineTo(DlPoint p2)
Draw a line from the current point to the indicated point p2.
DlPathBuilder & MoveTo(DlPoint p2)
Start a new contour that will originate at the indicated point p2.
const DlPath TakePath()
Returns the path constructed by this path builder and resets its internal state to the default state ...
DlPathBuilder & Close()
The path is closed back to the location of the most recent MoveTo call. Contours that are filled are ...
static DlPath MakeRectLTRB(DlScalar left, DlScalar top, DlScalar right, DlScalar bottom)
static DlPath MakeRect(const DlRect &rect)
static DlPath MakeRoundRectXY(const DlRect &rect, DlScalar x_radius, DlScalar y_radius, bool counter_clock_wise=false)
static DlPath MakeOval(const DlRect &bounds)
static std::shared_ptr< ShadowVertices > MakeAmbientShadowVertices(Tessellator &tessellator, const PathSource &source, Scalar occluder_height, const Matrix &matrix)
A utility that generates triangles of the specified fill type given a polyline. This happens on the C...
#define FML_LOG(severity)
TEST(FrameTimingsRecorderTest, RecordVsync)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
static constexpr DlScalar kEhCloseEnough
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeScale(const Vector3 &s)
constexpr Type Cross(const TPoint &p) const
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)