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

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

Issue 2408203005: Add tests where we split near an edge. (Closed)
Patch Set: rebased Created 4 years, 2 months 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. 5 // We would like to use M_PI on windows too.
6 #ifdef _WIN32 6 #ifdef _WIN32
7 #define _USE_MATH_DEFINES 7 #define _USE_MATH_DEFINES
8 #endif 8 #endif
9 9
10 #include <stddef.h> 10 #include <stddef.h>
11 11
12 #include <limits> 12 #include <limits>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "cc/output/bsp_compare_result.h" 16 #include "cc/output/bsp_compare_result.h"
17 #include "cc/quads/draw_polygon.h" 17 #include "cc/quads/draw_polygon.h"
18 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/gfx/transform.h" 19 #include "ui/gfx/transform.h"
20 20
21 namespace cc { 21 namespace cc {
22 22
23 #if !defined(OS_WIN) 23 #if !defined(OS_WIN)
24 void DrawPolygon::RecomputeNormalForTesting() { 24 void DrawPolygon::RecomputeNormalForTesting() {
25 ConstructNormal(); 25 ConstructNormal();
26 } 26 }
27 #endif 27 #endif
28 28
29 static int sign(float v) {
30 static const float epsilon = 0.00001f;
31
32 if (v > epsilon)
33 return 1;
34 if (v < -epsilon)
35 return -1;
36 return 0;
37 }
38
39 bool IsPlanarForTesting(const DrawPolygon& p) {
40 static const float epsilon = 0.00001f;
41 for (size_t i = 1; i < p.points_.size(); i++) {
42 if (gfx::DotProduct(p.points_[i] - p.points_[0], p.normal_) > epsilon)
43 return false;
44 }
45 return true;
46 }
47
48 bool IsConvexForTesting(const DrawPolygon& p) {
49 if (p.points_.size() < 3)
50 return true;
51
52 gfx::Vector3dF prev =
53 p.points_[p.points_.size() - 1] - p.points_[p.points_.size() - 2];
54 gfx::Vector3dF next = p.points_[0] - p.points_[p.points_.size() - 1];
55 int ccw = sign(gfx::DotProduct(CrossProduct(prev, next), p.normal_));
56 for (size_t i = 1; i < p.points_.size(); i++) {
57 prev = next;
58 next = p.points_[i] - p.points_[i - 1];
59 int next_sign = sign(gfx::DotProduct(CrossProduct(prev, next), p.normal_));
60 if (ccw == 0)
61 ccw = next_sign;
62 if (next_sign != 0 && next_sign != ccw)
63 return false;
64 }
65 return true;
66 }
67
29 namespace { 68 namespace {
30 69
31 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \ 70 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \
32 DrawPolygon name(NULL, points_vector, normal, polygon_id) 71 DrawPolygon name(NULL, points_vector, normal, polygon_id)
33 72
34 #define CREATE_NEW_DRAW_POLYGON_PTR(name, points_vector, normal, polygon_id) \ 73 #define CREATE_NEW_DRAW_POLYGON_PTR(name, points_vector, normal, polygon_id) \
35 std::unique_ptr<DrawPolygon> name(base::MakeUnique<DrawPolygon>( \ 74 std::unique_ptr<DrawPolygon> name(base::MakeUnique<DrawPolygon>( \
36 nullptr, points_vector, normal, polygon_id)) 75 nullptr, points_vector, normal, polygon_id))
37 76
38 #define CREATE_TEST_DRAW_FORWARD_POLYGON(name, points_vector, id) \ 77 #define CREATE_TEST_DRAW_FORWARD_POLYGON(name, points_vector, id) \
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f)); 349 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f));
311 350
312 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 351 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a,
313 gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); 352 gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
314 CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, 353 CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b,
315 gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); 354 gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1);
316 355
317 EXPECT_EQ(BSP_BACK, SideCompare(polygon_b, polygon_a)); 356 EXPECT_EQ(BSP_BACK, SideCompare(polygon_b, polygon_a));
318 } 357 }
319 358
359 // One quad intersects a pent with an occluded side.
360 TEST(DrawPolygonSplitTest, SlimClip) {
361 std::vector<gfx::Point3F> vertices_a;
362 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
363 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
364 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
365 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
366 std::vector<gfx::Point3F> vertices_b;
367 vertices_b.push_back(gfx::Point3F(9.0f, 9.0f, 5.000f));
368 vertices_b.push_back(gfx::Point3F(1.0f, 1.0f, 0.001f));
369 vertices_b.push_back(gfx::Point3F(1.0f, 1.0f, 0.000f));
370 vertices_b.push_back(gfx::Point3F(1.002f, 1.002f, -0.005f));
371 vertices_b.push_back(gfx::Point3F(9.0f, 9.0f, -4.000f));
372
373 CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a,
374 gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
375 CREATE_NEW_DRAW_POLYGON_PTR(
376 polygon_b, vertices_b,
377 gfx::Vector3dF(sqrt(2) / 2, -sqrt(2) / 2, 0.000000), 1);
378
379 // These are well formed, convex polygons.
380 EXPECT_TRUE(IsPlanarForTesting(*(polygon_a.get())));
381 EXPECT_TRUE(IsConvexForTesting(*(polygon_a.get())));
382 EXPECT_TRUE(IsPlanarForTesting(*(polygon_b.get())));
383 EXPECT_TRUE(IsConvexForTesting(*(polygon_b.get())));
384
385 std::unique_ptr<DrawPolygon> front_polygon;
386 std::unique_ptr<DrawPolygon> back_polygon;
387 bool is_coplanar;
388
389 polygon_a->SplitPolygon(std::move(polygon_b), &front_polygon, &back_polygon,
390 &is_coplanar);
391
392 EXPECT_FALSE(is_coplanar);
393 EXPECT_TRUE(front_polygon != nullptr);
394 EXPECT_TRUE(back_polygon != nullptr);
395 }
396
320 // One quad intersects another and becomes two pieces. 397 // One quad intersects another and becomes two pieces.
321 TEST(DrawPolygonSplitTest, BasicSplit) { 398 TEST(DrawPolygonSplitTest, BasicSplit) {
322 std::vector<gfx::Point3F> vertices_a; 399 std::vector<gfx::Point3F> vertices_a;
323 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); 400 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
324 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); 401 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
325 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); 402 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
326 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); 403 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
327 std::vector<gfx::Point3F> vertices_b; 404 std::vector<gfx::Point3F> vertices_b;
328 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f)); 405 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f));
329 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f)); 406 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f));
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 test_points_b.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f)); 476 test_points_b.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f));
400 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); 477 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
401 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); 478 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
402 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); 479 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f));
403 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); 480 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f));
404 481
405 ValidatePointsWithinDeltaOf(*(front_polygon.get()), test_points_a, 1e-6f); 482 ValidatePointsWithinDeltaOf(*(front_polygon.get()), test_points_a, 1e-6f);
406 ValidatePointsWithinDeltaOf(*(back_polygon.get()), test_points_b, 1e-6f); 483 ValidatePointsWithinDeltaOf(*(back_polygon.get()), test_points_b, 1e-6f);
407 } 484 }
408 485
486 // In this test we cut the corner of a quad so that it creates a triangle and
487 // a pentagon as a result, and then cut the pentagon.
488 TEST(DrawPolygonSplitTest, DoubleSplit) {
489 std::vector<gfx::Point3F> vertices_a;
490 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
491 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
492 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f));
493 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
494 std::vector<gfx::Point3F> vertices_b;
495 vertices_b.push_back(gfx::Point3F(2.0f, 5.0f, 1.0f));
496 vertices_b.push_back(gfx::Point3F(2.0f, -5.0f, 1.0f));
497 vertices_b.push_back(gfx::Point3F(-1.0f, -5.0f, -2.0f));
498 vertices_b.push_back(gfx::Point3F(-1.0f, 5.0f, -2.0f));
499
500 CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a,
501 gfx::Vector3dF(0.0f, 1.0f, 0.0f), 0);
502 CREATE_NEW_DRAW_POLYGON_PTR(polygon_b, vertices_b,
503 gfx::Vector3dF(sqrt(2) / 2, 0.0f, -sqrt(2) / 2),
504 1);
505
506 std::unique_ptr<DrawPolygon> front_polygon;
507 std::unique_ptr<DrawPolygon> back_polygon;
508 bool is_coplanar;
509
510 polygon_b->SplitPolygon(std::move(polygon_a), &front_polygon, &back_polygon,
511 &is_coplanar);
512 EXPECT_FALSE(is_coplanar);
513 EXPECT_TRUE(front_polygon != nullptr);
514 EXPECT_TRUE(back_polygon != nullptr);
515
516 EXPECT_EQ(3u, front_polygon->points().size());
517 EXPECT_EQ(5u, back_polygon->points().size());
518
519 std::vector<gfx::Point3F> vertices_c;
520 vertices_c.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
521 vertices_c.push_back(gfx::Point3F(1.0f, -0.05f, 0.0f));
522 vertices_c.push_back(gfx::Point3F(10.0f, 0.05f, 9.0f));
523
524 CREATE_NEW_DRAW_POLYGON_PTR(polygon_c, vertices_c,
525 gfx::Vector3dF(0.0055f, -0.999f, 0.0055f), 0);
526
527 std::unique_ptr<DrawPolygon> second_front_polygon;
528 std::unique_ptr<DrawPolygon> second_back_polygon;
529
530 polygon_c->SplitPolygon(std::move(back_polygon), &second_front_polygon,
531 &second_back_polygon, &is_coplanar);
532 EXPECT_FALSE(is_coplanar);
533 EXPECT_TRUE(second_front_polygon != nullptr);
534 EXPECT_TRUE(second_back_polygon != nullptr);
535
536 EXPECT_EQ(3u, second_front_polygon->points().size());
537 EXPECT_EQ(3u, second_back_polygon->points().size());
538 }
539
409 TEST(DrawPolygonTransformTest, TransformNormal) { 540 TEST(DrawPolygonTransformTest, TransformNormal) {
410 std::vector<gfx::Point3F> vertices_a; 541 std::vector<gfx::Point3F> vertices_a;
411 vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 1.0f)); 542 vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 1.0f));
412 vertices_a.push_back(gfx::Point3F(-1.0f, 0.0f, -1.0f)); 543 vertices_a.push_back(gfx::Point3F(-1.0f, 0.0f, -1.0f));
413 vertices_a.push_back(gfx::Point3F(0.0f, 1.0f, 0.0f)); 544 vertices_a.push_back(gfx::Point3F(0.0f, 1.0f, 0.0f));
414 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 545 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a,
415 gfx::Vector3dF(sqrt(2) / 2, 0.0f, -sqrt(2) / 2), 0); 546 gfx::Vector3dF(sqrt(2) / 2, 0.0f, -sqrt(2) / 2), 0);
416 EXPECT_NORMAL(polygon_a, sqrt(2) / 2, 0.0f, -sqrt(2) / 2); 547 EXPECT_NORMAL(polygon_a, sqrt(2) / 2, 0.0f, -sqrt(2) / 2);
417 548
418 gfx::Transform transform; 549 gfx::Transform transform;
419 transform.RotateAboutYAxis(45.0f); 550 transform.RotateAboutYAxis(45.0f);
420 // This would transform the vertices as well, but we are transforming a 551 // This would transform the vertices as well, but we are transforming a
421 // DrawPolygon with 0 vertices just to make sure our normal transformation 552 // DrawPolygon with 0 vertices just to make sure our normal transformation
422 // using the inverse tranpose matrix gives us the right result. 553 // using the inverse tranpose matrix gives us the right result.
423 polygon_a.TransformToScreenSpace(transform); 554 polygon_a.TransformToScreenSpace(transform);
424 555
425 // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here 556 // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here
426 // because some architectures (e.g., Arm64) employ a fused multiply-add 557 // because some architectures (e.g., Arm64) employ a fused multiply-add
427 // instruction which causes rounding asymmetry and reduces precision. 558 // instruction which causes rounding asymmetry and reduces precision.
428 // http://crbug.com/401117. 559 // http://crbug.com/401117.
429 EXPECT_NORMAL(polygon_a, 0.0f, 0.0f, -1.0f); 560 EXPECT_NORMAL(polygon_a, 0.0f, 0.0f, -1.0f);
430 } 561 }
431 562
432 } // namespace 563 } // namespace
433 } // namespace cc 564 } // 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