mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Avoid instancing/SSBOs for text to support GLES (flutter/engine#160)
This commit is contained in:
parent
21088d20a8
commit
bc34d52063
@ -106,65 +106,41 @@ bool TextContents::Render(const ContentContext& renderer,
|
||||
// and the vertex shader uses this to size the glyph correctly. The
|
||||
// interpolated vertex information is also used in the fragment shader to
|
||||
// sample from the glyph atlas.
|
||||
{
|
||||
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
|
||||
if (!Tessellator{}.Tessellate(
|
||||
FillType::kPositive,
|
||||
PathBuilder{}
|
||||
.AddRect(Rect::MakeXYWH(0.0, 0.0, 1.0, 1.0))
|
||||
.TakePath()
|
||||
.CreatePolyline(),
|
||||
[&vertex_builder](Point point) {
|
||||
VS::PerVertexData vtx;
|
||||
vtx.unit_vertex = point;
|
||||
vertex_builder.AppendVertex(std::move(vtx));
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
auto dummy = vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer());
|
||||
auto vertex_buffer = dummy;
|
||||
if (!vertex_buffer) {
|
||||
return false;
|
||||
}
|
||||
cmd.BindVertices(std::move(vertex_buffer));
|
||||
}
|
||||
|
||||
size_t instance_count = 0u;
|
||||
std::vector<Matrix> glyph_positions;
|
||||
std::vector<Point> glyph_sizes;
|
||||
std::vector<Point> atlas_positions;
|
||||
std::vector<Point> atlas_glyph_sizes;
|
||||
const std::vector<Point> unit_vertex_points = {
|
||||
{0, 0}, {1, 0}, {0, 1}, {1, 0}, {0, 1}, {1, 1},
|
||||
};
|
||||
|
||||
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
|
||||
for (const auto& run : frame_.GetRuns()) {
|
||||
auto font = run.GetFont();
|
||||
auto glyph_size = ISize::Ceil(font.GetMetrics().GetBoundingBox().size);
|
||||
for (const auto& glyph_position : run.GetGlyphPositions()) {
|
||||
FontGlyphPair font_glyph_pair{font, glyph_position.glyph};
|
||||
auto atlas_glyph_pos = atlas->FindFontGlyphPosition(font_glyph_pair);
|
||||
if (!atlas_glyph_pos.has_value()) {
|
||||
VALIDATION_LOG << "Could not find glyph position in the atlas.";
|
||||
return false;
|
||||
for (const auto& point : unit_vertex_points) {
|
||||
VS::PerVertexData vtx;
|
||||
vtx.unit_vertex = point;
|
||||
|
||||
FontGlyphPair font_glyph_pair{font, glyph_position.glyph};
|
||||
auto atlas_glyph_pos = atlas->FindFontGlyphPosition(font_glyph_pair);
|
||||
if (!atlas_glyph_pos.has_value()) {
|
||||
VALIDATION_LOG << "Could not find glyph position in the atlas.";
|
||||
return false;
|
||||
}
|
||||
vtx.glyph_position =
|
||||
glyph_position.position +
|
||||
Point{font.GetMetrics().min_extent.x, font.GetMetrics().ascent};
|
||||
vtx.glyph_size = Point{static_cast<Scalar>(glyph_size.width),
|
||||
static_cast<Scalar>(glyph_size.height)};
|
||||
vtx.atlas_position = atlas_glyph_pos->origin;
|
||||
vtx.atlas_glyph_size =
|
||||
Point{atlas_glyph_pos->size.width, atlas_glyph_pos->size.height};
|
||||
vertex_builder.AppendVertex(std::move(vtx));
|
||||
}
|
||||
instance_count++;
|
||||
glyph_positions.emplace_back(glyph_position.position.Translate(
|
||||
{font.GetMetrics().min_extent.x, font.GetMetrics().ascent, 0.0}));
|
||||
glyph_sizes.emplace_back(Point{static_cast<Scalar>(glyph_size.width),
|
||||
static_cast<Scalar>(glyph_size.height)});
|
||||
atlas_positions.emplace_back(atlas_glyph_pos->origin);
|
||||
atlas_glyph_sizes.emplace_back(
|
||||
Point{atlas_glyph_pos->size.width, atlas_glyph_pos->size.height});
|
||||
}
|
||||
}
|
||||
|
||||
cmd.instance_count = instance_count;
|
||||
VS::BindGlyphPositions(
|
||||
cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(glyph_positions));
|
||||
VS::BindGlyphSizes(
|
||||
cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(glyph_sizes));
|
||||
VS::BindAtlasPositions(
|
||||
cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(atlas_positions));
|
||||
VS::BindAtlasGlyphSizes(
|
||||
cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(atlas_glyph_sizes));
|
||||
auto vertex_buffer =
|
||||
vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer());
|
||||
cmd.BindVertices(std::move(vertex_buffer));
|
||||
|
||||
if (!pass.AddCommand(cmd)) {
|
||||
return false;
|
||||
|
||||
@ -2,37 +2,17 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifdef IMPELLER_TARGET_OPENGLES
|
||||
|
||||
void main() {
|
||||
// Unimplemented because the implementation uses instancing and SSBOs.
|
||||
}
|
||||
|
||||
#else // IMPELLER_TARGET_OPENGLES
|
||||
|
||||
uniform FrameInfo {
|
||||
mat4 mvp;
|
||||
vec2 atlas_size;
|
||||
vec4 text_color;
|
||||
} frame_info;
|
||||
|
||||
readonly buffer GlyphPositions {
|
||||
mat4 position[];
|
||||
} glyph_positions;
|
||||
|
||||
readonly buffer GlyphSizes {
|
||||
vec2 size[];
|
||||
} glyph_sizes;
|
||||
|
||||
readonly buffer AtlasPositions {
|
||||
vec2 position[];
|
||||
} atlas_positions;
|
||||
|
||||
readonly buffer AtlasGlyphSizes {
|
||||
vec2 size[];
|
||||
} atlas_glyph_sizes;
|
||||
|
||||
in vec2 unit_vertex;
|
||||
in vec2 glyph_position;
|
||||
in vec2 glyph_size;
|
||||
in vec2 atlas_position;
|
||||
in vec2 atlas_glyph_size;
|
||||
|
||||
out vec2 v_unit_vertex;
|
||||
out vec2 v_atlas_position;
|
||||
@ -41,26 +21,25 @@ out vec2 v_atlas_size;
|
||||
out vec4 v_text_color;
|
||||
|
||||
void main() {
|
||||
// The position to place the glyph.
|
||||
mat4 glyph_position = glyph_positions.position[gl_InstanceIndex];
|
||||
// The size of the glyph.
|
||||
vec2 glyph_size = glyph_sizes.size[gl_InstanceIndex];
|
||||
// The location of the glyph in the atlas.
|
||||
vec2 glyph_atlas_position = atlas_positions.position[gl_InstanceIndex];
|
||||
// The size of the glyph within the atlas.
|
||||
vec2 glyph_atlas_size = atlas_glyph_sizes.size[gl_InstanceIndex];
|
||||
|
||||
gl_Position = frame_info.mvp
|
||||
* glyph_position
|
||||
vec4 translate = frame_info.mvp[0] * glyph_position.x
|
||||
+ frame_info.mvp[1] * glyph_position.y
|
||||
+ frame_info.mvp[3];
|
||||
mat4 translated_mvp = mat4(
|
||||
frame_info.mvp[0],
|
||||
frame_info.mvp[1],
|
||||
frame_info.mvp[2],
|
||||
vec4(
|
||||
translate.xyz,
|
||||
frame_info.mvp[3].w
|
||||
)
|
||||
);
|
||||
gl_Position = translated_mvp
|
||||
* vec4(unit_vertex.x * glyph_size.x,
|
||||
unit_vertex.y * glyph_size.y, 0.0, 1.0);
|
||||
|
||||
v_unit_vertex = unit_vertex;
|
||||
v_atlas_position = glyph_atlas_position;
|
||||
v_atlas_glyph_size = glyph_atlas_size;
|
||||
v_atlas_position = atlas_position;
|
||||
v_atlas_glyph_size = atlas_glyph_size;
|
||||
v_atlas_size = frame_info.atlas_size;
|
||||
v_text_color = frame_info.text_color;
|
||||
}
|
||||
|
||||
#endif // IMPELLER_TARGET_OPENGLES
|
||||
|
||||
|
||||
@ -52,8 +52,7 @@ TextFrame TextFrameFromTextBlob(sk_sp<SkTextBlob> blob, Scalar scale) {
|
||||
// kFull_Positioning has two scalars per glyph.
|
||||
const SkPoint* glyph_points = run.points();
|
||||
const auto* point = glyph_points + i;
|
||||
text_run.AddGlyph(glyphs[i],
|
||||
Matrix::MakeTranslation({point->x(), point->y()}));
|
||||
text_run.AddGlyph(glyphs[i], Point{point->x(), point->y()});
|
||||
}
|
||||
break;
|
||||
case SkTextBlobRunIterator::kRSXform_Positioning:
|
||||
|
||||
@ -16,8 +16,8 @@ std::optional<Rect> TextFrame::GetBounds() const {
|
||||
for (const auto& run : runs_) {
|
||||
const auto glyph_bounds = run.GetFont().GetMetrics().GetBoundingBox();
|
||||
for (const auto& glyph_position : run.GetGlyphPositions()) {
|
||||
Vector2 position = glyph_position.position * Vector2();
|
||||
Rect glyph_rect = Rect(position + glyph_bounds.origin, glyph_bounds.size);
|
||||
Rect glyph_rect = Rect(glyph_position.position + glyph_bounds.origin,
|
||||
glyph_bounds.size);
|
||||
result = result.has_value() ? result->Union(glyph_rect) : glyph_rect;
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ TextRun::TextRun(Font font) : font_(std::move(font)) {
|
||||
|
||||
TextRun::~TextRun() = default;
|
||||
|
||||
bool TextRun::AddGlyph(Glyph glyph, Matrix position) {
|
||||
bool TextRun::AddGlyph(Glyph glyph, Point position) {
|
||||
glyphs_.emplace_back(GlyphPosition{glyph, position});
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -20,9 +20,9 @@ class TextRun {
|
||||
public:
|
||||
struct GlyphPosition {
|
||||
Glyph glyph;
|
||||
Matrix position;
|
||||
Point position;
|
||||
|
||||
GlyphPosition(Glyph p_glyph, Matrix p_position)
|
||||
GlyphPosition(Glyph p_glyph, Point p_position)
|
||||
: glyph(p_glyph), position(p_position) {}
|
||||
};
|
||||
|
||||
@ -45,7 +45,7 @@ class TextRun {
|
||||
///
|
||||
/// @return If the glyph could be added to the run.
|
||||
///
|
||||
bool AddGlyph(Glyph glyph, Matrix position);
|
||||
bool AddGlyph(Glyph glyph, Point position);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Get the number of glyphs in the run.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user