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

Commit 688782f

Browse files
author
Jonah Williams
authored
[Impeller] Use separate atlases and shaders for color and alpha (#41780)
Creates a separate atlas context and cache for color and alpha bitmap glyphs. Removes SDF shader and uses separate shader for full color glyphs. Requires #41754 Fixes flutter/flutter#116818 Fixes flutter/flutter#126101 This also fixes #39383 but for light text on a dark background. This problem crops up when we switch to a full color atlas. In this context, the chosen glyph color is important. But with the alpha channel only atlas, its irrelevant. See diff: ![image](https://user-images.githubusercontent.com/8975114/236598809-f4434764-cd16-4489-9644-4e9a370de7ee.png) Example app: ```dart // Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; void main() => runApp( Container( alignment: Alignment.center, child: Text( ''' (Unicode Conference)� ا�ذ� س�ع�د �� 10-12 آذار 1997 ب�د��ة ��ا����ت�س� أ��ا��ا. � س�ج�ع ا��ؤت�ر ب�� خبراء �� �ا�ة �طاعات ا�ص�اعة ع�� ا�شب�ة ا�عا���ة ا�تر��ت �������د� ح�ث ستت�� ع�� ا�صع�د�� ا�د��� �ا��ح�� ع�� حد س�اء ��ا�شة سب� استخدا� �����د �� ا��ظ� ا��ائ�ة ����ا �خص ا�تطب��ات ا�حاس�ب�ة� ا�خط�ط� تص��� ا��ص�ص �ا�ح�سبة �تعددة ا��غات. ������������� � � � �''', textDirection: TextDirection.rtl, style: TextStyle(fontSize: 24, color: Colors.white), ), ), ); ```
1 parent ee6b2f4 commit 688782f

16 files changed

+224
-515
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,8 +1297,7 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noa
12971297
ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag + ../../../flutter/LICENSE
12981298
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag + ../../../flutter/LICENSE
12991299
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert + ../../../flutter/LICENSE
1300-
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.frag + ../../../flutter/LICENSE
1301-
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.vert + ../../../flutter/LICENSE
1300+
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas_color.frag + ../../../flutter/LICENSE
13021301
ORIGIN: ../../../flutter/impeller/entity/shaders/gradient_fill.vert + ../../../flutter/LICENSE
13031302
ORIGIN: ../../../flutter/impeller/entity/shaders/linear_gradient_fill.frag + ../../../flutter/LICENSE
13041303
ORIGIN: ../../../flutter/impeller/entity/shaders/linear_gradient_ssbo_fill.frag + ../../../flutter/LICENSE
@@ -3910,8 +3909,7 @@ FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalp
39103909
FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag
39113910
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag
39123911
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert
3913-
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.frag
3914-
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.vert
3912+
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_color.frag
39153913
FILE: ../../../flutter/impeller/entity/shaders/gradient_fill.vert
39163914
FILE: ../../../flutter/impeller/entity/shaders/linear_gradient_fill.frag
39173915
FILE: ../../../flutter/impeller/entity/shaders/linear_gradient_ssbo_fill.frag

impeller/entity/BUILD.gn

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ impeller_shaders("entity_shaders") {
4343
"shaders/gaussian_blur/gaussian_blur_noalpha_decal.frag",
4444
"shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag",
4545
"shaders/glyph_atlas.frag",
46+
"shaders/glyph_atlas_color.frag",
4647
"shaders/glyph_atlas.vert",
47-
"shaders/glyph_atlas_sdf.frag",
48-
"shaders/glyph_atlas_sdf.vert",
4948
"shaders/gradient_fill.vert",
5049
"shaders/linear_to_srgb_filter.frag",
5150
"shaders/linear_to_srgb_filter.vert",

impeller/entity/contents/content_context.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ static std::unique_ptr<PipelineT> CreateDefaultPipeline(
164164
ContentContext::ContentContext(std::shared_ptr<Context> context)
165165
: context_(std::move(context)),
166166
tessellator_(std::make_shared<Tessellator>()),
167-
glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()),
167+
alpha_glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()),
168+
color_glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()),
168169
scene_context_(std::make_shared<scene::SceneContext>(context_)) {
169170
if (!context_ || !context_->IsValid()) {
170171
return;
@@ -286,6 +287,8 @@ ContentContext::ContentContext(std::shared_ptr<Context> context)
286287
CreateDefaultPipeline<SrgbToLinearFilterPipeline>(*context_);
287288
glyph_atlas_pipelines_[{}] =
288289
CreateDefaultPipeline<GlyphAtlasPipeline>(*context_);
290+
glyph_atlas_color_pipelines_[{}] =
291+
CreateDefaultPipeline<GlyphAtlasColorPipeline>(*context_);
289292
geometry_color_pipelines_[{}] =
290293
CreateDefaultPipeline<GeometryColorPipeline>(*context_);
291294
yuv_to_rgb_filter_pipelines_[{}] =
@@ -378,9 +381,10 @@ std::shared_ptr<Tessellator> ContentContext::GetTessellator() const {
378381
return tessellator_;
379382
}
380383

381-
std::shared_ptr<GlyphAtlasContext> ContentContext::GetGlyphAtlasContext()
382-
const {
383-
return glyph_atlas_context_;
384+
std::shared_ptr<GlyphAtlasContext> ContentContext::GetGlyphAtlasContext(
385+
GlyphAtlas::Type type) const {
386+
return type == GlyphAtlas::Type::kAlphaBitmap ? alpha_glyph_atlas_context_
387+
: color_glyph_atlas_context_;
384388
}
385389

386390
std::shared_ptr<Context> ContentContext::GetContext() const {

impeller/entity/contents/content_context.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "impeller/entity/conical_gradient_fill.frag.h"
3333
#include "impeller/entity/glyph_atlas.frag.h"
3434
#include "impeller/entity/glyph_atlas.vert.h"
35+
#include "impeller/entity/glyph_atlas_color.frag.h"
3536
#include "impeller/entity/gradient_fill.vert.h"
3637
#include "impeller/entity/linear_gradient_fill.frag.h"
3738
#include "impeller/entity/linear_to_srgb_filter.frag.h"
@@ -171,6 +172,8 @@ using SrgbToLinearFilterPipeline =
171172
SrgbToLinearFilterFragmentShader>;
172173
using GlyphAtlasPipeline =
173174
RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasFragmentShader>;
175+
using GlyphAtlasColorPipeline =
176+
RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasColorFragmentShader>;
174177
using PorterDuffBlendPipeline =
175178
RenderPipelineT<BlendVertexShader, PorterDuffBlendFragmentShader>;
176179
// Instead of requiring new shaders for clips, the solid fill stages are used
@@ -469,6 +472,11 @@ class ContentContext {
469472
return GetPipeline(glyph_atlas_pipelines_, opts);
470473
}
471474

475+
std::shared_ptr<Pipeline<PipelineDescriptor>> GetGlyphAtlasColorPipeline(
476+
ContentContextOptions opts) const {
477+
return GetPipeline(glyph_atlas_color_pipelines_, opts);
478+
}
479+
472480
std::shared_ptr<Pipeline<PipelineDescriptor>> GetGeometryColorPipeline(
473481
ContentContextOptions opts) const {
474482
return GetPipeline(geometry_color_pipelines_, opts);
@@ -654,7 +662,8 @@ class ContentContext {
654662

655663
std::shared_ptr<Context> GetContext() const;
656664

657-
std::shared_ptr<GlyphAtlasContext> GetGlyphAtlasContext() const;
665+
std::shared_ptr<GlyphAtlasContext> GetGlyphAtlasContext(
666+
GlyphAtlas::Type type) const;
658667

659668
const Capabilities& GetDeviceCapabilities() const;
660669

@@ -722,6 +731,7 @@ class ContentContext {
722731
mutable Variants<SrgbToLinearFilterPipeline> srgb_to_linear_filter_pipelines_;
723732
mutable Variants<ClipPipeline> clip_pipelines_;
724733
mutable Variants<GlyphAtlasPipeline> glyph_atlas_pipelines_;
734+
mutable Variants<GlyphAtlasColorPipeline> glyph_atlas_color_pipelines_;
725735
mutable Variants<GeometryColorPipeline> geometry_color_pipelines_;
726736
mutable Variants<YUVToRGBFilterPipeline> yuv_to_rgb_filter_pipelines_;
727737
mutable Variants<PorterDuffBlendPipeline> porter_duff_blend_pipelines_;
@@ -813,7 +823,8 @@ class ContentContext {
813823

814824
bool is_valid_ = false;
815825
std::shared_ptr<Tessellator> tessellator_;
816-
std::shared_ptr<GlyphAtlasContext> glyph_atlas_context_;
826+
std::shared_ptr<GlyphAtlasContext> alpha_glyph_atlas_context_;
827+
std::shared_ptr<GlyphAtlasContext> color_glyph_atlas_context_;
817828
std::shared_ptr<scene::SceneContext> scene_context_;
818829
bool wireframe_ = false;
819830

impeller/entity/contents/text_contents.cc

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ static bool CommonRender(
112112
frag_info.text_color = ToVector(color.Premultiply());
113113
FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));
114114

115-
// Common fragment uniforms for all glyphs.
116115
FS::BindGlyphAtlasSampler(
117116
cmd, // command
118117
atlas->GetTexture(), // texture
@@ -198,9 +197,6 @@ static bool CommonRender(
198197
point * glyph_position.glyph.bounds.size);
199198
}
200199
vtx.uv = uv_origin + point * uv_size;
201-
vtx.has_color =
202-
glyph_position.glyph.type == Glyph::Type::kBitmap ? 1.0 : 0.0;
203-
204200
vertex_builder.AppendVertex(vtx);
205201
}
206202
}
@@ -224,16 +220,9 @@ bool TextContents::Render(const ContentContext& renderer,
224220
return true;
225221
}
226222

227-
// This TextContents may be for a frame that doesn't have color, but the
228-
// lazy atlas for this scene already does have color.
229-
// Benchmarks currently show that creating two atlases per pass regresses
230-
// render time. This should get re-evaluated if we start caching atlases
231-
// between frames or get significantly faster at creating atlases, because
232-
// we're potentially trading memory for time here.
233-
auto atlas =
234-
ResolveAtlas(lazy_atlas_->HasColor() ? GlyphAtlas::Type::kColorBitmap
235-
: GlyphAtlas::Type::kAlphaBitmap,
236-
renderer.GetGlyphAtlasContext(), renderer.GetContext());
223+
auto type = frame_.GetAtlasType();
224+
auto atlas = ResolveAtlas(type, renderer.GetGlyphAtlasContext(type),
225+
renderer.GetContext());
237226

238227
if (!atlas || !atlas->IsValid()) {
239228
VALIDATION_LOG << "Cannot render glyphs without prepared atlas.";
@@ -245,7 +234,11 @@ bool TextContents::Render(const ContentContext& renderer,
245234
cmd.label = "TextFrame";
246235
auto opts = OptionsFromPassAndEntity(pass, entity);
247236
opts.primitive_type = PrimitiveType::kTriangle;
248-
cmd.pipeline = renderer.GetGlyphAtlasPipeline(opts);
237+
if (type == GlyphAtlas::Type::kAlphaBitmap) {
238+
cmd.pipeline = renderer.GetGlyphAtlasPipeline(opts);
239+
} else {
240+
cmd.pipeline = renderer.GetGlyphAtlasColorPipeline(opts);
241+
}
249242
cmd.stencil_reference = entity.GetStencilDepth();
250243

251244
return CommonRender(renderer, entity, pass, color, frame_, offset_, atlas,

impeller/entity/shaders/glyph_atlas.frag

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,18 @@
44

55
#include <impeller/types.glsl>
66

7-
uniform sampler2D glyph_atlas_sampler;
7+
uniform f16sampler2D glyph_atlas_sampler;
88

99
uniform FragInfo {
10-
vec4 text_color;
10+
f16vec4 text_color;
1111
}
1212
frag_info;
1313

1414
in vec2 v_uv;
15-
in float v_has_color;
1615

17-
out vec4 frag_color;
16+
out f16vec4 frag_color;
1817

1918
void main() {
20-
vec4 value = texture(glyph_atlas_sampler, v_uv);
21-
if (v_has_color != 1.0) {
22-
frag_color = value.aaaa * frag_info.text_color;
23-
} else {
24-
frag_color = value * frag_info.text_color.a;
25-
}
19+
f16vec4 value = texture(glyph_atlas_sampler, v_uv);
20+
frag_color = value.aaaa * frag_info.text_color;
2621
}

impeller/entity/shaders/glyph_atlas.vert

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@ uniform FrameInfo {
1010
}
1111
frame_info;
1212

13-
in vec4 position;
13+
in highp vec4 position;
1414
in vec2 uv;
15-
in float has_color;
1615

1716
out vec2 v_uv;
18-
out float v_has_color;
1917

2018
void main() {
2119
gl_Position = frame_info.mvp * position;
2220
v_uv = uv;
23-
v_has_color = has_color;
2421
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include <impeller/types.glsl>
6+
7+
uniform f16sampler2D glyph_atlas_sampler;
8+
9+
uniform FragInfo {
10+
f16vec4 text_color;
11+
}
12+
frag_info;
13+
14+
in vec2 v_uv;
15+
16+
out f16vec4 frag_color;
17+
18+
void main() {
19+
f16vec4 value = texture(glyph_atlas_sampler, v_uv);
20+
frag_color = value * frag_info.text_color.aaaa;
21+
}

impeller/entity/shaders/glyph_atlas_sdf.frag

Lines changed: 0 additions & 35 deletions
This file was deleted.

impeller/entity/shaders/glyph_atlas_sdf.vert

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)