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

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: Moved section and rebased again 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') | third_party/WebKit/LayoutTests/TestExpectations » ('j') | 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 #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
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
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
OLDNEW
« no previous file with comments | « cc/quads/draw_polygon.cc ('k') | third_party/WebKit/LayoutTests/TestExpectations » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698