blob: 3ef6bd163691a1e46b05a88f33a12e7a4d416fe5 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/testing/testing.h"
#include "gtest/gtest.h"
#include "impeller/geometry/path.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/tessellator/tessellator.h"
namespace impeller {
namespace testing {
TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
// Zero points.
{
Tessellator t;
auto path = PathBuilder{}.TakePath(FillType::kPositive);
Tessellator::Result result = t.Tessellate(
path, 1.0f,
[](const float* vertices, size_t vertices_count,
const uint16_t* indices, size_t indices_count) { return true; });
ASSERT_EQ(result, Tessellator::Result::kInputError);
}
// One point.
{
Tessellator t;
auto path = PathBuilder{}.LineTo({0, 0}).TakePath(FillType::kPositive);
Tessellator::Result result = t.Tessellate(
path, 1.0f,
[](const float* vertices, size_t vertices_count,
const uint16_t* indices, size_t indices_count) { return true; });
ASSERT_EQ(result, Tessellator::Result::kSuccess);
}
// Two points.
{
Tessellator t;
auto path =
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kPositive);
Tessellator::Result result = t.Tessellate(
path, 1.0f,
[](const float* vertices, size_t vertices_count,
const uint16_t* indices, size_t indices_count) { return true; });
ASSERT_EQ(result, Tessellator::Result::kSuccess);
}
// Many points.
{
Tessellator t;
PathBuilder builder;
for (int i = 0; i < 1000; i++) {
auto coord = i * 1.0f;
builder.AddLine({coord, coord}, {coord + 1, coord + 1});
}
auto path = builder.TakePath(FillType::kPositive);
Tessellator::Result result = t.Tessellate(
path, 1.0f,
[](const float* vertices, size_t vertices_count,
const uint16_t* indices, size_t indices_count) { return true; });
ASSERT_EQ(result, Tessellator::Result::kSuccess);
}
// Closure fails.
{
Tessellator t;
auto path =
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kPositive);
Tessellator::Result result = t.Tessellate(
path, 1.0f,
[](const float* vertices, size_t vertices_count,
const uint16_t* indices, size_t indices_count) { return false; });
ASSERT_EQ(result, Tessellator::Result::kInputError);
}
// More than 30 contours, non-zero fill mode.
{
Tessellator t;
PathBuilder builder = {};
for (auto i = 0u; i < Tessellator::kMultiContourThreshold + 1; i++) {
builder.AddCircle(Point(i, i), 4);
}
auto path = builder.TakePath(FillType::kNonZero);
bool no_indices = false;
Tessellator::Result result = t.Tessellate(
path, 1.0f,
[&no_indices](const float* vertices, size_t vertices_count,
const uint16_t* indices, size_t indices_count) {
no_indices = indices == nullptr;
return true;
});
ASSERT_TRUE(no_indices);
ASSERT_EQ(result, Tessellator::Result::kSuccess);
}
// More than uint16 points, odd fill mode.
{
Tessellator t;
PathBuilder builder = {};
for (auto i = 0; i < 1000; i++) {
builder.AddCircle(Point(i, i), 4);
}
auto path = builder.TakePath(FillType::kOdd);
bool no_indices = false;
size_t count = 0u;
Tessellator::Result result = t.Tessellate(
path, 1.0f,
[&no_indices, &count](const float* vertices, size_t vertices_count,
const uint16_t* indices, size_t indices_count) {
no_indices = indices == nullptr;
count = vertices_count;
return true;
});
ASSERT_TRUE(no_indices);
ASSERT_TRUE(count >= USHRT_MAX);
ASSERT_EQ(result, Tessellator::Result::kSuccess);
}
}
TEST(TessellatorTest, TessellateConvex) {
{
Tessellator t;
// Sanity check simple rectangle.
auto [pts, indices] = t.TessellateConvex(
PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 10, 10)).TakePath(), 1.0);
std::vector<Point> expected = {
{0, 0}, {10, 0}, {10, 10}, {0, 10}, //
};
std::vector<uint16_t> expected_indices = {0, 1, 2, 0, 2, 3};
ASSERT_EQ(pts, expected);
ASSERT_EQ(indices, expected_indices);
}
{
Tessellator t;
auto [pts, indices] =
t.TessellateConvex(PathBuilder{}
.AddRect(Rect::MakeLTRB(0, 0, 10, 10))
.AddRect(Rect::MakeLTRB(20, 20, 30, 30))
.TakePath(),
1.0);
std::vector<Point> expected = {
{0, 0}, {10, 0}, {10, 10}, {0, 10}, //
{20, 20}, {30, 20}, {30, 30}, {20, 30} //
};
std::vector<uint16_t> expected_indices = {0, 1, 2, 0, 2, 3,
0, 6, 7, 0, 7, 8};
ASSERT_EQ(pts, expected);
ASSERT_EQ(indices, expected_indices);
}
}
} // namespace testing
} // namespace impeller