| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // We would like to use M_PI on windows too. |
| 6 #ifdef _WIN32 |
| 7 #define _USE_MATH_DEFINES |
| 8 #endif |
| 9 |
| 5 #include <limits> | 10 #include <limits> |
| 6 #include <vector> | 11 #include <vector> |
| 7 | 12 |
| 8 #include "cc/output/bsp_compare_result.h" | 13 #include "cc/output/bsp_compare_result.h" |
| 9 #include "cc/quads/draw_polygon.h" | 14 #include "cc/quads/draw_polygon.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 11 #include "ui/gfx/transform.h" | 16 #include "ui/gfx/transform.h" |
| 12 | 17 |
| 13 namespace cc { | 18 namespace cc { |
| 19 |
| 20 #if !defined(OS_WIN) |
| 21 void DrawPolygon::RecomputeNormalForTesting() { |
| 22 ConstructNormal(); |
| 23 } |
| 24 #endif |
| 25 |
| 14 namespace { | 26 namespace { |
| 15 | 27 |
| 16 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \ | 28 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \ |
| 17 DrawPolygon name(NULL, points_vector, normal, polygon_id) | 29 DrawPolygon name(NULL, points_vector, normal, polygon_id) |
| 18 | 30 |
| 31 #define CREATE_TEST_DRAW_POLYGON(name, points_vector, polygon_id) \ |
| 32 DrawPolygon name(NULL, points_vector, gfx::Vector3dF(1, 2, 3), polygon_id); \ |
| 33 name.RecomputeNormalForTesting() |
| 34 |
| 19 #define EXPECT_FLOAT_WITHIN_EPSILON_OF(a, b) \ | 35 #define EXPECT_FLOAT_WITHIN_EPSILON_OF(a, b) \ |
| 20 EXPECT_TRUE(std::abs(a - b) < std::numeric_limits<float>::epsilon()); | 36 EXPECT_TRUE(std::abs(a - b) < std::numeric_limits<float>::epsilon()); |
| 21 | 37 |
| 22 #define EXPECT_POINT_EQ(point_a, point_b) \ | 38 #define EXPECT_POINT_EQ(point_a, point_b) \ |
| 23 EXPECT_FLOAT_EQ(point_a.x(), point_b.x()); \ | 39 EXPECT_FLOAT_EQ(point_a.x(), point_b.x()); \ |
| 24 EXPECT_FLOAT_EQ(point_a.y(), point_b.y()); \ | 40 EXPECT_FLOAT_EQ(point_a.y(), point_b.y()); \ |
| 25 EXPECT_FLOAT_EQ(point_a.z(), point_b.z()); | 41 EXPECT_FLOAT_EQ(point_a.z(), point_b.z()); |
| 26 | 42 |
| 43 #define EXPECT_NORMAL(poly, n_x, n_y, n_z) \ |
| 44 EXPECT_FLOAT_WITHIN_EPSILON_OF(poly.normal().x(), n_x); \ |
| 45 EXPECT_FLOAT_WITHIN_EPSILON_OF(poly.normal().y(), n_y); \ |
| 46 EXPECT_FLOAT_WITHIN_EPSILON_OF(poly.normal().z(), n_z); |
| 47 |
| 27 static void ValidatePoints(const DrawPolygon& polygon, | 48 static void ValidatePoints(const DrawPolygon& polygon, |
| 28 const std::vector<gfx::Point3F>& points) { | 49 const std::vector<gfx::Point3F>& points) { |
| 29 EXPECT_EQ(polygon.points().size(), points.size()); | 50 EXPECT_EQ(polygon.points().size(), points.size()); |
| 30 for (size_t i = 0; i < points.size(); i++) { | 51 for (size_t i = 0; i < points.size(); i++) { |
| 31 EXPECT_POINT_EQ(polygon.points()[i], points[i]); | 52 EXPECT_POINT_EQ(polygon.points()[i], points[i]); |
| 32 } | 53 } |
| 33 } | 54 } |
| 34 | 55 |
| 56 // A simple square in a plane. |
| 57 TEST(DrawPolygonConstructionTest, NormalNormal) { |
| 58 gfx::Transform Identity; |
| 59 DrawPolygon polygon(NULL, gfx::RectF(10.0f, 10.0f), Identity, 1); |
| 60 EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); |
| 61 } |
| 62 |
| 63 // More complicated shapes. |
| 64 TEST(DrawPolygonConstructionTest, TestNormal) { |
| 65 std::vector<gfx::Point3F> vertices; |
| 66 vertices.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); |
| 67 vertices.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); |
| 68 vertices.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); |
| 69 vertices.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); |
| 70 |
| 71 CREATE_TEST_DRAW_POLYGON(polygon, vertices, 1); |
| 72 EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); |
| 73 } |
| 74 |
| 75 TEST(DrawPolygonConstructionTest, InverseNormal) { |
| 76 std::vector<gfx::Point3F> vertices; |
| 77 vertices.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); |
| 78 vertices.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); |
| 79 vertices.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); |
| 80 vertices.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); |
| 81 |
| 82 CREATE_TEST_DRAW_POLYGON(polygon, vertices, 1); |
| 83 EXPECT_NORMAL(polygon, 0.0f, 0.0f, -1.0f); |
| 84 } |
| 85 |
| 86 TEST(DrawPolygonConstructionTest, ClippedNormal) { |
| 87 std::vector<gfx::Point3F> vertices; |
| 88 vertices.push_back(gfx::Point3F(0.1f, 10.0f, 0.0f)); |
| 89 vertices.push_back(gfx::Point3F(0.0f, 9.9f, 0.0f)); |
| 90 vertices.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); |
| 91 vertices.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); |
| 92 vertices.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); |
| 93 vertices.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); |
| 94 |
| 95 CREATE_TEST_DRAW_POLYGON(polygon, vertices, 1); |
| 96 EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); |
| 97 } |
| 98 |
| 99 TEST(DrawPolygonConstructionTest, SlimTriangleNormal) { |
| 100 std::vector<gfx::Point3F> vertices; |
| 101 vertices.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); |
| 102 vertices.push_back(gfx::Point3F(5000.0f, 0.0f, 0.0f)); |
| 103 vertices.push_back(gfx::Point3F(10000.0f, 1.0f, 0.0f)); |
| 104 |
| 105 CREATE_TEST_DRAW_POLYGON(polygon, vertices, 2); |
| 106 EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); |
| 107 } |
| 108 |
| 109 TEST(DrawPolygonConstructionTest, ManyVertexNormal) { |
| 110 std::vector<gfx::Point3F> vertices_c; |
| 111 std::vector<gfx::Point3F> vertices_d; |
| 112 for (int i = 0; i < 100; i++) { |
| 113 vertices_c.push_back( |
| 114 gfx::Point3F(cos(i * M_PI / 50), sin(i * M_PI / 50), 0.0f)); |
| 115 vertices_d.push_back(gfx::Point3F(cos(i * M_PI / 50) + 99.0f, |
| 116 sin(i * M_PI / 50) + 99.0f, 100.0f)); |
| 117 } |
| 118 CREATE_TEST_DRAW_POLYGON(polygon_c, vertices_c, 3); |
| 119 EXPECT_NORMAL(polygon_c, 0.0f, 0.0f, 1.0f); |
| 120 |
| 121 CREATE_TEST_DRAW_POLYGON(polygon_d, vertices_d, 4); |
| 122 EXPECT_NORMAL(polygon_c, 0.0f, 0.0f, 1.0f); |
| 123 } |
| 124 |
| 125 // A simple rect being transformed. |
| 126 TEST(DrawPolygonConstructionTest, DizzyNormal) { |
| 127 gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); |
| 128 |
| 129 gfx::Transform transform_i(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); |
| 130 DrawPolygon polygon_i(NULL, src, transform_i, 1); |
| 131 |
| 132 EXPECT_NORMAL(polygon_i, 0.0f, 0.0f, 1.0f); |
| 133 |
| 134 gfx::Transform tranform_a(0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); |
| 135 DrawPolygon polygon_a(NULL, src, tranform_a, 2); |
| 136 EXPECT_NORMAL(polygon_a, 0.0f, 0.0f, -1.0f); |
| 137 |
| 138 gfx::Transform tranform_b(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1); |
| 139 DrawPolygon polygon_b(NULL, src, tranform_b, 3); |
| 140 EXPECT_NORMAL(polygon_b, -1.0f, 0.0f, 0.0f); |
| 141 |
| 142 gfx::Transform tranform_c(1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1); |
| 143 DrawPolygon polygon_c(NULL, src, tranform_c, 4); |
| 144 EXPECT_NORMAL(polygon_c, 0.0f, -1.0f, 0.0f); |
| 145 |
| 146 gfx::Transform tranform_d(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); |
| 147 DrawPolygon polygon_d(NULL, src, tranform_d, 5); |
| 148 EXPECT_NORMAL(polygon_d, 0.0f, 0.0f, -1.0f); |
| 149 } |
| 150 |
| 35 // Two quads are nearly touching but definitely ordered. Second one should | 151 // Two quads are nearly touching but definitely ordered. Second one should |
| 36 // compare in front. | 152 // compare in front. |
| 37 TEST(DrawPolygonSplitTest, NearlyTouchingOrder) { | 153 TEST(DrawPolygonSplitTest, NearlyTouchingOrder) { |
| 38 std::vector<gfx::Point3F> vertices_a; | 154 std::vector<gfx::Point3F> vertices_a; |
| 39 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); | 155 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); |
| 40 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | 156 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); |
| 41 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); | 157 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); |
| 42 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); | 158 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); |
| 43 std::vector<gfx::Point3F> vertices_b; | 159 std::vector<gfx::Point3F> vertices_b; |
| 44 vertices_b.push_back(gfx::Point3F(0.0f, 10.0f, -1.0f)); | 160 vertices_b.push_back(gfx::Point3F(0.0f, 10.0f, -1.0f)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 55 | 171 |
| 56 // Two quads are definitely not touching and so no split should occur. | 172 // Two quads are definitely not touching and so no split should occur. |
| 57 TEST(DrawPolygonSplitTest, NotClearlyInFront) { | 173 TEST(DrawPolygonSplitTest, NotClearlyInFront) { |
| 58 std::vector<gfx::Point3F> vertices_a; | 174 std::vector<gfx::Point3F> vertices_a; |
| 59 vertices_a.push_back(gfx::Point3F(87.2f, 1185.0f, 0.9f)); | 175 vertices_a.push_back(gfx::Point3F(87.2f, 1185.0f, 0.9f)); |
| 60 vertices_a.push_back(gfx::Point3F(288.3f, 1185.0f, -0.7f)); | 176 vertices_a.push_back(gfx::Point3F(288.3f, 1185.0f, -0.7f)); |
| 61 vertices_a.push_back(gfx::Point3F(288.3f, 1196.0f, -0.7f)); | 177 vertices_a.push_back(gfx::Point3F(288.3f, 1196.0f, -0.7f)); |
| 62 vertices_a.push_back(gfx::Point3F(87.2f, 1196.0f, 0.9f)); | 178 vertices_a.push_back(gfx::Point3F(87.2f, 1196.0f, 0.9f)); |
| 63 gfx::Vector3dF normal_a = gfx::CrossProduct(vertices_a[1] - vertices_a[0], | 179 gfx::Vector3dF normal_a = gfx::CrossProduct(vertices_a[1] - vertices_a[0], |
| 64 vertices_a[1] - vertices_a[2]); | 180 vertices_a[1] - vertices_a[2]); |
| 65 normal_a.Scale(1.0 / normal_a.Length()); | 181 normal_a.Scale(1.0f / normal_a.Length()); |
| 66 | 182 |
| 67 std::vector<gfx::Point3F> vertices_b; | 183 std::vector<gfx::Point3F> vertices_b; |
| 68 vertices_b.push_back(gfx::Point3F(62.1f, 1034.7f, 1.0f)); | 184 vertices_b.push_back(gfx::Point3F(62.1f, 1034.7f, 1.0f)); |
| 69 vertices_b.push_back(gfx::Point3F(313.4f, 1035.3f, -1.0f)); | 185 vertices_b.push_back(gfx::Point3F(313.4f, 1035.3f, -1.0f)); |
| 70 vertices_b.push_back(gfx::Point3F(313.4f, 1196.0f, -1.0f)); | 186 vertices_b.push_back(gfx::Point3F(313.4f, 1196.0f, -1.0f)); |
| 71 vertices_b.push_back(gfx::Point3F(62.1f, 1196.0f, 1.0f)); | 187 vertices_b.push_back(gfx::Point3F(62.1f, 1196.0f, 1.0f)); |
| 72 gfx::Vector3dF normal_b = gfx::CrossProduct(vertices_b[1] - vertices_b[0], | 188 gfx::Vector3dF normal_b = gfx::CrossProduct(vertices_b[1] - vertices_b[0], |
| 73 vertices_b[1] - vertices_b[2]); | 189 vertices_b[1] - vertices_b[2]); |
| 74 normal_b.Scale(1.0 / normal_b.Length()); | 190 normal_b.Scale(1.0f / normal_b.Length()); |
| 75 | 191 |
| 76 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, normal_a, 0); | 192 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, normal_a, 0); |
| 77 CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, normal_b, 1); | 193 CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, normal_b, 1); |
| 78 | 194 |
| 79 EXPECT_EQ(BSP_FRONT, DrawPolygon::SideCompare(polygon_b, polygon_a)); | 195 EXPECT_EQ(BSP_FRONT, DrawPolygon::SideCompare(polygon_b, polygon_a)); |
| 80 } | 196 } |
| 81 | 197 |
| 82 // Two quads are definitely not touching and so no split should occur. | 198 // Two quads are definitely not touching and so no split should occur. |
| 83 TEST(DrawPolygonSplitTest, NotTouchingNoSplit) { | 199 TEST(DrawPolygonSplitTest, NotTouchingNoSplit) { |
| 84 std::vector<gfx::Point3F> vertices_a; | 200 std::vector<gfx::Point3F> vertices_a; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | 320 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); |
| 205 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); | 321 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); |
| 206 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); | 322 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); |
| 207 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); | 323 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); |
| 208 | 324 |
| 209 ValidatePoints(*(front_polygon.get()), test_points_a); | 325 ValidatePoints(*(front_polygon.get()), test_points_a); |
| 210 ValidatePoints(*(back_polygon.get()), test_points_b); | 326 ValidatePoints(*(back_polygon.get()), test_points_b); |
| 211 } | 327 } |
| 212 | 328 |
| 213 TEST(DrawPolygonTransformTest, TransformNormal) { | 329 TEST(DrawPolygonTransformTest, TransformNormal) { |
| 214 // We give this polygon no actual vertices because we're not interested | |
| 215 // in actually transforming any points, just the normal. | |
| 216 std::vector<gfx::Point3F> vertices_a; | 330 std::vector<gfx::Point3F> vertices_a; |
| 331 vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 1.0f)); |
| 332 vertices_a.push_back(gfx::Point3F(-1.0f, 0.0f, -1.0f)); |
| 333 vertices_a.push_back(gfx::Point3F(0.0f, 1.0f, 0.0f)); |
| 217 CREATE_NEW_DRAW_POLYGON( | 334 CREATE_NEW_DRAW_POLYGON( |
| 218 polygon_a, vertices_a, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 0); | 335 polygon_a, vertices_a, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 0); |
| 336 // Check we believe your little white lie. |
| 337 EXPECT_NORMAL(polygon_a, 0.707107f, 0.0f, -0.707107f); |
| 338 |
| 339 polygon_a.RecomputeNormalForTesting(); |
| 340 // Check that we recompute it more accurately. |
| 341 EXPECT_NORMAL(polygon_a, sqrt(2) / 2, 0.0f, -sqrt(2) / 2); |
| 219 | 342 |
| 220 gfx::Transform transform; | 343 gfx::Transform transform; |
| 221 transform.RotateAboutYAxis(45.0); | 344 transform.RotateAboutYAxis(45.0f); |
| 222 // This would transform the vertices as well, but we are transforming a | 345 // This would transform the vertices as well, but we are transforming a |
| 223 // DrawPolygon with 0 vertices just to make sure our normal transformation | 346 // DrawPolygon with 0 vertices just to make sure our normal transformation |
| 224 // using the inverse tranpose matrix gives us the right result. | 347 // using the inverse tranpose matrix gives us the right result. |
| 225 polygon_a.TransformToScreenSpace(transform); | 348 polygon_a.TransformToScreenSpace(transform); |
| 226 | 349 |
| 227 // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here | 350 // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here |
| 228 // because some architectures (e.g., Arm64) employ a fused multiply-add | 351 // because some architectures (e.g., Arm64) employ a fused multiply-add |
| 229 // instruction which causes rounding asymmetry and reduces precision. | 352 // instruction which causes rounding asymmetry and reduces precision. |
| 230 // http://crbug.com/401117. | 353 // http://crbug.com/401117. |
| 231 EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().x(), 0); | 354 EXPECT_NORMAL(polygon_a, 0.0f, 0.0f, -1.0f); |
| 232 EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().y(), 0); | |
| 233 EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().z(), -1); | |
| 234 } | 355 } |
| 235 | 356 |
| 236 } // namespace | 357 } // namespace |
| 237 } // namespace cc | 358 } // namespace cc |
| OLD | NEW |