Chromium Code Reviews| 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 void DrawPolygon::RecomputeNormalForTesting() { | |
| 21 ConstructNormal(); | |
| 22 } | |
| 23 | |
| 14 namespace { | 24 namespace { |
| 15 | 25 |
| 16 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \ | 26 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \ |
| 17 DrawPolygon name(NULL, points_vector, normal, polygon_id) | 27 DrawPolygon name(NULL, points_vector, normal, polygon_id) |
| 18 | 28 |
| 29 #define CREATE_TEST_DRAW_POLYGON(name, points_vector, polygon_id) \ | |
| 30 DrawPolygon name(NULL, points_vector, gfx::Vector3dF(1, 2, 3), polygon_id); \ | |
| 31 name.RecomputeNormalForTesting() | |
| 32 | |
| 19 #define EXPECT_FLOAT_WITHIN_EPSILON_OF(a, b) \ | 33 #define EXPECT_FLOAT_WITHIN_EPSILON_OF(a, b) \ |
| 20 EXPECT_TRUE(std::abs(a - b) < std::numeric_limits<float>::epsilon()); | 34 EXPECT_TRUE(std::abs(a - b) < std::numeric_limits<float>::epsilon()); |
| 21 | 35 |
| 22 #define EXPECT_POINT_EQ(point_a, point_b) \ | 36 #define EXPECT_POINT_EQ(point_a, point_b) \ |
| 23 EXPECT_FLOAT_EQ(point_a.x(), point_b.x()); \ | 37 EXPECT_FLOAT_EQ(point_a.x(), point_b.x()); \ |
| 24 EXPECT_FLOAT_EQ(point_a.y(), point_b.y()); \ | 38 EXPECT_FLOAT_EQ(point_a.y(), point_b.y()); \ |
| 25 EXPECT_FLOAT_EQ(point_a.z(), point_b.z()); | 39 EXPECT_FLOAT_EQ(point_a.z(), point_b.z()); |
| 26 | 40 |
| 41 #define EXPECT_NORMAL(poly, n_x, n_y, n_z) \ | |
| 42 EXPECT_FLOAT_WITHIN_EPSILON_OF(poly.normal().x(), n_x); \ | |
| 43 EXPECT_FLOAT_WITHIN_EPSILON_OF(poly.normal().y(), n_y); \ | |
| 44 EXPECT_FLOAT_WITHIN_EPSILON_OF(poly.normal().z(), n_z); | |
| 45 | |
| 27 static void ValidatePoints(const DrawPolygon& polygon, | 46 static void ValidatePoints(const DrawPolygon& polygon, |
| 28 const std::vector<gfx::Point3F>& points) { | 47 const std::vector<gfx::Point3F>& points) { |
| 29 EXPECT_EQ(polygon.points().size(), points.size()); | 48 EXPECT_EQ(polygon.points().size(), points.size()); |
| 30 for (size_t i = 0; i < points.size(); i++) { | 49 for (size_t i = 0; i < points.size(); i++) { |
| 31 EXPECT_POINT_EQ(polygon.points()[i], points[i]); | 50 EXPECT_POINT_EQ(polygon.points()[i], points[i]); |
| 32 } | 51 } |
| 33 } | 52 } |
| 34 | 53 |
| 54 // A simple square in a plane. | |
| 55 TEST(DrawPolygonConstructionTest, NormalNormal) { | |
| 56 std::vector<gfx::Point3F> vertices; | |
| 57 vertices.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); | |
| 58 vertices.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | |
| 59 vertices.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); | |
| 60 vertices.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); | |
|
Ian Vollick
2015/12/05 01:09:58
looks like |vertices| aren't used here?
Peter Mayo
2015/12/07 22:28:02
Correct, this mimics the direct renderer use case.
| |
| 61 | |
| 62 gfx::Transform Identity; | |
| 63 DrawPolygon polygon(NULL, gfx::RectF(10.0f, 10.0f), Identity, 1); | |
| 64 EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); | |
| 65 } | |
|
Ian Vollick
2015/12/05 01:09:58
nit: would be nice to check that putting the verti
Peter Mayo
2015/12/07 22:28:02
Done.
| |
| 66 | |
| 67 // More complicated shapes. | |
| 68 TEST(DrawPolygonConstructionTest, TestNormal) { | |
| 69 std::vector<gfx::Point3F> vertices; | |
| 70 vertices.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); | |
| 71 vertices.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | |
| 72 vertices.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); | |
| 73 vertices.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); | |
| 74 | |
| 75 CREATE_TEST_DRAW_POLYGON(polygon, vertices, 1); | |
| 76 EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); | |
| 77 } | |
| 78 | |
| 79 TEST(DrawPolygonConstructionTest, ClippedNormal) { | |
| 80 std::vector<gfx::Point3F> vertices; | |
| 81 vertices.push_back(gfx::Point3F(0.1f, 10.0f, 0.0f)); | |
| 82 vertices.push_back(gfx::Point3F(0.0f, 9.9f, 0.0f)); | |
| 83 vertices.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); | |
| 84 vertices.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | |
| 85 vertices.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); | |
| 86 vertices.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); | |
| 87 | |
| 88 CREATE_TEST_DRAW_POLYGON(polygon, vertices, 1); | |
| 89 EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); | |
| 90 } | |
| 91 | |
| 92 TEST(DrawPolygonConstructionTest, SlimTriangleNormal) { | |
| 93 std::vector<gfx::Point3F> vertices; | |
| 94 vertices.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | |
| 95 vertices.push_back(gfx::Point3F(5000.0f, 0.0f, 0.0f)); | |
| 96 vertices.push_back(gfx::Point3F(10000.0f, 1.0f, 0.0f)); | |
| 97 | |
| 98 CREATE_TEST_DRAW_POLYGON(polygon, vertices, 2); | |
| 99 EXPECT_NORMAL(polygon, 0.0f, 0.0f, 1.0f); | |
| 100 } | |
| 101 | |
| 102 TEST(DrawPolygonConstructionTest, ManyVertexNormal) { | |
| 103 std::vector<gfx::Point3F> vertices_c; | |
| 104 std::vector<gfx::Point3F> vertices_d; | |
| 105 for (int i = 0; i < 100; i++) { | |
| 106 vertices_c.push_back( | |
| 107 gfx::Point3F(cos(i * M_PI / 50), sin(i * M_PI / 50), 0.0f)); | |
| 108 vertices_d.push_back(gfx::Point3F(cos(i * M_PI / 50) + 99.0f, | |
| 109 sin(i * M_PI / 50) + 99.0f, 100.0f)); | |
| 110 } | |
| 111 CREATE_TEST_DRAW_POLYGON(polygon_c, vertices_c, 3); | |
| 112 EXPECT_NORMAL(polygon_c, 0.0f, 0.0f, 1.0f); | |
| 113 | |
| 114 CREATE_TEST_DRAW_POLYGON(polygon_d, vertices_d, 4); | |
| 115 EXPECT_NORMAL(polygon_c, 0.0f, 0.0f, 1.0f); | |
| 116 } | |
| 117 | |
| 118 // A simple rect being transformed. | |
| 119 TEST(DrawPolygonConstructionTest, DizzyNormal) { | |
| 120 gfx::RectF src(-0.1f, -10.0f, 0.2f, 20.0f); | |
| 121 | |
| 122 gfx::Transform transform_i(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); | |
| 123 DrawPolygon polygon_i(NULL, src, transform_i, 1); | |
| 124 | |
| 125 EXPECT_NORMAL(polygon_i, 0.0f, 0.0f, 1.0f); | |
| 126 | |
| 127 gfx::Transform tranform_a(0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); | |
| 128 DrawPolygon polygon_a(NULL, src, tranform_a, 2); | |
| 129 EXPECT_NORMAL(polygon_a, 0.0f, 0.0f, -1.0f); | |
| 130 | |
| 131 gfx::Transform tranform_b(0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1); | |
| 132 DrawPolygon polygon_b(NULL, src, tranform_b, 3); | |
| 133 EXPECT_NORMAL(polygon_b, -1.0f, 0.0f, 0.0f); | |
| 134 | |
| 135 gfx::Transform tranform_c(1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1); | |
| 136 DrawPolygon polygon_c(NULL, src, tranform_c, 4); | |
| 137 EXPECT_NORMAL(polygon_c, 0.0f, -1.0f, 0.0f); | |
| 138 | |
| 139 gfx::Transform tranform_d(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); | |
| 140 DrawPolygon polygon_d(NULL, src, tranform_d, 5); | |
| 141 EXPECT_NORMAL(polygon_d, 0.0f, 0.0f, -1.0f); | |
| 142 } | |
| 143 | |
| 35 // Two quads are nearly touching but definitely ordered. Second one should | 144 // Two quads are nearly touching but definitely ordered. Second one should |
| 36 // compare in front. | 145 // compare in front. |
| 37 TEST(DrawPolygonSplitTest, NearlyTouchingOrder) { | 146 TEST(DrawPolygonSplitTest, NearlyTouchingOrder) { |
| 38 std::vector<gfx::Point3F> vertices_a; | 147 std::vector<gfx::Point3F> vertices_a; |
| 39 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); | 148 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)); | 149 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)); | 150 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)); | 151 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); |
| 43 std::vector<gfx::Point3F> vertices_b; | 152 std::vector<gfx::Point3F> vertices_b; |
| 44 vertices_b.push_back(gfx::Point3F(0.0f, 10.0f, -1.0f)); | 153 vertices_b.push_back(gfx::Point3F(0.0f, 10.0f, -1.0f)); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 55 | 164 |
| 56 // Two quads are definitely not touching and so no split should occur. | 165 // Two quads are definitely not touching and so no split should occur. |
| 57 TEST(DrawPolygonSplitTest, NotClearlyInFront) { | 166 TEST(DrawPolygonSplitTest, NotClearlyInFront) { |
| 58 std::vector<gfx::Point3F> vertices_a; | 167 std::vector<gfx::Point3F> vertices_a; |
| 59 vertices_a.push_back(gfx::Point3F(87.2f, 1185.0f, 0.9f)); | 168 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)); | 169 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)); | 170 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)); | 171 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], | 172 gfx::Vector3dF normal_a = gfx::CrossProduct(vertices_a[1] - vertices_a[0], |
| 64 vertices_a[1] - vertices_a[2]); | 173 vertices_a[1] - vertices_a[2]); |
| 65 normal_a.Scale(1.0 / normal_a.Length()); | 174 normal_a.Scale(1.0f / normal_a.Length()); |
| 66 | 175 |
| 67 std::vector<gfx::Point3F> vertices_b; | 176 std::vector<gfx::Point3F> vertices_b; |
| 68 vertices_b.push_back(gfx::Point3F(62.1f, 1034.7f, 1.0f)); | 177 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)); | 178 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)); | 179 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)); | 180 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], | 181 gfx::Vector3dF normal_b = gfx::CrossProduct(vertices_b[1] - vertices_b[0], |
| 73 vertices_b[1] - vertices_b[2]); | 182 vertices_b[1] - vertices_b[2]); |
| 74 normal_b.Scale(1.0 / normal_b.Length()); | 183 normal_b.Scale(1.0f / normal_b.Length()); |
| 75 | 184 |
| 76 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, normal_a, 0); | 185 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, normal_a, 0); |
| 77 CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, normal_b, 1); | 186 CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, normal_b, 1); |
| 78 | 187 |
| 79 EXPECT_EQ(BSP_FRONT, DrawPolygon::SideCompare(polygon_b, polygon_a)); | 188 EXPECT_EQ(BSP_FRONT, DrawPolygon::SideCompare(polygon_b, polygon_a)); |
| 80 } | 189 } |
| 81 | 190 |
| 82 // Two quads are definitely not touching and so no split should occur. | 191 // Two quads are definitely not touching and so no split should occur. |
| 83 TEST(DrawPolygonSplitTest, NotTouchingNoSplit) { | 192 TEST(DrawPolygonSplitTest, NotTouchingNoSplit) { |
| 84 std::vector<gfx::Point3F> vertices_a; | 193 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)); | 313 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)); | 314 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)); | 315 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)); | 316 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); |
| 208 | 317 |
| 209 ValidatePoints(*(front_polygon.get()), test_points_a); | 318 ValidatePoints(*(front_polygon.get()), test_points_a); |
| 210 ValidatePoints(*(back_polygon.get()), test_points_b); | 319 ValidatePoints(*(back_polygon.get()), test_points_b); |
| 211 } | 320 } |
| 212 | 321 |
| 213 TEST(DrawPolygonTransformTest, TransformNormal) { | 322 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; | 323 std::vector<gfx::Point3F> vertices_a; |
| 324 vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 1.0f)); | |
| 325 vertices_a.push_back(gfx::Point3F(-1.0f, 0.0f, -1.0f)); | |
| 326 vertices_a.push_back(gfx::Point3F(0.0f, 1.0f, 0.0f)); | |
| 217 CREATE_NEW_DRAW_POLYGON( | 327 CREATE_NEW_DRAW_POLYGON( |
| 218 polygon_a, vertices_a, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 0); | 328 polygon_a, vertices_a, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 0); |
| 329 // Check we believe your little white lie. | |
| 330 EXPECT_NORMAL(polygon_a, 0.707107f, 0.0f, -0.707107f); | |
| 331 | |
| 332 polygon_a.RecomputeNormalForTesting(); | |
| 333 // Check that we recompute it more accurately. | |
| 334 EXPECT_NORMAL(polygon_a, sqrt(2) / 2, 0.0f, -sqrt(2) / 2); | |
| 219 | 335 |
| 220 gfx::Transform transform; | 336 gfx::Transform transform; |
| 221 transform.RotateAboutYAxis(45.0); | 337 transform.RotateAboutYAxis(45.0f); |
| 222 // This would transform the vertices as well, but we are transforming a | 338 // This would transform the vertices as well, but we are transforming a |
| 223 // DrawPolygon with 0 vertices just to make sure our normal transformation | 339 // DrawPolygon with 0 vertices just to make sure our normal transformation |
| 224 // using the inverse tranpose matrix gives us the right result. | 340 // using the inverse tranpose matrix gives us the right result. |
| 225 polygon_a.TransformToScreenSpace(transform); | 341 polygon_a.TransformToScreenSpace(transform); |
| 226 | 342 |
| 227 // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here | 343 // 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 | 344 // because some architectures (e.g., Arm64) employ a fused multiply-add |
| 229 // instruction which causes rounding asymmetry and reduces precision. | 345 // instruction which causes rounding asymmetry and reduces precision. |
| 230 // http://crbug.com/401117. | 346 // http://crbug.com/401117. |
| 231 EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().x(), 0); | 347 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 } | 348 } |
| 235 | 349 |
| 236 } // namespace | 350 } // namespace |
| 237 } // namespace cc | 351 } // namespace cc |
| OLD | NEW |