Skip to content

Commit 6f14ffb

Browse files
authored
[Impeller] Copy user indices directly into buffer for DrawVertices (flutter#34792)
1 parent a519f34 commit 6f14ffb

File tree

11 files changed

+149
-61
lines changed

11 files changed

+149
-61
lines changed

display_list/display_list_vertices.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class DlVertices {
108108
///
109109
/// Vertices are always required. Optional texture coordinates
110110
/// and optional colors are reserved depending on the |Flags|.
111-
/// Optional indices will be reserved iff the index_count is
111+
/// Optional indices will be reserved if the index_count is
112112
/// positive (>0).
113113
///
114114
/// The caller must provide all data that is promised by the

impeller/aiks/canvas.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,11 +306,12 @@ void Canvas::DrawTextFrame(TextFrame text_frame, Point position, Paint paint) {
306306
}
307307

308308
void Canvas::DrawVertices(Vertices vertices,
309-
Entity::BlendMode mode,
309+
Entity::BlendMode blend_mode,
310310
Paint paint) {
311311
std::shared_ptr<VerticesContents> contents =
312312
std::make_shared<VerticesContents>(std::move(vertices));
313313
contents->SetColor(paint.color);
314+
contents->SetBlendMode(blend_mode);
314315
Entity entity;
315316
entity.SetTransformation(GetCurrentTransformation());
316317
entity.SetStencilDepth(GetStencilDepth());

impeller/aiks/canvas.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ class Canvas {
9393

9494
void DrawTextFrame(TextFrame text_frame, Point position, Paint paint);
9595

96-
void DrawVertices(Vertices vertices, Entity::BlendMode mode, Paint paint);
96+
void DrawVertices(Vertices vertices,
97+
Entity::BlendMode blend_mode,
98+
Paint paint);
9799

98100
Picture EndRecordingAsPicture();
99101

impeller/entity/contents/vertices_contents.cc

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "impeller/renderer/formats.h"
1313
#include "impeller/renderer/render_pass.h"
1414
#include "impeller/renderer/sampler_library.h"
15+
#include "impeller/renderer/vertex_buffer.h"
1516

1617
namespace impeller {
1718

@@ -28,10 +29,27 @@ void VerticesContents::SetColor(Color color) {
2829
color_ = color.Premultiply();
2930
}
3031

32+
void VerticesContents::SetBlendMode(Entity::BlendMode blend_mode) {
33+
blend_mode_ = blend_mode;
34+
}
35+
36+
static PrimitiveType GetPrimitiveType(const Vertices& vertices) {
37+
switch (vertices.GetMode()) {
38+
case VertexMode::kTriangle:
39+
return PrimitiveType::kTriangle;
40+
case VertexMode::kTriangleStrip:
41+
return PrimitiveType::kTriangleStrip;
42+
}
43+
}
44+
3145
bool VerticesContents::Render(const ContentContext& renderer,
3246
const Entity& entity,
3347
RenderPass& pass) const {
34-
using VS = VerticesVertexShader;
48+
if (!vertices_.IsValid()) {
49+
return true;
50+
}
51+
52+
using VS = VerticesPipeline::VertexShader;
3553

3654
const auto coverage_rect = vertices_.GetBoundingBox();
3755

@@ -43,42 +61,36 @@ bool VerticesContents::Render(const ContentContext& renderer,
4361
return true;
4462
}
4563

46-
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
47-
std::vector<Point> points = vertices_.GetPoints();
48-
std::vector<uint16_t> indices = vertices_.GetIndices();
49-
// TODO: colors are currently unused, must be blended with
50-
// paint color based on provided blend mode.
51-
std::vector<Color> colors = vertices_.GetColors();
52-
VertexMode mode = vertices_.GetMode();
53-
54-
if (indices.size() == 0) {
55-
for (size_t i = 0; i < points.size(); i += 1) {
56-
VS::PerVertexData data;
57-
data.point = points[i];
58-
data.vertex_color = color_;
59-
vertex_builder.AppendVertex(data);
60-
}
61-
} else {
62-
for (size_t i = 0; i < indices.size(); i += 1) {
63-
VS::PerVertexData data;
64-
data.point = points[indices[i]];
65-
data.vertex_color = color_;
66-
vertex_builder.AppendVertex(data);
64+
std::vector<VS::PerVertexData> vertex_data;
65+
{
66+
const auto& positions = vertices_.GetPositions();
67+
const auto& colors = vertices_.GetColors();
68+
for (size_t i = 0; i < positions.size(); i++) {
69+
vertex_data.push_back(VS::PerVertexData{
70+
.position = positions[i],
71+
// TODO(108047): Blend these colors together when available. Use
72+
// colors[i] as the destination and color_ as the
73+
// source. Always use color_ when vertex colors are not
74+
// supplied.
75+
.color = i < colors.size() ? colors[i] : color_,
76+
});
6777
}
6878
}
6979

70-
PrimitiveType primitiveType;
71-
switch (mode) {
72-
case VertexMode::kTriangle:
73-
primitiveType = PrimitiveType::kTriangle;
74-
break;
75-
case VertexMode::kTriangleStrip:
76-
primitiveType = PrimitiveType::kTriangleStrip;
77-
break;
78-
}
80+
size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData);
81+
size_t total_idx_bytes = vertices_.GetIndices().size() * sizeof(uint16_t);
7982

80-
if (!vertex_builder.HasVertices()) {
81-
return true;
83+
auto buffer = renderer.GetContext()->GetTransientsAllocator()->CreateBuffer(
84+
StorageMode::kHostVisible, total_vtx_bytes + total_idx_bytes);
85+
86+
if (!buffer->CopyHostBuffer(reinterpret_cast<uint8_t*>(vertex_data.data()),
87+
Range{0, total_vtx_bytes}, 0)) {
88+
return false;
89+
}
90+
if (!buffer->CopyHostBuffer(reinterpret_cast<uint8_t*>(const_cast<uint16_t*>(
91+
vertices_.GetIndices().data())),
92+
Range{0, total_idx_bytes}, total_vtx_bytes)) {
93+
return false;
8294
}
8395

8496
auto& host_buffer = pass.GetTransientsBuffer();
@@ -91,8 +103,14 @@ bool VerticesContents::Render(const ContentContext& renderer,
91103
cmd.pipeline =
92104
renderer.GetVerticesPipeline(OptionsFromPassAndEntity(pass, entity));
93105
cmd.stencil_reference = entity.GetStencilDepth();
94-
cmd.primitive_type = primitiveType;
95-
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));
106+
cmd.primitive_type = GetPrimitiveType(vertices_);
107+
cmd.BindVertices({
108+
.vertex_buffer = {.buffer = buffer, .range = Range{0, total_vtx_bytes}},
109+
.index_buffer = {.buffer = buffer,
110+
.range = Range{total_vtx_bytes, total_idx_bytes}},
111+
.index_count = vertices_.GetIndices().size(),
112+
.index_type = IndexType::k16bit,
113+
});
96114
VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
97115
pass.AddCommand(std::move(cmd));
98116

impeller/entity/contents/vertices_contents.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "flutter/fml/macros.h"
1212
#include "impeller/entity/contents/contents.h"
13+
#include "impeller/entity/entity.h"
1314
#include "impeller/geometry/color.h"
1415
#include "impeller/geometry/path.h"
1516
#include "impeller/geometry/point.h"
@@ -26,6 +27,8 @@ class VerticesContents final : public Contents {
2627

2728
void SetColor(Color color);
2829

30+
void SetBlendMode(Entity::BlendMode blend_mode);
31+
2932
// |Contents|
3033
std::optional<Rect> GetCoverage(const Entity& entity) const override;
3134

@@ -37,6 +40,7 @@ class VerticesContents final : public Contents {
3740
public:
3841
Vertices vertices_;
3942
Color color_;
43+
Entity::BlendMode blend_mode_ = Entity::BlendMode::kSource;
4044

4145
FML_DISALLOW_COPY_AND_ASSIGN(VerticesContents);
4246
};

impeller/entity/entity_unittests.cc

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,14 +1055,31 @@ TEST_P(EntityTest, BorderMaskBlurCoverageIsCorrect) {
10551055
}
10561056
}
10571057

1058-
TEST_P(EntityTest, DrawVerticesSolidColorTrianglesWithoutIndex) {
1059-
std::vector<Point> points = {Point(100, 300), Point(200, 100),
1060-
Point(300, 300)};
1061-
std::vector<uint16_t> indexes;
1058+
TEST_P(EntityTest, DrawVerticesSolidColorTrianglesWithoutIndices) {
1059+
std::vector<Point> positions = {Point(100, 300), Point(200, 100),
1060+
Point(300, 300)};
10621061
std::vector<Color> colors = {Color::White(), Color::White(), Color::White()};
10631062

1064-
Vertices vertices = Vertices(points, indexes, colors, VertexMode::kTriangle,
1065-
Rect(100, 100, 300, 300));
1063+
Vertices vertices = Vertices(positions, {} /* indices */, colors,
1064+
VertexMode::kTriangle, Rect(100, 100, 300, 300));
1065+
1066+
std::shared_ptr<VerticesContents> contents =
1067+
std::make_shared<VerticesContents>(vertices);
1068+
contents->SetColor(Color::White());
1069+
Entity e;
1070+
e.SetTransformation(Matrix::MakeScale(GetContentScale()));
1071+
e.SetContents(contents);
1072+
1073+
ASSERT_TRUE(OpenPlaygroundHere(e));
1074+
}
1075+
1076+
TEST_P(EntityTest, DrawVerticesSolidColorTrianglesWithIndices) {
1077+
std::vector<Point> positions = {Point(100, 300), Point(200, 100),
1078+
Point(300, 300), Point(200, 500)};
1079+
std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
1080+
1081+
Vertices vertices = Vertices(positions, indices, {} /* colors */,
1082+
VertexMode::kTriangle, Rect(100, 100, 300, 300));
10661083

10671084
std::shared_ptr<VerticesContents> contents =
10681085
std::make_shared<VerticesContents>(vertices);

impeller/entity/shaders/vertices.frag

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
in vec4 color;
5+
in vec4 v_color;
66

77
out vec4 frag_color;
88

99
void main() {
10-
frag_color = color;
10+
frag_color = v_color;
1111
}

impeller/entity/shaders/vertices.vert

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ uniform FrameInfo {
66
mat4 mvp;
77
} frame_info;
88

9-
in vec2 point;
10-
in vec4 vertex_color;
9+
in vec2 position;
10+
in vec4 color;
1111

12-
out vec4 color;
12+
out vec4 v_color;
1313

1414
void main() {
15-
gl_Position = frame_info.mvp * vec4(point, 0.0, 1.0);
16-
color = vertex_color;
15+
gl_Position = frame_info.mvp * vec4(position, 0.0, 1.0);
16+
v_color = color;
1717
}

impeller/geometry/geometry_unittests.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,7 @@ TEST(GeometryTest, VerticesConstructorAndGetters) {
12331233
Rect(0, 0, 4, 4));
12341234

12351235
ASSERT_EQ(vertices.GetBoundingBox().value(), Rect(0, 0, 4, 4));
1236-
ASSERT_EQ(vertices.GetPoints(), points);
1236+
ASSERT_EQ(vertices.GetPositions(), points);
12371237
ASSERT_EQ(vertices.GetIndices(), indices);
12381238
ASSERT_EQ(vertices.GetColors(), colors);
12391239
ASSERT_EQ(vertices.GetMode(), VertexMode::kTriangle);

impeller/geometry/vertices.cc

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,31 @@ Vertices::Vertices(std::vector<Point> points,
1111
std::vector<Color> colors,
1212
VertexMode vertex_mode,
1313
Rect bounds)
14-
: points_(std::move(points)),
14+
: positions_(std::move(points)),
1515
indices_(std::move(indices)),
1616
colors_(std::move(colors)),
1717
vertex_mode_(vertex_mode),
18-
bounds_(bounds){};
18+
bounds_(bounds) {
19+
NormalizeIndices();
20+
}
1921

2022
Vertices::~Vertices() = default;
2123

24+
bool Vertices::IsValid() const {
25+
size_t points_size = positions_.size();
26+
size_t colors_size = colors_.size();
27+
28+
if (colors_size > 0 && colors_size != points_size) {
29+
return false;
30+
}
31+
32+
return true;
33+
}
34+
35+
std::optional<Rect> Vertices::GetBoundingBox() const {
36+
return bounds_;
37+
};
38+
2239
std::optional<Rect> Vertices::GetTransformedBoundingBox(
2340
const Matrix& transform) const {
2441
auto bounds = GetBoundingBox();
@@ -28,4 +45,29 @@ std::optional<Rect> Vertices::GetTransformedBoundingBox(
2845
return bounds->TransformBounds(transform);
2946
};
3047

48+
const std::vector<Point>& Vertices::GetPositions() const {
49+
return positions_;
50+
}
51+
52+
const std::vector<uint16_t>& Vertices::GetIndices() const {
53+
return indices_;
54+
}
55+
56+
const std::vector<Color>& Vertices::GetColors() const {
57+
return colors_;
58+
}
59+
60+
VertexMode Vertices::GetMode() const {
61+
return vertex_mode_;
62+
}
63+
64+
void Vertices::NormalizeIndices() {
65+
if (indices_.size() != 0 || positions_.size() == 0) {
66+
return;
67+
}
68+
for (size_t i = 0; i < positions_.size(); i++) {
69+
indices_.push_back(i);
70+
}
71+
}
72+
3173
} // namespace impeller

0 commit comments

Comments
 (0)