Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller] Remove libtess2 from libflutter. #52357

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -40794,6 +40794,8 @@ ORIGIN: ../../../flutter/impeller/tessellator/c/tessellator.h + ../../../flutter
ORIGIN: ../../../flutter/impeller/tessellator/dart/lib/tessellator.dart + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/tessellator/tessellator.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/tessellator/tessellator.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/tessellator/tessellator_libtess.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/tessellator/tessellator_libtess.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/toolkit/android/choreographer.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/toolkit/android/choreographer.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/toolkit/android/hardware_buffer.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -43676,6 +43678,8 @@ FILE: ../../../flutter/impeller/tessellator/c/tessellator.h
FILE: ../../../flutter/impeller/tessellator/dart/lib/tessellator.dart
FILE: ../../../flutter/impeller/tessellator/tessellator.cc
FILE: ../../../flutter/impeller/tessellator/tessellator.h
FILE: ../../../flutter/impeller/tessellator/tessellator_libtess.cc
FILE: ../../../flutter/impeller/tessellator/tessellator_libtess.h
FILE: ../../../flutter/impeller/toolkit/android/choreographer.cc
FILE: ../../../flutter/impeller/toolkit/android/choreographer.h
FILE: ../../../flutter/impeller/toolkit/android/hardware_buffer.cc
Expand Down
2 changes: 1 addition & 1 deletion impeller/geometry/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ executable("geometry_benchmarks") {
deps = [
":geometry",
"../entity",
"../tessellator",
"../tessellator:tessellator_libtess",
"//flutter/benchmarking",
]
}
3 changes: 2 additions & 1 deletion impeller/geometry/geometry_benchmarks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "impeller/geometry/path.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/tessellator/tessellator.h"
#include "impeller/tessellator/tessellator_libtess.h"

namespace impeller {

Expand Down Expand Up @@ -37,7 +38,7 @@ Path CreateQuadratic(bool closed);
Path CreateRRect();
} // namespace

static Tessellator tess;
static TessellatorLibtess tess;

template <class... Args>
static void BM_Polyline(benchmark::State& state, Args&&... args) {
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ impeller_component("renderer_unittests") {
":renderer",
"../fixtures",
"../playground:playground_test",
"../tessellator:tessellator_libtess",
"//flutter/testing:testing_lib",
]

Expand Down
7 changes: 2 additions & 5 deletions impeller/renderer/renderer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,18 @@
#include "impeller/fixtures/sepia.frag.h"
#include "impeller/fixtures/sepia.vert.h"
#include "impeller/fixtures/swizzle.frag.h"
#include "impeller/fixtures/test_texture.frag.h"
#include "impeller/fixtures/test_texture.vert.h"
#include "impeller/fixtures/texture.frag.h"
#include "impeller/fixtures/texture.vert.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/playground/playground_test.h"
#include "impeller/renderer/command.h"
#include "impeller/renderer/command_buffer.h"
#include "impeller/renderer/pipeline_builder.h"
#include "impeller/renderer/pipeline_library.h"
#include "impeller/renderer/render_pass.h"
#include "impeller/renderer/render_target.h"
#include "impeller/renderer/renderer.h"
#include "impeller/renderer/vertex_buffer_builder.h"
#include "impeller/tessellator/tessellator.h"
#include "impeller/tessellator/tessellator_libtess.h"
#include "third_party/imgui/imgui.h"

// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
Expand Down Expand Up @@ -394,7 +391,7 @@ TEST_P(RendererTest, CanRenderInstanced) {
VertexBufferBuilder<VS::PerVertexData> builder;

ASSERT_EQ(Tessellator::Result::kSuccess,
Tessellator{}.Tessellate(
TessellatorLibtess{}.Tessellate(
PathBuilder{}
.AddRect(Rect::MakeXYWH(10, 10, 100, 100))
.TakePath(FillType::kOdd),
Expand Down
21 changes: 18 additions & 3 deletions impeller/tessellator/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ impeller_component("tessellator") {
deps = [
"../core",
"//flutter/fml",
]
}

impeller_component("tessellator_libtess") {
sources = [
"tessellator_libtess.cc",
"tessellator_libtess.h",
]

public_deps = [ "../geometry" ]

deps = [
":tessellator",
"../core",
"//flutter/fml",
"//third_party/libtess2",
]
}
Expand All @@ -30,11 +45,11 @@ impeller_component("tessellator_shared") {
sources = [
"c/tessellator.cc",
"c/tessellator.h",
"tessellator.cc",
"tessellator.h",
]

deps = [
":tessellator",
":tessellator_libtess",
"../core",
"../geometry",
"//flutter/fml",
Expand All @@ -50,7 +65,7 @@ impeller_component("tessellator_unittests") {
testonly = true
sources = [ "tessellator_unittests.cc" ]
deps = [
":tessellator",
":tessellator_libtess",
"../geometry:geometry_asserts",
"//flutter/testing",
]
Expand Down
4 changes: 3 additions & 1 deletion impeller/tessellator/c/tessellator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include <vector>

#include "impeller/tessellator/tessellator_libtess.h"

namespace impeller {
PathBuilder* CreatePathBuilder() {
return new PathBuilder();
Expand Down Expand Up @@ -42,7 +44,7 @@ struct Vertices* Tessellate(PathBuilder* builder,
Scalar tolerance) {
auto path = builder->CopyPath(static_cast<FillType>(fill_type));
std::vector<float> points;
if (Tessellator{}.Tessellate(
if (TessellatorLibtess{}.Tessellate(
path, tolerance,
[&points](const float* vertices, size_t vertices_count,
const uint16_t* indices, size_t indices_count) {
Expand Down
1 change: 0 additions & 1 deletion impeller/tessellator/c/tessellator.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <cstdint>

#include "impeller/geometry/path_builder.h"
#include "impeller/tessellator/tessellator.h"

#ifdef _WIN32
#define IMPELLER_API __declspec(dllexport)
Expand Down
159 changes: 1 addition & 158 deletions impeller/tessellator/tessellator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,166 +4,15 @@

#include "impeller/tessellator/tessellator.h"

#include "third_party/libtess2/Include/tesselator.h"

namespace impeller {

static void* HeapAlloc(void* userData, unsigned int size) {
return malloc(size);
}

static void* HeapRealloc(void* userData, void* ptr, unsigned int size) {
return realloc(ptr, size);
}

static void HeapFree(void* userData, void* ptr) {
free(ptr);
}

// Note: these units are "number of entities" for bucket size and not in KB.
static const TESSalloc kAlloc = {
HeapAlloc, HeapRealloc, HeapFree, 0, /* =userData */
16, /* =meshEdgeBucketSize */
16, /* =meshVertexBucketSize */
16, /* =meshFaceBucketSize */
16, /* =dictNodeBucketSize */
16, /* =regionBucketSize */
0 /* =extraVertices */
};

Tessellator::Tessellator()
: point_buffer_(std::make_unique<std::vector<Point>>()),
c_tessellator_(nullptr, &DestroyTessellator) {
: point_buffer_(std::make_unique<std::vector<Point>>()) {
point_buffer_->reserve(2048);
TESSalloc alloc = kAlloc;
{
// libTess2 copies the TESSalloc despite the non-const argument.
CTessellator tessellator(::tessNewTess(&alloc), &DestroyTessellator);
c_tessellator_ = std::move(tessellator);
}
}

Tessellator::~Tessellator() = default;

static int ToTessWindingRule(FillType fill_type) {
switch (fill_type) {
case FillType::kOdd:
return TESS_WINDING_ODD;
case FillType::kNonZero:
return TESS_WINDING_NONZERO;
}
return TESS_WINDING_ODD;
}

Tessellator::Result Tessellator::Tessellate(const Path& path,
Scalar tolerance,
const BuilderCallback& callback) {
if (!callback) {
return Result::kInputError;
}

point_buffer_->clear();
auto polyline =
path.CreatePolyline(tolerance, std::move(point_buffer_),
[this](Path::Polyline::PointBufferPtr point_buffer) {
point_buffer_ = std::move(point_buffer);
});

auto fill_type = path.GetFillType();

if (polyline.points->empty()) {
return Result::kInputError;
}

auto tessellator = c_tessellator_.get();
if (!tessellator) {
return Result::kTessellationError;
}

constexpr int kVertexSize = 2;
constexpr int kPolygonSize = 3;

//----------------------------------------------------------------------------
/// Feed contour information to the tessellator.
///
static_assert(sizeof(Point) == 2 * sizeof(float));
for (size_t contour_i = 0; contour_i < polyline.contours.size();
contour_i++) {
size_t start_point_index, end_point_index;
std::tie(start_point_index, end_point_index) =
polyline.GetContourPointBounds(contour_i);

::tessAddContour(tessellator, // the C tessellator
kVertexSize, //
polyline.points->data() + start_point_index, //
sizeof(Point), //
end_point_index - start_point_index //
);
}

//----------------------------------------------------------------------------
/// Let's tessellate.
///
auto result = ::tessTesselate(tessellator, // tessellator
ToTessWindingRule(fill_type), // winding
TESS_POLYGONS, // element type
kPolygonSize, // polygon size
kVertexSize, // vertex size
nullptr // normal (null is automatic)
);

if (result != 1) {
return Result::kTessellationError;
}

int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;

// We default to using a 16bit index buffer, but in cases where we generate
// more tessellated data than this can contain we need to fall back to
// dropping the index buffer entirely. Instead code could instead switch to
// a uint32 index buffer, but this is done for simplicity with the other
// fast path above.
if (element_item_count < USHRT_MAX) {
int vertex_item_count = tessGetVertexCount(tessellator);
auto vertices = tessGetVertices(tessellator);
auto elements = tessGetElements(tessellator);

// libtess uses an int index internally due to usage of -1 as a sentinel
// value.
std::vector<uint16_t> indices(element_item_count);
for (int i = 0; i < element_item_count; i++) {
indices[i] = static_cast<uint16_t>(elements[i]);
}
if (!callback(vertices, vertex_item_count, indices.data(),
element_item_count)) {
return Result::kInputError;
}
} else {
std::vector<Point> points;
std::vector<float> data;

int vertex_item_count = tessGetVertexCount(tessellator) * kVertexSize;
auto vertices = tessGetVertices(tessellator);
points.reserve(vertex_item_count);
for (int i = 0; i < vertex_item_count; i += 2) {
points.emplace_back(vertices[i], vertices[i + 1]);
}

int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
auto elements = tessGetElements(tessellator);
data.reserve(element_item_count);
for (int i = 0; i < element_item_count; i++) {
data.emplace_back(points[elements[i]].x);
data.emplace_back(points[elements[i]].y);
}
if (!callback(data.data(), element_item_count, nullptr, 0u)) {
return Result::kInputError;
}
}

return Result::kSuccess;
}

Path::Polyline Tessellator::CreateTempPolyline(const Path& path,
Scalar tolerance) {
FML_DCHECK(point_buffer_);
Expand Down Expand Up @@ -239,12 +88,6 @@ std::vector<Point> Tessellator::TessellateConvex(const Path& path,
return output;
}

void DestroyTessellator(TESStesselator* tessellator) {
if (tessellator != nullptr) {
::tessDeleteTess(tessellator);
}
}

static constexpr int kPrecomputedDivisionCount = 1024;
static int kPrecomputedDivisions[kPrecomputedDivisionCount] = {
// clang-format off
Expand Down
Loading