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

Commit 769d4af

Browse files
committed
move to direct HostBuffer emplacement of tessellation results
1 parent 39f8a54 commit 769d4af

File tree

4 files changed

+135
-67
lines changed

4 files changed

+135
-67
lines changed

impeller/entity/geometry/circle_tessellator.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace impeller {
1010

11-
std::vector<Trig> CircleTessellator::trigs_[MAX_DIVISIONS_ + 1];
11+
std::vector<Trig> CircleTessellator::trigs_[kMaxDivisions + 1];
1212

1313
size_t CircleTessellator::ComputeQuadrantDivisions(Scalar pixel_radius) {
1414
// Note: these values are approximated based on the values returned from
@@ -26,16 +26,17 @@ size_t CircleTessellator::ComputeQuadrantDivisions(Scalar pixel_radius) {
2626
return 9;
2727
}
2828
pixel_radius /= 4;
29-
if (pixel_radius > (MAX_DIVISIONS_ - 1)) {
30-
return MAX_DIVISIONS_;
29+
if (pixel_radius > (kMaxDivisions - 1)) {
30+
return kMaxDivisions;
3131
}
32-
return static_cast<int>(ceil(pixel_radius));
32+
return static_cast<size_t>(ceil(pixel_radius));
3333
}
3434

3535
const std::vector<Trig>& CircleTessellator::GetTrigForDivisions(
3636
size_t divisions) {
37-
FML_DCHECK(divisions > 0 && divisions <= MAX_DIVISIONS_);
37+
FML_DCHECK(divisions > 0 && divisions <= kMaxDivisions);
3838
std::vector<Trig>& trigs = trigs_[divisions];
39+
trigs.reserve(divisions + 1);
3940

4041
if (trigs.empty()) {
4142
double angle_scale = kPiOver2 / divisions;

impeller/entity/geometry/circle_tessellator.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ namespace impeller {
1616
/// @brief A structure to store the sine and cosine of an angle.
1717
struct Trig {
1818
/// Construct a Trig object from a given angle in radians.
19-
Trig(Radians r) : cos(std::cos(r.radians)), sin(std::sin(r.radians)) {}
19+
explicit Trig(Radians r)
20+
: cos(std::cos(r.radians)), sin(std::sin(r.radians)) {}
2021

2122
/// Construct a Trig object from the given cosine and sine values.
2223
Trig(double cos, double sin) : cos(cos), sin(sin) {}
@@ -128,9 +129,9 @@ class CircleTessellator {
128129
/// @return The vector of (divisions + 1) trig values.
129130
static const std::vector<Trig>& GetTrigForDivisions(size_t divisions);
130131

131-
static constexpr int MAX_DIVISIONS_ = 35;
132+
static constexpr int kMaxDivisions = 35;
132133

133-
static std::vector<Trig> trigs_[MAX_DIVISIONS_ + 1];
134+
static std::vector<Trig> trigs_[kMaxDivisions + 1];
134135
};
135136

136137
} // namespace impeller

impeller/entity/geometry/ellipse_geometry.cc

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,33 @@ GeometryResult EllipseGeometry::GetPositionBuffer(
1818
const Entity& entity,
1919
RenderPass& pass) const {
2020
auto& host_buffer = pass.GetTransientsBuffer();
21+
using VT = SolidFillVertexShader::PerVertexData;
2122

22-
VertexBufferBuilder<SolidFillVertexShader::PerVertexData> vtx_builder;
23-
23+
Scalar radius = radius_;
24+
const Point& center = center_;
2425
CircleTessellator tessellator(entity.GetTransform(), radius_);
25-
vtx_builder.Reserve(tessellator.GetCircleVertexCount());
26-
tessellator.GenerateCircleTriangleStrip(
27-
[&vtx_builder](const Point& p) { //
28-
vtx_builder.AppendVertex({.position = p});
29-
},
30-
center_, radius_);
26+
size_t count = tessellator.GetCircleVertexCount();
27+
auto vertex_buffer =
28+
host_buffer.Emplace(count * sizeof(VT), alignof(VT),
29+
[&tessellator, &center, radius](uint8_t* buffer) {
30+
auto vertices = reinterpret_cast<VT*>(buffer);
31+
tessellator.GenerateCircleTriangleStrip(
32+
[&vertices](const Point& p) { //
33+
*vertices++ = {
34+
.position = p,
35+
};
36+
},
37+
center, radius);
38+
});
3139

3240
return GeometryResult{
3341
.type = PrimitiveType::kTriangleStrip,
34-
.vertex_buffer = vtx_builder.CreateVertexBuffer(host_buffer),
42+
.vertex_buffer =
43+
{
44+
.vertex_buffer = vertex_buffer,
45+
.vertex_count = count,
46+
.index_type = IndexType::kNone,
47+
},
3548
.transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
3649
entity.GetTransform(),
3750
.prevent_overdraw = false,
@@ -46,25 +59,37 @@ GeometryResult EllipseGeometry::GetPositionUVBuffer(
4659
const Entity& entity,
4760
RenderPass& pass) const {
4861
auto& host_buffer = pass.GetTransientsBuffer();
49-
62+
using VT = TextureFillVertexShader::PerVertexData;
5063
auto uv_transform =
5164
texture_coverage.GetNormalizingTransform() * effect_transform;
52-
VertexBufferBuilder<TextureFillVertexShader::PerVertexData> vtx_builder;
5365

66+
Scalar radius = radius_;
67+
const Point& center = center_;
5468
CircleTessellator tessellator(entity.GetTransform(), radius_);
55-
vtx_builder.Reserve(tessellator.GetCircleVertexCount());
56-
tessellator.GenerateCircleTriangleStrip(
57-
[&vtx_builder, &uv_transform](const Point& p) {
58-
vtx_builder.AppendVertex({
59-
.position = p,
60-
.texture_coords = uv_transform * p,
61-
});
62-
},
63-
center_, radius_);
69+
size_t count = tessellator.GetCircleVertexCount();
70+
auto vertex_buffer = host_buffer.Emplace(
71+
count * sizeof(VT), alignof(VT),
72+
[&tessellator, &uv_transform, &center, radius](uint8_t* buffer) {
73+
auto vertices = reinterpret_cast<VT*>(buffer);
74+
tessellator.GenerateCircleTriangleStrip(
75+
[&vertices, &uv_transform](const Point& p) { //
76+
*vertices++ = {
77+
.position = p,
78+
.texture_coords = uv_transform * p,
79+
};
80+
},
81+
center, radius);
82+
});
6483

6584
return GeometryResult{
6685
.type = PrimitiveType::kTriangleStrip,
67-
.vertex_buffer = vtx_builder.CreateVertexBuffer(host_buffer),
86+
.vertex_buffer =
87+
{
88+
.vertex_buffer = vertex_buffer,
89+
.vertex_count = count,
90+
.index_type = IndexType::kNone,
91+
},
92+
// .vertex_buffer = vtx_builder.CreateVertexBuffer(host_buffer),
6893
.transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
6994
entity.GetTransform(),
7095
.prevent_overdraw = false,

impeller/entity/geometry/line_geometry.cc

Lines changed: 79 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -68,37 +68,58 @@ bool LineGeometry::ComputeCorners(Point corners[4],
6868
GeometryResult LineGeometry::GetPositionBuffer(const ContentContext& renderer,
6969
const Entity& entity,
7070
RenderPass& pass) const {
71+
auto& host_buffer = pass.GetTransientsBuffer();
72+
using VT = SolidFillVertexShader::PerVertexData;
73+
7174
auto& transform = entity.GetTransform();
7275
auto radius = ComputeHalfWidth(transform);
7376

74-
VertexBufferBuilder<SolidFillVertexShader::PerVertexData> vtx_builder;
75-
77+
size_t count;
78+
BufferView vertex_buffer;
7679
if (cap_ == Cap::kRound) {
80+
const Point& p0 = p0_;
81+
const Point& p1 = p1_;
82+
7783
CircleTessellator tessellator(transform, radius);
78-
vtx_builder.Reserve(tessellator.GetCircleVertexCount());
79-
tessellator.GenerateRoundCapLineTriangleStrip(
80-
[&vtx_builder](const Point& p) { //
81-
vtx_builder.AppendVertex({.position = p});
82-
},
83-
p0_, p1_, radius);
84+
count = tessellator.GetCircleVertexCount();
85+
vertex_buffer =
86+
host_buffer.Emplace(count * sizeof(VT), alignof(VT),
87+
[&tessellator, &p0, &p1, radius](uint8_t* buffer) {
88+
auto vertices = reinterpret_cast<VT*>(buffer);
89+
tessellator.GenerateRoundCapLineTriangleStrip(
90+
[&vertices](const Point& p) { //
91+
*vertices++ = {
92+
.position = p,
93+
};
94+
},
95+
p0, p1, radius);
96+
});
8497
} else {
8598
Point corners[4];
8699
if (ComputeCorners(corners, transform, cap_ == Cap::kSquare)) {
87-
vtx_builder.Reserve(4);
88-
vtx_builder.AppendVertex({.position = corners[0]});
89-
vtx_builder.AppendVertex({.position = corners[1]});
90-
vtx_builder.AppendVertex({.position = corners[2]});
91-
vtx_builder.AppendVertex({.position = corners[3]});
100+
count = 4;
101+
vertex_buffer = host_buffer.Emplace(
102+
count * sizeof(VT), alignof(VT), [&corners](uint8_t* buffer) {
103+
auto vertices = reinterpret_cast<VT*>(buffer);
104+
for (auto& corner : corners) {
105+
*vertices++ = {
106+
.position = corner,
107+
};
108+
}
109+
});
110+
} else {
111+
return {};
92112
}
93113
}
94-
if (!vtx_builder.HasVertices()) {
95-
return {};
96-
}
97114

98115
return GeometryResult{
99116
.type = PrimitiveType::kTriangleStrip,
100117
.vertex_buffer =
101-
vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()),
118+
{
119+
.vertex_buffer = vertex_buffer,
120+
.vertex_count = count,
121+
.index_type = IndexType::kNone,
122+
},
102123
.transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
103124
entity.GetTransform(),
104125
.prevent_overdraw = false,
@@ -111,44 +132,64 @@ GeometryResult LineGeometry::GetPositionUVBuffer(Rect texture_coverage,
111132
const ContentContext& renderer,
112133
const Entity& entity,
113134
RenderPass& pass) const {
135+
auto& host_buffer = pass.GetTransientsBuffer();
136+
using VT = TextureFillVertexShader::PerVertexData;
137+
114138
auto& transform = entity.GetTransform();
115139
auto radius = ComputeHalfWidth(transform);
116140

117141
auto uv_transform =
118142
texture_coverage.GetNormalizingTransform() * effect_transform;
119-
VertexBufferBuilder<TextureFillVertexShader::PerVertexData> vtx_builder;
120143

144+
size_t count;
145+
BufferView vertex_buffer;
121146
if (cap_ == Cap::kRound) {
147+
const Point& p0 = p0_;
148+
const Point& p1 = p1_;
149+
122150
CircleTessellator tessellator(transform, radius);
123-
vtx_builder.Reserve(tessellator.GetCircleVertexCount());
124-
tessellator.GenerateRoundCapLineTriangleStrip(
125-
[&vtx_builder, &uv_transform](const Point& p) {
126-
vtx_builder.AppendVertex({
127-
.position = p,
128-
.texture_coords = uv_transform * p,
129-
});
130-
},
131-
p0_, p1_, radius);
151+
count = tessellator.GetCircleVertexCount();
152+
vertex_buffer = host_buffer.Emplace(
153+
count * sizeof(VT), alignof(VT),
154+
[&tessellator, &uv_transform, &p0, &p1, radius](uint8_t* buffer) {
155+
auto vertices = reinterpret_cast<VT*>(buffer);
156+
tessellator.GenerateRoundCapLineTriangleStrip(
157+
[&vertices, &uv_transform](const Point& p) { //
158+
*vertices++ = {
159+
.position = p,
160+
.texture_coords = uv_transform * p,
161+
};
162+
},
163+
p0, p1, radius);
164+
});
132165
} else {
133166
Point corners[4];
134167
if (ComputeCorners(corners, transform, cap_ == Cap::kSquare)) {
135-
vtx_builder.Reserve(4);
136-
for (auto& corner : corners) {
137-
vtx_builder.AppendVertex({
138-
.position = corner,
139-
.texture_coords = uv_transform * corner,
140-
});
141-
}
168+
count = 4;
169+
vertex_buffer =
170+
host_buffer.Emplace(count * sizeof(VT), alignof(VT),
171+
[&uv_transform, &corners](uint8_t* buffer) {
172+
auto vertices = reinterpret_cast<VT*>(buffer);
173+
for (auto& corner : corners) {
174+
*vertices++ = {
175+
.position = corner,
176+
.texture_coords = uv_transform * corner,
177+
};
178+
}
179+
});
180+
} else {
181+
return {};
142182
}
143183
}
144-
if (!vtx_builder.HasVertices()) {
145-
return {};
146-
}
147184

148185
return GeometryResult{
149186
.type = PrimitiveType::kTriangleStrip,
150187
.vertex_buffer =
151-
vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()),
188+
{
189+
.vertex_buffer = vertex_buffer,
190+
.vertex_count = count,
191+
.index_type = IndexType::kNone,
192+
},
152193
.transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
153194
entity.GetTransform(),
154195
.prevent_overdraw = false,

0 commit comments

Comments
 (0)