Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1297,8 +1297,7 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noa
ORIGIN: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.vert + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas_color.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradient_fill.vert + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/linear_gradient_fill.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/linear_gradient_ssbo_fill.frag + ../../../flutter/LICENSE
Expand Down Expand Up @@ -3891,8 +3890,7 @@ FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalp
FILE: ../../../flutter/impeller/entity/shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.frag
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_sdf.vert
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas_color.frag
FILE: ../../../flutter/impeller/entity/shaders/gradient_fill.vert
FILE: ../../../flutter/impeller/entity/shaders/linear_gradient_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/linear_gradient_ssbo_fill.frag
Expand Down
3 changes: 1 addition & 2 deletions impeller/entity/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ impeller_shaders("entity_shaders") {
"shaders/gaussian_blur/gaussian_blur_noalpha_decal.frag",
"shaders/gaussian_blur/gaussian_blur_noalpha_nodecal.frag",
"shaders/glyph_atlas.frag",
"shaders/glyph_atlas_color.frag",
"shaders/glyph_atlas.vert",
"shaders/glyph_atlas_sdf.frag",
"shaders/glyph_atlas_sdf.vert",
"shaders/gradient_fill.vert",
"shaders/linear_to_srgb_filter.frag",
"shaders/linear_to_srgb_filter.vert",
Expand Down
14 changes: 8 additions & 6 deletions impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ static std::unique_ptr<PipelineT> CreateDefaultPipeline(
ContentContext::ContentContext(std::shared_ptr<Context> context)
: context_(std::move(context)),
tessellator_(std::make_shared<Tessellator>()),
glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()),
alpha_glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()),
color_glyph_atlas_context_(std::make_shared<GlyphAtlasContext>()),
scene_context_(std::make_shared<scene::SceneContext>(context_)) {
if (!context_ || !context_->IsValid()) {
return;
Expand Down Expand Up @@ -286,8 +287,8 @@ ContentContext::ContentContext(std::shared_ptr<Context> context)
CreateDefaultPipeline<SrgbToLinearFilterPipeline>(*context_);
glyph_atlas_pipelines_[{}] =
CreateDefaultPipeline<GlyphAtlasPipeline>(*context_);
glyph_atlas_sdf_pipelines_[{}] =
CreateDefaultPipeline<GlyphAtlasSdfPipeline>(*context_);
glyph_atlas_color_pipelines_[{}] =
CreateDefaultPipeline<GlyphAtlasColorPipeline>(*context_);
geometry_color_pipelines_[{}] =
CreateDefaultPipeline<GeometryColorPipeline>(*context_);
yuv_to_rgb_filter_pipelines_[{}] =
Expand Down Expand Up @@ -380,9 +381,10 @@ std::shared_ptr<Tessellator> ContentContext::GetTessellator() const {
return tessellator_;
}

std::shared_ptr<GlyphAtlasContext> ContentContext::GetGlyphAtlasContext()
const {
return glyph_atlas_context_;
std::shared_ptr<GlyphAtlasContext> ContentContext::GetGlyphAtlasContext(
GlyphAtlas::Type type) const {
return type == GlyphAtlas::Type::kAlphaBitmap ? alpha_glyph_atlas_context_
: color_glyph_atlas_context_;
}

std::shared_ptr<Context> ContentContext::GetContext() const {
Expand Down
19 changes: 10 additions & 9 deletions impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
#include "impeller/entity/conical_gradient_fill.frag.h"
#include "impeller/entity/glyph_atlas.frag.h"
#include "impeller/entity/glyph_atlas.vert.h"
#include "impeller/entity/glyph_atlas_sdf.frag.h"
#include "impeller/entity/glyph_atlas_sdf.vert.h"
#include "impeller/entity/glyph_atlas_color.frag.h"
#include "impeller/entity/gradient_fill.vert.h"
#include "impeller/entity/linear_gradient_fill.frag.h"
#include "impeller/entity/linear_to_srgb_filter.frag.h"
Expand Down Expand Up @@ -173,8 +172,8 @@ using SrgbToLinearFilterPipeline =
SrgbToLinearFilterFragmentShader>;
using GlyphAtlasPipeline =
RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasFragmentShader>;
using GlyphAtlasSdfPipeline =
RenderPipelineT<GlyphAtlasSdfVertexShader, GlyphAtlasSdfFragmentShader>;
using GlyphAtlasColorPipeline =
RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasColorFragmentShader>;
using PorterDuffBlendPipeline =
RenderPipelineT<BlendVertexShader, PorterDuffBlendFragmentShader>;
// Instead of requiring new shaders for clips, the solid fill stages are used
Expand Down Expand Up @@ -473,9 +472,9 @@ class ContentContext {
return GetPipeline(glyph_atlas_pipelines_, opts);
}

std::shared_ptr<Pipeline<PipelineDescriptor>> GetGlyphAtlasSdfPipeline(
std::shared_ptr<Pipeline<PipelineDescriptor>> GetGlyphAtlasColorPipeline(
ContentContextOptions opts) const {
return GetPipeline(glyph_atlas_sdf_pipelines_, opts);
return GetPipeline(glyph_atlas_color_pipelines_, opts);
}

std::shared_ptr<Pipeline<PipelineDescriptor>> GetGeometryColorPipeline(
Expand Down Expand Up @@ -663,7 +662,8 @@ class ContentContext {

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

std::shared_ptr<GlyphAtlasContext> GetGlyphAtlasContext() const;
std::shared_ptr<GlyphAtlasContext> GetGlyphAtlasContext(
GlyphAtlas::Type type) const;

const Capabilities& GetDeviceCapabilities() const;

Expand Down Expand Up @@ -731,7 +731,7 @@ class ContentContext {
mutable Variants<SrgbToLinearFilterPipeline> srgb_to_linear_filter_pipelines_;
mutable Variants<ClipPipeline> clip_pipelines_;
mutable Variants<GlyphAtlasPipeline> glyph_atlas_pipelines_;
mutable Variants<GlyphAtlasSdfPipeline> glyph_atlas_sdf_pipelines_;
mutable Variants<GlyphAtlasColorPipeline> glyph_atlas_color_pipelines_;
mutable Variants<GeometryColorPipeline> geometry_color_pipelines_;
mutable Variants<YUVToRGBFilterPipeline> yuv_to_rgb_filter_pipelines_;
mutable Variants<PorterDuffBlendPipeline> porter_duff_blend_pipelines_;
Expand Down Expand Up @@ -823,7 +823,8 @@ class ContentContext {

bool is_valid_ = false;
std::shared_ptr<Tessellator> tessellator_;
std::shared_ptr<GlyphAtlasContext> glyph_atlas_context_;
std::shared_ptr<GlyphAtlasContext> alpha_glyph_atlas_context_;
std::shared_ptr<GlyphAtlasContext> color_glyph_atlas_context_;
Comment on lines +826 to +827
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could put these into a map or something else. Feels weird to make a second container but might as well. I don't think we'll end up with a third glyph atlas, at least not for a while

std::shared_ptr<scene::SceneContext> scene_context_;
bool wireframe_ = false;

Expand Down
79 changes: 21 additions & 58 deletions impeller/entity/contents/text_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ std::optional<Rect> TextContents::GetCoverage(const Entity& entity) const {
return bounds->TransformBounds(entity.GetTransformation());
}

template <class TPipeline>
static bool CommonRender(
const ContentContext& renderer,
const Entity& entity,
Expand All @@ -85,15 +84,6 @@ static bool CommonRender(
std::shared_ptr<GlyphAtlas>
atlas, // NOLINT(performance-unnecessary-value-param)
Command& cmd) {
using VS = typename TPipeline::VertexShader;
using FS = typename TPipeline::FragmentShader;

// Common vertex uniforms for all glyphs.
typename VS::FrameInfo frame_info;

frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize());
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));

SamplerDescriptor sampler_desc;
if (entity.GetTransformation().IsTranslationScaleOnly()) {
sampler_desc.min_filter = MinMagFilter::kNearest;
Expand All @@ -109,11 +99,17 @@ static bool CommonRender(
}
sampler_desc.mip_filter = MipFilter::kNearest;

typename FS::FragInfo frag_info;
using VS = GlyphAtlasPipeline::VertexShader;
using FS = GlyphAtlasPipeline::FragmentShader;

VS::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize());
VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info));

FS::FragInfo frag_info;
frag_info.text_color = ToVector(color.Premultiply());
FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info));

// Common fragment uniforms for all glyphs.
FS::BindGlyphAtlasSampler(
cmd, // command
atlas->GetTexture(), // texture
Expand Down Expand Up @@ -183,7 +179,7 @@ static bool CommonRender(
.Round();

for (const auto& point : unit_points) {
typename VS::PerVertexData vtx;
VS::PerVertexData vtx;

if (entity.GetTransformation().IsTranslationScaleOnly()) {
// Rouding up here prevents the bounds from becoming 1 pixel too small
Expand All @@ -199,19 +195,13 @@ static bool CommonRender(
point * glyph_position.glyph.bounds.size);
}
vtx.uv = uv_origin + point * uv_size;

if constexpr (std::is_same_v<TPipeline, GlyphAtlasPipeline>) {
vtx.has_color =
glyph_position.glyph.type == Glyph::Type::kBitmap ? 1.0 : 0.0;
}

vertex_builder.AppendVertex(std::move(vtx));
vertex_builder.AppendVertex(vtx);
}
}
}
auto vertex_buffer =
vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer());
cmd.BindVertices(std::move(vertex_buffer));
cmd.BindVertices(vertex_buffer);

if (!pass.AddCommand(cmd)) {
return false;
Expand All @@ -220,30 +210,6 @@ static bool CommonRender(
return true;
}

bool TextContents::RenderSdf(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
auto atlas =
ResolveAtlas(GlyphAtlas::Type::kSignedDistanceField,
renderer.GetGlyphAtlasContext(), renderer.GetContext());

if (!atlas || !atlas->IsValid()) {
VALIDATION_LOG << "Cannot render glyphs without prepared atlas.";
return false;
}

// Information shared by all glyph draw calls.
Command cmd;
cmd.label = "TextFrameSDF";
auto opts = OptionsFromPassAndEntity(pass, entity);
opts.primitive_type = PrimitiveType::kTriangle;
cmd.pipeline = renderer.GetGlyphAtlasSdfPipeline(opts);
cmd.stencil_reference = entity.GetStencilDepth();

return CommonRender<GlyphAtlasSdfPipeline>(renderer, entity, pass, GetColor(),
frame_, offset_, atlas, cmd);
}

bool TextContents::Render(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
Expand All @@ -252,16 +218,9 @@ bool TextContents::Render(const ContentContext& renderer,
return true;
}

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

if (!atlas || !atlas->IsValid()) {
VALIDATION_LOG << "Cannot render glyphs without prepared atlas.";
Expand All @@ -273,11 +232,15 @@ bool TextContents::Render(const ContentContext& renderer,
cmd.label = "TextFrame";
auto opts = OptionsFromPassAndEntity(pass, entity);
opts.primitive_type = PrimitiveType::kTriangle;
cmd.pipeline = renderer.GetGlyphAtlasPipeline(opts);
if (type == GlyphAtlas::Type::kAlphaBitmap) {
cmd.pipeline = renderer.GetGlyphAtlasPipeline(opts);
} else {
cmd.pipeline = renderer.GetGlyphAtlasColorPipeline(opts);
}
cmd.stencil_reference = entity.GetStencilDepth();

return CommonRender<GlyphAtlasPipeline>(renderer, entity, pass, color, frame_,
offset_, atlas, cmd);
return CommonRender(renderer, entity, pass, color, frame_, offset_, atlas,
cmd);
}

} // namespace impeller
5 changes: 0 additions & 5 deletions impeller/entity/contents/text_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ class TextContents final : public Contents {
const Entity& entity,
RenderPass& pass) const override;

// TODO(dnfield): remove this https://github.com/flutter/flutter/issues/111640
bool RenderSdf(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const;

private:
TextFrame frame_;
Color color_;
Expand Down
28 changes: 0 additions & 28 deletions impeller/entity/entity_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2151,34 +2151,6 @@ TEST_P(EntityTest, TTTBlendColor) {
}
}

TEST_P(EntityTest, SdfText) {
auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
SkFont font;
font.setSize(30);
auto blob = SkTextBlob::MakeFromString(
"the quick brown fox jumped over the lazy dog (but with sdf).", font);
auto frame = TextFrameFromTextBlob(blob);
auto lazy_glyph_atlas = std::make_shared<LazyGlyphAtlas>();
lazy_glyph_atlas->AddTextFrame(frame);

EXPECT_FALSE(lazy_glyph_atlas->HasColor());

auto text_contents = std::make_shared<TextContents>();
text_contents->SetTextFrame(frame);
text_contents->SetGlyphAtlas(std::move(lazy_glyph_atlas));
text_contents->SetColor(Color(1.0, 0.0, 0.0, 1.0));
Entity entity;
entity.SetTransformation(
Matrix::MakeTranslation(Vector3{200.0, 200.0, 0.0}) *
Matrix::MakeScale(GetContentScale()));
entity.SetContents(text_contents);

// Force SDF rendering.
return text_contents->RenderSdf(context, entity, pass);
};
ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, AtlasContentsSubAtlas) {
auto boston = CreateTextureForFixture("boston.jpg");

Expand Down
15 changes: 5 additions & 10 deletions impeller/entity/shaders/glyph_atlas.frag
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,18 @@

#include <impeller/types.glsl>

uniform sampler2D glyph_atlas_sampler;
uniform f16sampler2D glyph_atlas_sampler;

uniform FragInfo {
vec4 text_color;
f16vec4 text_color;
}
frag_info;

in vec2 v_uv;
in float v_has_color;

out vec4 frag_color;
out f16vec4 frag_color;

void main() {
vec4 value = texture(glyph_atlas_sampler, v_uv);
if (v_has_color != 1.0) {
frag_color = value.aaaa * frag_info.text_color;
} else {
frag_color = value * frag_info.text_color.a;
}
f16vec4 value = texture(glyph_atlas_sampler, v_uv);
frag_color = value.aaaa * frag_info.text_color;
}
5 changes: 1 addition & 4 deletions impeller/entity/shaders/glyph_atlas.vert
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,12 @@ uniform FrameInfo {
}
frame_info;

in vec4 position;
in highp vec4 position;
in vec2 uv;
in float has_color;

out vec2 v_uv;
out float v_has_color;

void main() {
gl_Position = frame_info.mvp * position;
v_uv = uv;
v_has_color = has_color;
}
21 changes: 21 additions & 0 deletions impeller/entity/shaders/glyph_atlas_color.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2013 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.

#include <impeller/types.glsl>

uniform f16sampler2D glyph_atlas_sampler;

uniform FragInfo {
f16vec4 text_color;
}
frag_info;

in vec2 v_uv;

out f16vec4 frag_color;

void main() {
f16vec4 value = texture(glyph_atlas_sampler, v_uv);
frag_color = value * frag_info.text_color.aaaa;
}
Loading