Skip to content

Commit 120c0b6

Browse files
committed
Avoid instancing/SSBOs for text to support GLES (flutter#160)
1 parent 86fdc79 commit 120c0b6

File tree

6 files changed

+52
-98
lines changed

6 files changed

+52
-98
lines changed

impeller/entity/contents/text_contents.cc

Lines changed: 26 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -106,65 +106,41 @@ bool TextContents::Render(const ContentContext& renderer,
106106
// and the vertex shader uses this to size the glyph correctly. The
107107
// interpolated vertex information is also used in the fragment shader to
108108
// sample from the glyph atlas.
109-
{
110-
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
111-
if (!Tessellator{}.Tessellate(
112-
FillType::kPositive,
113-
PathBuilder{}
114-
.AddRect(Rect::MakeXYWH(0.0, 0.0, 1.0, 1.0))
115-
.TakePath()
116-
.CreatePolyline(),
117-
[&vertex_builder](Point point) {
118-
VS::PerVertexData vtx;
119-
vtx.unit_vertex = point;
120-
vertex_builder.AppendVertex(std::move(vtx));
121-
})) {
122-
return false;
123-
}
124-
auto dummy = vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer());
125-
auto vertex_buffer = dummy;
126-
if (!vertex_buffer) {
127-
return false;
128-
}
129-
cmd.BindVertices(std::move(vertex_buffer));
130-
}
131109

132-
size_t instance_count = 0u;
133-
std::vector<Matrix> glyph_positions;
134-
std::vector<Point> glyph_sizes;
135-
std::vector<Point> atlas_positions;
136-
std::vector<Point> atlas_glyph_sizes;
110+
const std::vector<Point> unit_vertex_points = {
111+
{0, 0}, {1, 0}, {0, 1}, {1, 0}, {0, 1}, {1, 1},
112+
};
137113

114+
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
138115
for (const auto& run : frame_.GetRuns()) {
139116
auto font = run.GetFont();
140117
auto glyph_size = ISize::Ceil(font.GetMetrics().GetBoundingBox().size);
141118
for (const auto& glyph_position : run.GetGlyphPositions()) {
142-
FontGlyphPair font_glyph_pair{font, glyph_position.glyph};
143-
auto atlas_glyph_pos = atlas->FindFontGlyphPosition(font_glyph_pair);
144-
if (!atlas_glyph_pos.has_value()) {
145-
VALIDATION_LOG << "Could not find glyph position in the atlas.";
146-
return false;
119+
for (const auto& point : unit_vertex_points) {
120+
VS::PerVertexData vtx;
121+
vtx.unit_vertex = point;
122+
123+
FontGlyphPair font_glyph_pair{font, glyph_position.glyph};
124+
auto atlas_glyph_pos = atlas->FindFontGlyphPosition(font_glyph_pair);
125+
if (!atlas_glyph_pos.has_value()) {
126+
VALIDATION_LOG << "Could not find glyph position in the atlas.";
127+
return false;
128+
}
129+
vtx.glyph_position =
130+
glyph_position.position +
131+
Point{font.GetMetrics().min_extent.x, font.GetMetrics().ascent};
132+
vtx.glyph_size = Point{static_cast<Scalar>(glyph_size.width),
133+
static_cast<Scalar>(glyph_size.height)};
134+
vtx.atlas_position = atlas_glyph_pos->origin;
135+
vtx.atlas_glyph_size =
136+
Point{atlas_glyph_pos->size.width, atlas_glyph_pos->size.height};
137+
vertex_builder.AppendVertex(std::move(vtx));
147138
}
148-
instance_count++;
149-
glyph_positions.emplace_back(glyph_position.position.Translate(
150-
{font.GetMetrics().min_extent.x, font.GetMetrics().ascent, 0.0}));
151-
glyph_sizes.emplace_back(Point{static_cast<Scalar>(glyph_size.width),
152-
static_cast<Scalar>(glyph_size.height)});
153-
atlas_positions.emplace_back(atlas_glyph_pos->origin);
154-
atlas_glyph_sizes.emplace_back(
155-
Point{atlas_glyph_pos->size.width, atlas_glyph_pos->size.height});
156139
}
157140
}
158-
159-
cmd.instance_count = instance_count;
160-
VS::BindGlyphPositions(
161-
cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(glyph_positions));
162-
VS::BindGlyphSizes(
163-
cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(glyph_sizes));
164-
VS::BindAtlasPositions(
165-
cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(atlas_positions));
166-
VS::BindAtlasGlyphSizes(
167-
cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(atlas_glyph_sizes));
141+
auto vertex_buffer =
142+
vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer());
143+
cmd.BindVertices(std::move(vertex_buffer));
168144

169145
if (!pass.AddCommand(cmd)) {
170146
return false;

impeller/entity/shaders/glyph_atlas.vert

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

5-
#ifdef IMPELLER_TARGET_OPENGLES
6-
7-
void main() {
8-
// Unimplemented because the implementation uses instancing and SSBOs.
9-
}
10-
11-
#else // IMPELLER_TARGET_OPENGLES
12-
135
uniform FrameInfo {
146
mat4 mvp;
157
vec2 atlas_size;
168
vec4 text_color;
179
} frame_info;
1810

19-
readonly buffer GlyphPositions {
20-
mat4 position[];
21-
} glyph_positions;
22-
23-
readonly buffer GlyphSizes {
24-
vec2 size[];
25-
} glyph_sizes;
26-
27-
readonly buffer AtlasPositions {
28-
vec2 position[];
29-
} atlas_positions;
30-
31-
readonly buffer AtlasGlyphSizes {
32-
vec2 size[];
33-
} atlas_glyph_sizes;
34-
3511
in vec2 unit_vertex;
12+
in vec2 glyph_position;
13+
in vec2 glyph_size;
14+
in vec2 atlas_position;
15+
in vec2 atlas_glyph_size;
3616

3717
out vec2 v_unit_vertex;
3818
out vec2 v_atlas_position;
@@ -41,26 +21,25 @@ out vec2 v_atlas_size;
4121
out vec4 v_text_color;
4222

4323
void main() {
44-
// The position to place the glyph.
45-
mat4 glyph_position = glyph_positions.position[gl_InstanceIndex];
46-
// The size of the glyph.
47-
vec2 glyph_size = glyph_sizes.size[gl_InstanceIndex];
48-
// The location of the glyph in the atlas.
49-
vec2 glyph_atlas_position = atlas_positions.position[gl_InstanceIndex];
50-
// The size of the glyph within the atlas.
51-
vec2 glyph_atlas_size = atlas_glyph_sizes.size[gl_InstanceIndex];
52-
53-
gl_Position = frame_info.mvp
54-
* glyph_position
24+
vec4 translate = frame_info.mvp[0] * glyph_position.x
25+
+ frame_info.mvp[1] * glyph_position.y
26+
+ frame_info.mvp[3];
27+
mat4 translated_mvp = mat4(
28+
frame_info.mvp[0],
29+
frame_info.mvp[1],
30+
frame_info.mvp[2],
31+
vec4(
32+
translate.xyz,
33+
frame_info.mvp[3].w
34+
)
35+
);
36+
gl_Position = translated_mvp
5537
* vec4(unit_vertex.x * glyph_size.x,
5638
unit_vertex.y * glyph_size.y, 0.0, 1.0);
5739

5840
v_unit_vertex = unit_vertex;
59-
v_atlas_position = glyph_atlas_position;
60-
v_atlas_glyph_size = glyph_atlas_size;
41+
v_atlas_position = atlas_position;
42+
v_atlas_glyph_size = atlas_glyph_size;
6143
v_atlas_size = frame_info.atlas_size;
6244
v_text_color = frame_info.text_color;
6345
}
64-
65-
#endif // IMPELLER_TARGET_OPENGLES
66-

impeller/typographer/backends/skia/text_frame_skia.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ TextFrame TextFrameFromTextBlob(sk_sp<SkTextBlob> blob, Scalar scale) {
5252
// kFull_Positioning has two scalars per glyph.
5353
const SkPoint* glyph_points = run.points();
5454
const auto* point = glyph_points + i;
55-
text_run.AddGlyph(glyphs[i],
56-
Matrix::MakeTranslation({point->x(), point->y()}));
55+
text_run.AddGlyph(glyphs[i], Point{point->x(), point->y()});
5756
}
5857
break;
5958
case SkTextBlobRunIterator::kRSXform_Positioning:

impeller/typographer/text_frame.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ std::optional<Rect> TextFrame::GetBounds() const {
1616
for (const auto& run : runs_) {
1717
const auto glyph_bounds = run.GetFont().GetMetrics().GetBoundingBox();
1818
for (const auto& glyph_position : run.GetGlyphPositions()) {
19-
Vector2 position = glyph_position.position * Vector2();
20-
Rect glyph_rect = Rect(position + glyph_bounds.origin, glyph_bounds.size);
19+
Rect glyph_rect = Rect(glyph_position.position + glyph_bounds.origin,
20+
glyph_bounds.size);
2121
result = result.has_value() ? result->Union(glyph_rect) : glyph_rect;
2222
}
2323
}

impeller/typographer/text_run.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ TextRun::TextRun(Font font) : font_(std::move(font)) {
1515

1616
TextRun::~TextRun() = default;
1717

18-
bool TextRun::AddGlyph(Glyph glyph, Matrix position) {
18+
bool TextRun::AddGlyph(Glyph glyph, Point position) {
1919
glyphs_.emplace_back(GlyphPosition{glyph, position});
2020
return true;
2121
}

impeller/typographer/text_run.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ class TextRun {
2020
public:
2121
struct GlyphPosition {
2222
Glyph glyph;
23-
Matrix position;
23+
Point position;
2424

25-
GlyphPosition(Glyph p_glyph, Matrix p_position)
25+
GlyphPosition(Glyph p_glyph, Point p_position)
2626
: glyph(p_glyph), position(p_position) {}
2727
};
2828

@@ -45,7 +45,7 @@ class TextRun {
4545
///
4646
/// @return If the glyph could be added to the run.
4747
///
48-
bool AddGlyph(Glyph glyph, Matrix position);
48+
bool AddGlyph(Glyph glyph, Point position);
4949

5050
//----------------------------------------------------------------------------
5151
/// @brief Get the number of glyphs in the run.

0 commit comments

Comments
 (0)