5 #include "gtest/gtest.h"
11 #include <type_traits>
13 #include "flutter/fml/build_config.h"
14 #include "flutter/testing/testing.h"
37 1.0f, 1.0f + std::numeric_limits<float>::epsilon() * 4));
40 TEST(GeometryTest, MakeColumn) {
46 auto expect =
Matrix{1, 2, 3, 4,
51 ASSERT_TRUE(matrix == expect);
54 TEST(GeometryTest, MakeRow) {
60 auto expect =
Matrix{1, 5, 9, 13,
65 ASSERT_TRUE(matrix == expect);
68 TEST(GeometryTest, RotationMatrix) {
79 TEST(GeometryTest, InvertMultMatrix) {
82 auto invert = rotation.
Invert();
93 auto invert = scale.
Invert();
94 auto expect =
Matrix{0.5, 0, 0, 0,
102 TEST(GeometryTest, MatrixBasis) {
103 auto matrix =
Matrix{1, 2, 3, 4,
107 auto basis = matrix.
Basis();
108 auto expect =
Matrix{1, 2, 3, 0,
115 TEST(GeometryTest, MutliplicationMatrix) {
117 auto invert = rotation.
Invert();
121 TEST(GeometryTest, DeterminantTest) {
122 auto matrix =
Matrix{3, 4, 14, 155, 2, 1, 3, 4, 2, 3, 2, 1, 1, 2, 4, 2};
123 ASSERT_EQ(matrix.GetDeterminant(), -1889);
126 TEST(GeometryTest, InvertMatrix) {
127 auto inverted =
Matrix{10, -9, -12, 8,
134 438.0 / 85123.0, 1751.0 / 85123.0, -7783.0 / 85123.0, 4672.0 / 85123.0,
135 393.0 / 85123.0, -178.0 / 85123.0, -570.0 / 85123.0, 4192 / 85123.0,
136 -5230.0 / 85123.0, 2802.0 / 85123.0, -3461.0 / 85123.0, 962.0 / 85123.0,
137 2690.0 / 85123.0, 1814.0 / 85123.0, 3896.0 / 85123.0, 319.0 / 85123.0};
142 TEST(GeometryTest, TestDecomposition) {
147 ASSERT_TRUE(result.has_value());
155 TEST(GeometryTest, TestDecomposition2) {
160 auto result = (translated * rotated * scaled).Decompose();
162 ASSERT_TRUE(result.has_value());
174 ASSERT_FLOAT_EQ(res.
scale.
x, 2);
175 ASSERT_FLOAT_EQ(res.
scale.
y, 3);
176 ASSERT_FLOAT_EQ(res.
scale.
z, 1);
179 TEST(GeometryTest, TestRecomposition) {
187 ASSERT_TRUE(result.has_value());
201 TEST(GeometryTest, TestRecomposition2) {
208 ASSERT_TRUE(result.has_value());
213 TEST(GeometryTest, MatrixVectorMultiplication) {
218 auto vector =
Vector4(10, 20, 30, 2);
220 Vector4 result = matrix * vector;
221 auto expected =
Vector4(160, 220, 260, 2);
229 auto vector =
Vector3(10, 20, 30);
231 Vector3 result = matrix * vector;
232 auto expected =
Vector3(60, 120, 160);
240 auto vector =
Point(10, 20);
242 Point result = matrix * vector;
243 auto expected =
Point(60, 120);
250 auto vector =
Vector3(3, 3, -3);
252 Vector3 result = matrix * vector;
253 auto expected =
Vector3(-1, -1, 1.3468);
260 auto point =
Point(3, 3);
262 Point result = matrix * point;
263 auto expected =
Point(-1, -1);
270 auto point =
Point(3, 3);
272 Point result = matrix * point;
273 auto expected =
Point(0, 0);
278 TEST(GeometryTest, MatrixMakeRotationFromQuaternion) {
298 TEST(GeometryTest, MatrixTransformDirection) {
303 auto vector =
Vector4(10, 20, 30, 2);
305 Vector4 result = matrix.TransformDirection(vector);
306 auto expected =
Vector4(-40, 20, 60, 2);
314 auto vector =
Vector3(10, 20, 30);
316 Vector3 result = matrix.TransformDirection(vector);
317 auto expected =
Vector3(-40, 20, 60);
325 auto vector =
Point(10, 20);
327 Point result = matrix.TransformDirection(vector);
328 auto expected =
Point(-40, 20);
333 TEST(GeometryTest, MatrixGetMaxBasisLengthXY) {
336 ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
339 ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
344 ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
350 1.0f, 0.0f, 0.0f, 0.0f,
351 0.0f, 1.0f, 0.0f, 0.0f,
352 4.0f, 0.0f, 1.0f, 0.0f,
353 0.0f, 0.0f, 0.0f, 1.0f
356 ASSERT_EQ(m.GetMaxBasisLengthXY(), 1.0f);
360 TEST(GeometryTest, MatrixMakeOrthographic) {
384 TEST(GeometryTest, MatrixMakePerspective) {
408 TEST(GeometryTest, MatrixGetBasisVectors) {
432 TEST(GeometryTest, MatrixGetDirectionScale) {
436 ASSERT_FLOAT_EQ(result, 1);
444 ASSERT_FLOAT_EQ(result, 1);
451 ASSERT_FLOAT_EQ(result, 8);
455 TEST(GeometryTest, MatrixTranslationScaleOnly) {
458 bool result = m.IsTranslationScaleOnly();
464 bool result = m.IsTranslationScaleOnly();
470 bool result = m.IsTranslationScaleOnly();
476 bool result = m.IsTranslationScaleOnly();
477 ASSERT_FALSE(result);
481 TEST(GeometryTest, MatrixLookAt) {
527 TEST(GeometryTest, QuaternionLerp) {
531 auto q3 = q1.Slerp(q2, 0.5);
538 TEST(GeometryTest, QuaternionVectorMultiply) {
580 TEST(GeometryTest, CanGenerateMipCounts) {
593 TEST(GeometryTest, CanConvertTTypesExplicitly) {
604 ASSERT_EQ(s2.
width, 1u);
616 TEST(GeometryTest, CanPerformAlgebraicPointOps) {
646 TEST(GeometryTest, CanPerformAlgebraicPointOpsWithArithmeticTypes) {
678 TEST(GeometryTest, PointIntegerCoercesToFloat) {
683 ASSERT_FLOAT_EQ(p2.
x, 2u);
684 ASSERT_FLOAT_EQ(p2.
y, 4u);
690 ASSERT_FLOAT_EQ(p2.
x, 2u);
691 ASSERT_FLOAT_EQ(p2.
y, 4u);
697 ASSERT_FLOAT_EQ(p2.
x, 2u);
698 ASSERT_FLOAT_EQ(p2.
y, 6u);
704 ASSERT_FLOAT_EQ(p2.
x, 1u);
705 ASSERT_FLOAT_EQ(p2.
y, 2u);
712 ASSERT_FLOAT_EQ(p2.
x, 2u);
713 ASSERT_FLOAT_EQ(p2.
y, 4u);
719 ASSERT_FLOAT_EQ(p2.
x, 2u);
720 ASSERT_FLOAT_EQ(p2.
y, 4u);
726 ASSERT_FLOAT_EQ(p2.
x, 2u);
727 ASSERT_FLOAT_EQ(p2.
y, 6u);
733 ASSERT_FLOAT_EQ(p2.
x, 1u);
734 ASSERT_FLOAT_EQ(p2.
y, 2u);
738 TEST(GeometryTest, SizeCoercesToPoint) {
798 TEST(GeometryTest, CanUsePointAssignmentOperators) {
873 TEST(GeometryTest, PointDotProduct) {
877 ASSERT_FLOAT_EQ(s, -1);
883 ASSERT_FLOAT_EQ(s, 0);
889 ASSERT_FLOAT_EQ(s, -5);
893 TEST(GeometryTest, PointCrossProduct) {
897 ASSERT_FLOAT_EQ(s, 0);
903 ASSERT_FLOAT_EQ(s, -1);
909 ASSERT_FLOAT_EQ(s, -10);
913 TEST(GeometryTest, PointReflect) {
917 auto reflected = a.
Reflect(axis);
918 auto expected =
Point(2, -3);
925 auto reflected = a.
Reflect(axis);
926 auto expected =
Point(0, -1);
933 auto reflected = a.
Reflect(axis);
940 auto a_abs = a.
Abs();
941 auto expected =
Point(1, 2);
945 TEST(GeometryTest, PointRotate) {
949 auto expected =
Point(0, 1);
956 auto expected =
Point(0, -1);
963 auto expected =
Point(-1, 0);
970 auto expected =
Point(0, -1);
975 TEST(GeometryTest, PointAngleTo) {
1007 Point expected(0, 2);
1011 TEST(GeometryTest, Vector4IsFinite) {
1015 v.
x = std::numeric_limits<Scalar>::infinity();
1017 v.
x = -std::numeric_limits<Scalar>::infinity();
1019 v.
x = -std::numeric_limits<Scalar>::quiet_NaN();
1026 v.
y = std::numeric_limits<Scalar>::infinity();
1028 v.
y = -std::numeric_limits<Scalar>::infinity();
1030 v.
y = -std::numeric_limits<Scalar>::quiet_NaN();
1037 v.
z = std::numeric_limits<Scalar>::infinity();
1039 v.
z = -std::numeric_limits<Scalar>::infinity();
1041 v.
z = -std::numeric_limits<Scalar>::quiet_NaN();
1048 v.
w = std::numeric_limits<Scalar>::infinity();
1050 v.
w = -std::numeric_limits<Scalar>::infinity();
1052 v.
w = -std::numeric_limits<Scalar>::quiet_NaN();
1074 Point expected(1, 10);
1088 Vector4 expected(1, 10, 3, 4);
1095 Point expected(1, 2);
1107 Vector4 p(1.5, 2.3, 3.9, 4.0);
1116 Point expected(2, 3);
1128 Vector4 p(1.5, 2.3, 3.9, 4.0);
1137 Point expected(2, 2);
1149 Vector4 p(1.5, 2.3, 3.9, 4.0);
1158 Point expected(4, 8);
1172 Vector4 expected(4, 8, 12, 16);
1176 TEST(GeometryTest, SeparatedVector2NormalizesWithConstructor) {
1182 TEST(GeometryTest, SeparatedVector2GetVector) {
1187 TEST(GeometryTest, SeparatedVector2GetAlignment) {
1210 TEST(GeometryTest, SeparatedVector2AngleTo) {
1226 TEST(GeometryTest, CanUseVector3AssignmentOperators) {
1248 ASSERT_EQ(p.
z, 12u);
1276 TEST(GeometryTest, CanPerformAlgebraicVector3Ops) {
1280 ASSERT_EQ(p2.
x, 2u);
1281 ASSERT_EQ(p2.
y, 4u);
1282 ASSERT_EQ(p2.
z, 6u);
1288 ASSERT_EQ(p2.
x, 2u);
1289 ASSERT_EQ(p2.
y, 4u);
1290 ASSERT_EQ(p2.
z, 6u);
1296 ASSERT_EQ(p2.
x, 2u);
1297 ASSERT_EQ(p2.
y, 6u);
1298 ASSERT_EQ(p2.
z, 12u);
1304 ASSERT_EQ(p2.
x, 1u);
1305 ASSERT_EQ(p2.
y, 2u);
1306 ASSERT_EQ(p2.
z, 3u);
1310 TEST(GeometryTest, CanPerformAlgebraicVector3OpsWithArithmeticTypes) {
1323 ASSERT_EQ(p2.
x, -1);
1358 ASSERT_EQ(p2.
z, -1);
1378 TEST(GeometryTest, ColorPremultiply) {
1380 Color a(1.0, 0.5, 0.2, 0.5);
1387 Color a(0.5, 0.25, 0.1, 0.5);
1394 Color a(0.5, 0.25, 0.1, 0.0);
1401 TEST(GeometryTest, ColorR8G8B8A8) {
1403 Color a(1.0, 0.5, 0.2, 0.5);
1404 std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1409 Color a(0.0, 0.0, 0.0, 0.0);
1410 std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1415 Color a(1.0, 1.0, 1.0, 1.0);
1416 std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1423 Color a(0.0, 0.0, 0.0, 0.0);
1424 Color b(1.0, 1.0, 1.0, 1.0);
1433 Color a(0.2, 0.4, 1.0, 0.5);
1434 Color b(0.4, 1.0, 0.2, 0.3);
1463 TEST(GeometryTest, ColorMakeRGBA8) {
1478 Color b(0.247059, 0.498039, 0.74902, 0.498039);
1483 TEST(GeometryTest, ColorApplyColorMatrix) {
1492 auto expected =
Color(1, 1, 1, 1);
1504 auto expected =
Color(0.11, 0.22, 0.33, 0.44);
1509 TEST(GeometryTest, ColorLinearToSRGB) {
1512 auto expected =
Color(1, 1, 1, 1);
1518 auto expected =
Color(0, 0, 0, 0);
1524 auto expected =
Color(0.484529, 0.665185, 0.797738, 0.8);
1529 TEST(GeometryTest, ColorSRGBToLinear) {
1532 auto expected =
Color(1, 1, 1, 1);
1538 auto expected =
Color(0, 0, 0, 0);
1544 auto expected =
Color(0.0331048, 0.132868, 0.318547, 0.8);
1556 static const std::map<BlendMode, Color>
1686 #define _BLEND_MODE_RESULT_CHECK(blend_mode) \
1687 expected = ColorBlendTestData::kExpectedResults[source_i] \
1688 .find(BlendMode::k##blend_mode) \
1690 EXPECT_COLOR_NEAR(dst.Blend(src, BlendMode::k##blend_mode), expected);
1692 TEST(GeometryTest, ColorBlendReturnsExpectedResults) {
1694 for (
size_t source_i = 0;
1704 #define _BLEND_MODE_NAME_CHECK(blend_mode) \
1705 case BlendMode::k##blend_mode: \
1706 ASSERT_STREQ(result, #blend_mode); \
1710 using BlendT = std::underlying_type_t<BlendMode>;
1718 TEST(GeometryTest, CanConvertBetweenDegressAndRadians) {
1726 TEST(GeometryTest, MatrixPrinting) {
1728 std::stringstream stream;
1731 ASSERT_EQ(stream.str(), R
"((
1732 1.000000, 0.000000, 0.000000, 0.000000,
1733 0.000000, 1.000000, 0.000000, 0.000000,
1734 0.000000, 0.000000, 1.000000, 0.000000,
1735 0.000000, 0.000000, 0.000000, 1.000000,
1740 std::stringstream stream;
1744 ASSERT_EQ(stream.str(), R"((
1745 1.000000, 0.000000, 0.000000, 10.000000,
1746 0.000000, 1.000000, 0.000000, 20.000000,
1747 0.000000, 0.000000, 1.000000, 30.000000,
1748 0.000000, 0.000000, 0.000000, 1.000000,
1753 TEST(GeometryTest, PointPrinting) {
1755 std::stringstream stream;
1758 ASSERT_EQ(stream.str(), "(0, 0)");
1762 std::stringstream stream;
1765 ASSERT_EQ(stream.str(),
"(13, 37)");
1769 TEST(GeometryTest, Vector3Printing) {
1771 std::stringstream stream;
1774 ASSERT_EQ(stream.str(),
"(0, 0, 0)");
1778 std::stringstream stream;
1781 ASSERT_EQ(stream.str(),
"(1, 2, 3)");
1785 TEST(GeometryTest, Vector4Printing) {
1787 std::stringstream stream;
1790 ASSERT_EQ(stream.str(),
"(0, 0, 0, 1)");
1794 std::stringstream stream;
1797 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
1801 TEST(GeometryTest, ColorPrinting) {
1803 std::stringstream stream;
1806 ASSERT_EQ(stream.str(),
"(0, 0, 0, 0)");
1810 std::stringstream stream;
1811 Color m(1, 2, 3, 4);
1813 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
1828 std::vector<Scalar> stops = {0.0, 1.0};
1833 ASSERT_EQ(gradient.texture_size, 2u);
1840 std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
1843 ASSERT_EQ(gradient.texture_size, 5u);
1851 std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
1856 ASSERT_EQ(gradient.texture_size, 4u);
1862 std::vector<Scalar> stops = {0.0, 0.25, 1.0};
1866 std::vector<Color> lerped_colors = {
1874 ASSERT_EQ(gradient.texture_size, 5u);
1879 std::vector<Color> colors = {};
1880 std::vector<Scalar> stops = {};
1881 for (
auto i = 0u; i < 1025; i++) {
1883 stops.push_back(i / 1025.0);
1888 ASSERT_EQ(gradient.texture_size, 1024u);
1889 ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
1893 TEST(GeometryTest, HalfConversions) {
1894 #if defined(FML_OS_MACOSX) || defined(FML_OS_IOS) || \
1895 defined(FML_OS_IOS_SIMULATOR)
1919 ASSERT_EQ(
Half(0.5f),
Half(0.5f16));
1920 ASSERT_EQ(
Half(0.5),
Half(0.5f16));
1923 GTEST_SKIP() <<
"Half-precision floats (IEEE 754) are not portable and "
1924 "only used on Apple platforms.";
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
#define _BLEND_MODE_RESULT_CHECK(blend_mode)
#define _BLEND_MODE_NAME_CHECK(blend_mode)
#define ASSERT_VECTOR4_NEAR(a, b)
#define ASSERT_MATRIX_NEAR(a, b)
#define ASSERT_QUATERNION_NEAR(a, b)
#define ASSERT_COLOR_NEAR(a, b)
#define ASSERT_POINT_NEAR(a, b)
#define ASSERT_ARRAY_4_NEAR(a, b)
#define ASSERT_COLOR_BUFFER_NEAR(a, b)
#define ASSERT_VECTOR3_NEAR(a, b)
TEST(AllocationSizeTest, CanCreateTypedAllocations)
constexpr float kEhCloseEnough
constexpr InternalHalf ScalarToHalf(Scalar f)
Convert a scalar to a half precision float.
const char * BlendModeToString(BlendMode blend_mode)
GradientData CreateGradientBuffer(const std::vector< Color > &colors, const std::vector< Scalar > &stops)
Populate a vector with the interpolated color bytes for the linear gradient described by colors and s...
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
constexpr float k1OverSqrt2
std::array< uint8_t, 4 > ToR8G8B8A8() const
Convert to R8G8B8A8 representation.
static uint32_t ToIColor(Color color)
Convert this color to a 32-bit representation.
static constexpr Color LimeGreen()
static constexpr Color BlackTransparent()
Color LinearToSRGB() const
Convert the color from linear space to sRGB space.
static constexpr Color Black()
static constexpr Color CornflowerBlue()
static constexpr Color White()
constexpr Color WithAlpha(Scalar new_alpha) const
Color ApplyColorMatrix(const ColorMatrix &color_matrix) const
A color filter that transforms colors through a 4x5 color matrix.
static constexpr Color Red()
constexpr Color Unpremultiply() const
constexpr Color Premultiply() const
static constexpr Color MakeRGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
constexpr Color Clamp01() const
constexpr static Color Lerp(Color a, Color b, Scalar t)
Return a color that is linearly interpolated between colors a and b, according to the value of t.
static constexpr Color Yellow()
Color SRGBToLinear() const
Convert the color from sRGB space to linear space.
static constexpr Color Blue()
static constexpr Color Green()
A storage only class for half precision floating point.
A storage only class for half precision floating point vector 2.
A storage only class for half precision floating point vector 3.
A storage only class for half precision floating point vector 4.
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeOrthographic(TSize< T > size)
static constexpr Matrix MakeTranslation(const Vector3 &t)
Scalar GetDirectionScale(Vector3 direction) const
constexpr Matrix Basis() const
The Matrix without its w components (without translation).
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
static Matrix MakeRotationY(Radians r)
std::optional< MatrixDecomposition > Decompose() const
static Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
static constexpr Matrix MakeRow(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
static Matrix MakeRotationZ(Radians r)
static constexpr Matrix MakeScale(const Vector3 &s)
static Matrix MakeLookAt(Vector3 position, Vector3 target, Vector3 up)
static Matrix MakeRotation(Quaternion q)
static Matrix MakeRotationX(Radians r)
A Vector2, broken down as a separate magnitude and direction. Assumes that the direction given is nor...
Radians AngleTo(const SeparatedVector2 &other) const
Returns the scalar angle between the two rays.
Scalar GetAlignment(const SeparatedVector2 &other) const
Vector2 direction
The normalized direction of the vector.
Vector2 GetVector() const
Returns the vector representation of the vector.
Scalar magnitude
The magnitude of the vector.
constexpr TPoint Abs() const
static constexpr TPoint Round(const TPoint< U > &other)
constexpr TPoint Max(const TPoint &p) const
constexpr TPoint Ceil() const
constexpr TPoint Normalize() const
constexpr Type Cross(const TPoint &p) const
constexpr TPoint Lerp(const TPoint &p, Scalar t) const
constexpr TPoint Floor() const
constexpr TPoint Rotate(const Radians &angle) const
constexpr TPoint Reflect(const TPoint &axis) const
constexpr TPoint Min(const TPoint &p) const
constexpr Type Dot(const TPoint &p) const
constexpr Radians AngleTo(const TPoint &p) const
constexpr size_t MipCount() const
Return the mip count of the texture.
Vector3 Min(const Vector3 &p) const
constexpr Vector3 Lerp(const Vector3 &v, Scalar t) const
Vector3 Max(const Vector3 &p) const
constexpr Vector4 Min(const Vector4 &p) const
constexpr Vector4 Lerp(const Vector4 &v, Scalar t) const
constexpr Vector4 Max(const Vector4 &p) const
static constexpr Color kDestinationColor
static const std::map< BlendMode, Color > kExpectedResults[sizeof(kSourceColors)]
static constexpr Color kSourceColors[]