Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Impeller][WIp] performance improvements for polyline generation. #52078

Closed
wants to merge 6 commits into from
Closed
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
11 changes: 2 additions & 9 deletions impeller/entity/geometry/fill_path_geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,10 @@ GeometryResult FillPathGeometry::GetPositionBuffer(

VertexBuffer vertex_buffer;

auto points = renderer.GetTessellator()->TessellateConvex(
path_, entity.GetTransform().GetMaxBasisLength());

vertex_buffer.vertex_buffer = host_buffer.Emplace(
points.data(), points.size() * sizeof(Point), alignof(Point));
vertex_buffer.index_buffer = {}, vertex_buffer.vertex_count = points.size();
vertex_buffer.index_type = IndexType::kNone;

return GeometryResult{
.type = PrimitiveType::kTriangleStrip,
.vertex_buffer = vertex_buffer,
.vertex_buffer = renderer.GetTessellator()->TessellateConvex2(
path_, host_buffer, entity.GetTransform().GetMaxBasisLength()),
.transform = entity.GetShaderTransform(pass),
.mode = GetResultMode(),
};
Expand Down
126 changes: 65 additions & 61 deletions impeller/entity/geometry/stroke_path_geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -321,35 +321,36 @@ void CreateRoundCap(VertexWriter& vtx_builder,
const Point& offset,
Scalar scale,
bool reverse) {
Point orientation = offset * (reverse ? -1 : 1);
Point forward(offset.y, -offset.x);
Point forward_normal = forward.Normalize();

CubicPathComponent arc;
if (reverse) {
arc = CubicPathComponent(
forward, forward + orientation * PathBuilder::kArcApproximationMagic,
orientation + forward * PathBuilder::kArcApproximationMagic,
orientation);
} else {
arc = CubicPathComponent(
orientation,
orientation + forward * PathBuilder::kArcApproximationMagic,
forward + orientation * PathBuilder::kArcApproximationMagic, forward);
}

Point vtx = position + orientation;
vtx_builder.AppendVertex(vtx);
vtx = position - orientation;
vtx_builder.AppendVertex(vtx);

arc.ToLinearPathComponents(scale, [&vtx_builder, &vtx, forward_normal,
position](const Point& point) {
vtx = position + point;
vtx_builder.AppendVertex(vtx);
vtx = position + (-point).Reflect(forward_normal);
vtx_builder.AppendVertex(vtx);
});
// Point orientation = offset * (reverse ? -1 : 1);
// Point forward(offset.y, -offset.x);
// Point forward_normal = forward.Normalize();

// CubicPathComponent arc;
// if (reverse) {
// arc = CubicPathComponent(
// forward, forward + orientation * PathBuilder::kArcApproximationMagic,
// orientation + forward * PathBuilder::kArcApproximationMagic,
// orientation);
// } else {
// arc = CubicPathComponent(
// orientation,
// orientation + forward * PathBuilder::kArcApproximationMagic,
// forward + orientation * PathBuilder::kArcApproximationMagic,
// forward);
// }

// Point vtx = position + orientation;
// vtx_builder.AppendVertex(vtx);
// vtx = position - orientation;
// vtx_builder.AppendVertex(vtx);

// arc.ToLinearPathComponents(scale, [&vtx_builder, &vtx, forward_normal,
// position](const Point& point) {
// vtx = position + point;
// vtx_builder.AppendVertex(vtx);
// vtx = position + (-point).Reflect(forward_normal);
// vtx_builder.AppendVertex(vtx);
// });
}

template <typename VertexWriter>
Expand Down Expand Up @@ -425,38 +426,41 @@ void CreateRoundJoin(VertexWriter& vtx_builder,
const Point& end_offset,
Scalar miter_limit,
Scalar scale) {
Point start_normal = start_offset.Normalize();
Point end_normal = end_offset.Normalize();

// 0 for no joint (straight line), 1 for max joint (180 degrees).
Scalar alignment = 1 - (start_normal.Dot(end_normal) + 1) / 2;
if (ScalarNearlyEqual(alignment, 0)) {
return;
}

Scalar direction = CreateBevelAndGetDirection(vtx_builder, position,
start_offset, end_offset);

Point middle =
(start_offset + end_offset).Normalize() * start_offset.GetLength();
Point middle_normal = middle.Normalize();

Point middle_handle = middle + Point(-middle.y, middle.x) *
PathBuilder::kArcApproximationMagic *
alignment * direction;
Point start_handle = start_offset + Point(start_offset.y, -start_offset.x) *
PathBuilder::kArcApproximationMagic *
alignment * direction;

VS::PerVertexData vtx;
CubicPathComponent(start_offset, start_handle, middle_handle, middle)
.ToLinearPathComponents(scale, [&vtx_builder, direction, &vtx, position,
middle_normal](const Point& point) {
vtx.position = position + point * direction;
vtx_builder.AppendVertex(vtx.position);
vtx.position = position + (-point * direction).Reflect(middle_normal);
vtx_builder.AppendVertex(vtx.position);
});
// Point start_normal = start_offset.Normalize();
// Point end_normal = end_offset.Normalize();

// // 0 for no joint (straight line), 1 for max joint (180 degrees).
// Scalar alignment = 1 - (start_normal.Dot(end_normal) + 1) / 2;
// if (ScalarNearlyEqual(alignment, 0)) {
// return;
// }

// Scalar direction = CreateBevelAndGetDirection(vtx_builder, position,
// start_offset, end_offset);

// Point middle =
// (start_offset + end_offset).Normalize() * start_offset.GetLength();
// Point middle_normal = middle.Normalize();

// Point middle_handle = middle + Point(-middle.y, middle.x) *
// PathBuilder::kArcApproximationMagic *
// alignment * direction;
// Point start_handle = start_offset + Point(start_offset.y, -start_offset.x)
// *
// PathBuilder::kArcApproximationMagic
// * alignment * direction;

// VS::PerVertexData vtx;
// CubicPathComponent(start_offset, start_handle, middle_handle, middle)
// .ToLinearPathComponents(scale, [&vtx_builder, direction, &vtx,
// position,
// middle_normal](const Point& point) {
// vtx.position = position + point * direction;
// vtx_builder.AppendVertex(vtx.position);
// vtx.position = position + (-point *
// direction).Reflect(middle_normal);
// vtx_builder.AppendVertex(vtx.position);
// });
}

template <typename VertexWriter>
Expand Down
2 changes: 2 additions & 0 deletions impeller/geometry/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ impeller_component("geometry") {
"type_traits.h",
"vector.cc",
"vector.h",
"vertex_writer.h",
"wangs_formula.h",
]

deps = [
Expand Down
98 changes: 89 additions & 9 deletions impeller/geometry/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "flutter/fml/logging.h"
#include "impeller/geometry/path_component.h"
#include "impeller/geometry/point.h"
#include "impeller/geometry/wangs_formula.h"

namespace impeller {

Expand Down Expand Up @@ -288,29 +289,29 @@ Path::Polyline Path::CreatePolyline(
.component_start_index = polyline.points->size() - 1,
.is_curve = false,
});
reinterpret_cast<const LinearPathComponent*>(
&path_points[path_component.index])
->AppendPolylinePoints(*polyline.points);
// reinterpret_cast<const LinearPathComponent*>(
// &path_points[path_component.index])
// ->AppendPolylinePoints(*polyline.points);
previous_path_component_index = component_i;
break;
case ComponentType::kQuadratic:
poly_components.push_back({
.component_start_index = polyline.points->size() - 1,
.is_curve = true,
});
reinterpret_cast<const QuadraticPathComponent*>(
&path_points[path_component.index])
->AppendPolylinePoints(scale, *polyline.points);
// reinterpret_cast<const QuadraticPathComponent*>(
// &path_points[path_component.index])
// ->AppendPolylinePoints(scale, *polyline.points);
previous_path_component_index = component_i;
break;
case ComponentType::kCubic:
poly_components.push_back({
.component_start_index = polyline.points->size() - 1,
.is_curve = true,
});
reinterpret_cast<const CubicPathComponent*>(
&path_points[path_component.index])
->AppendPolylinePoints(scale, *polyline.points);
// reinterpret_cast<const CubicPathComponent*>(
// &path_points[path_component.index])
// ->AppendPolylinePoints(scale, *polyline.points);
previous_path_component_index = component_i;
break;
case ComponentType::kContour:
Expand Down Expand Up @@ -349,4 +350,83 @@ std::optional<Rect> Path::GetTransformedBoundingBox(
return bounds->TransformBounds(transform);
}

std::pair<size_t, size_t> Path::ComputeStorage(Scalar scale) const {
auto& path_components = data_->components;
auto& path_points = data_->points;

size_t count = 0;
size_t contours = 0;
for (size_t component_i = 0; component_i < path_components.size();
component_i++) {
const auto& path_component = path_components[component_i];
switch (path_component.type) {
case ComponentType::kLinear: {
count++;
break;
}
case ComponentType::kQuadratic: {
const QuadraticPathComponent* quad =
reinterpret_cast<const QuadraticPathComponent*>(
&path_points[path_component.index]);
count += quadratic(scale, *quad);
break;
}
case ComponentType::kCubic: {
const CubicPathComponent* cub =
reinterpret_cast<const CubicPathComponent*>(
&path_points[path_component.index]);
count += cubic(scale, *cub);
break;
}
case ComponentType::kContour:
if (component_i > 0 && component_i < path_components.size() - 1) {
contours++;
}
break;
}
}
return std::make_pair(count, count + contours);
}

void Path::WritePolyline(VertexWriter& writer, Scalar scale) const {
auto& path_components = data_->components;
auto& path_points = data_->points;

for (size_t component_i = 0; component_i < path_components.size();
component_i++) {
const auto& path_component = path_components[component_i];
switch (path_component.type) {
case ComponentType::kLinear: {
const LinearPathComponent* linear =
reinterpret_cast<const LinearPathComponent*>(
&path_points[path_component.index]);
writer.Write(linear->p2);
break;
}
case ComponentType::kQuadratic: {
const QuadraticPathComponent* quad =
reinterpret_cast<const QuadraticPathComponent*>(
&path_points[path_component.index]);
quad->ToLinearPathComponents(scale, writer);
break;
}
case ComponentType::kCubic: {
const CubicPathComponent* cubic =
reinterpret_cast<const CubicPathComponent*>(
&path_points[path_component.index]);
cubic->ToLinearPathComponents(scale, writer);
break;
}
case ComponentType::kContour:
if (component_i == path_components.size() - 1) {
// If the last component is a contour, that means it's an empty
// contour, so skip it.
continue;
}
writer.EndContour();
break;
}
}
}

} // namespace impeller
6 changes: 6 additions & 0 deletions impeller/geometry/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <vector>

#include "impeller/geometry/path_component.h"
#include "impeller/geometry/vertex_writer.h"

namespace impeller {

Expand Down Expand Up @@ -137,6 +138,11 @@ class Path {

bool IsEmpty() const;

// vertex count, index count
std::pair<size_t, size_t> ComputeStorage(Scalar scale) const;

void WritePolyline(VertexWriter& writer, Scalar scale) const;

template <class T>
using Applier = std::function<void(size_t index, const T& component)>;
void EnumerateComponents(
Expand Down
Loading