Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / cc / quads / draw_polygon_unittest.cc
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
3 // found in the LICENSE file.
4
5 #include <limits>
6 #include <vector>
7
8 #include "cc/output/bsp_compare_result.h"
9 #include "cc/quads/draw_polygon.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/gfx/transform.h"
12
13 namespace cc {
14 namespace {
15
16 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \
17   DrawPolygon name(NULL, points_vector, normal, polygon_id)
18
19 #define EXPECT_FLOAT_WITHIN_EPSILON_OF(a, b) \
20   EXPECT_TRUE(std::abs(a - b) < std::numeric_limits<float>::epsilon());
21
22 #define EXPECT_POINT_EQ(point_a, point_b)    \
23   EXPECT_FLOAT_EQ(point_a.x(), point_b.x()); \
24   EXPECT_FLOAT_EQ(point_a.y(), point_b.y()); \
25   EXPECT_FLOAT_EQ(point_a.z(), point_b.z());
26
27 static void ValidatePoints(const DrawPolygon& polygon,
28                            const std::vector<gfx::Point3F>& points) {
29   EXPECT_EQ(polygon.points().size(), points.size());
30   for (size_t i = 0; i < points.size(); i++) {
31     EXPECT_POINT_EQ(polygon.points()[i], points[i]);
32   }
33 }
34
35 // Two quads are definitely not touching and so no split should occur.
36 TEST(DrawPolygonSplitTest, NotTouchingNoSplit) {
37   std::vector<gfx::Point3F> vertices_a;
38   vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
39   vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
40   vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
41   vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
42   std::vector<gfx::Point3F> vertices_b;
43   vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f));
44   vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f));
45   vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f));
46   vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f));
47
48   CREATE_NEW_DRAW_POLYGON(
49       polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
50   CREATE_NEW_DRAW_POLYGON(
51       polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1);
52
53   EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_FRONT);
54 }
55
56 // One quad is resting against another, but doesn't cross its plane so no split
57 // should occur.
58 TEST(DrawPolygonSplitTest, BarelyTouchingNoSplit) {
59   std::vector<gfx::Point3F> vertices_a;
60   vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
61   vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
62   vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
63   vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
64   std::vector<gfx::Point3F> vertices_b;
65   vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f));
66   vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f));
67   vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f));
68   vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f));
69
70   CREATE_NEW_DRAW_POLYGON(
71       polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
72   CREATE_NEW_DRAW_POLYGON(
73       polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1);
74
75   EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_BACK);
76 }
77
78 // One quad intersects another and becomes two pieces.
79 TEST(DrawPolygonSplitTest, BasicSplit) {
80   std::vector<gfx::Point3F> vertices_a;
81   vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
82   vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
83   vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
84   vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
85   std::vector<gfx::Point3F> vertices_b;
86   vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f));
87   vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f));
88   vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f));
89   vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f));
90
91   CREATE_NEW_DRAW_POLYGON(
92       polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
93   CREATE_NEW_DRAW_POLYGON(
94       polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1);
95
96   EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_SPLIT);
97
98   scoped_ptr<DrawPolygon> front_polygon;
99   scoped_ptr<DrawPolygon> back_polygon;
100   polygon_b.Split(polygon_a, &front_polygon, &back_polygon);
101   EXPECT_EQ(DrawPolygon::SideCompare(*front_polygon, polygon_a), BSP_FRONT);
102   EXPECT_EQ(DrawPolygon::SideCompare(*back_polygon, polygon_a), BSP_BACK);
103
104   std::vector<gfx::Point3F> test_points_a;
105   test_points_a.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f));
106   test_points_a.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f));
107   test_points_a.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f));
108   test_points_a.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f));
109   std::vector<gfx::Point3F> test_points_b;
110   test_points_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f));
111   test_points_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f));
112   test_points_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f));
113   test_points_b.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f));
114   ValidatePoints(*(front_polygon.get()), test_points_a);
115   ValidatePoints(*(back_polygon.get()), test_points_b);
116
117   EXPECT_EQ(front_polygon->points().size(), 4u);
118   EXPECT_EQ(back_polygon->points().size(), 4u);
119 }
120
121 // In this test we cut the corner of a quad so that it creates a triangle and
122 // a pentagon as a result.
123 TEST(DrawPolygonSplitTest, AngledSplit) {
124   std::vector<gfx::Point3F> vertices_a;
125   vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
126   vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
127   vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f));
128   vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
129   std::vector<gfx::Point3F> vertices_b;
130   vertices_b.push_back(gfx::Point3F(2.0f, 5.0f, 1.0f));
131   vertices_b.push_back(gfx::Point3F(2.0f, -5.0f, 1.0f));
132   vertices_b.push_back(gfx::Point3F(-1.0f, -5.0f, -2.0f));
133   vertices_b.push_back(gfx::Point3F(-1.0f, 5.0f, -2.0f));
134
135   CREATE_NEW_DRAW_POLYGON(
136       polygon_a, vertices_a, gfx::Vector3dF(0.0f, 1.0f, 0.0f), 0);
137   CREATE_NEW_DRAW_POLYGON(
138       polygon_b, vertices_b, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 1);
139
140   EXPECT_EQ(DrawPolygon::SideCompare(polygon_a, polygon_b), BSP_SPLIT);
141
142   scoped_ptr<DrawPolygon> front_polygon;
143   scoped_ptr<DrawPolygon> back_polygon;
144   polygon_a.Split(polygon_b, &front_polygon, &back_polygon);
145   EXPECT_EQ(DrawPolygon::SideCompare(*front_polygon, polygon_b), BSP_FRONT);
146   EXPECT_EQ(DrawPolygon::SideCompare(*back_polygon, polygon_b), BSP_BACK);
147
148   EXPECT_EQ(front_polygon->points().size(), 3u);
149   EXPECT_EQ(back_polygon->points().size(), 5u);
150
151   std::vector<gfx::Point3F> test_points_a;
152   test_points_a.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f));
153   test_points_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
154   test_points_a.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f));
155   std::vector<gfx::Point3F> test_points_b;
156   test_points_b.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f));
157   test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
158   test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
159   test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f));
160   test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f));
161
162   ValidatePoints(*(front_polygon.get()), test_points_a);
163   ValidatePoints(*(back_polygon.get()), test_points_b);
164 }
165
166 TEST(DrawPolygonTransformTest, TransformNormal) {
167   // We give this polygon no actual vertices because we're not interested
168   // in actually transforming any points, just the normal.
169   std::vector<gfx::Point3F> vertices_a;
170   CREATE_NEW_DRAW_POLYGON(
171       polygon_a, vertices_a, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 0);
172
173   gfx::Transform transform;
174   transform.RotateAboutYAxis(45.0);
175   // This would transform the vertices as well, but we are transforming a
176   // DrawPolygon with 0 vertices just to make sure our normal transformation
177   // using the inverse tranpose matrix gives us the right result.
178   polygon_a.TransformToScreenSpace(transform);
179
180   // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here
181   // because some architectures (e.g., Arm64) employ a fused multiply-add
182   // instruction which causes rounding asymmetry and reduces precision.
183   // http://crbug.com/401117.
184   EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().x(), 0);
185   EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().y(), 0);
186   EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().z(), -1);
187 }
188
189 }  // namespace
190 }  // namespace cc