Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Side by Side Diff: cc/quads/draw_polygon_unittest.cc

Issue 1497153002: Replace inverse transform with Cross-product computation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase + more windows Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/quads/draw_polygon.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « cc/quads/draw_polygon.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698