diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 82b2e704efec9..ed9bb006690c4 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -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 @@ -3898,8 +3897,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 diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 91ffdae65d58b..0cfde08d51875 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -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", diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 48257e494006e..4503b40cdbe6f 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -164,7 +164,8 @@ static std::unique_ptr CreateDefaultPipeline( ContentContext::ContentContext(std::shared_ptr context) : context_(std::move(context)), tessellator_(std::make_shared()), - glyph_atlas_context_(std::make_shared()), + alpha_glyph_atlas_context_(std::make_shared()), + color_glyph_atlas_context_(std::make_shared()), scene_context_(std::make_shared(context_)) { if (!context_ || !context_->IsValid()) { return; @@ -286,6 +287,8 @@ ContentContext::ContentContext(std::shared_ptr context) CreateDefaultPipeline(*context_); glyph_atlas_pipelines_[{}] = CreateDefaultPipeline(*context_); + glyph_atlas_color_pipelines_[{}] = + CreateDefaultPipeline(*context_); geometry_color_pipelines_[{}] = CreateDefaultPipeline(*context_); yuv_to_rgb_filter_pipelines_[{}] = @@ -378,9 +381,10 @@ std::shared_ptr ContentContext::GetTessellator() const { return tessellator_; } -std::shared_ptr ContentContext::GetGlyphAtlasContext() - const { - return glyph_atlas_context_; +std::shared_ptr ContentContext::GetGlyphAtlasContext( + GlyphAtlas::Type type) const { + return type == GlyphAtlas::Type::kAlphaBitmap ? alpha_glyph_atlas_context_ + : color_glyph_atlas_context_; } std::shared_ptr ContentContext::GetContext() const { diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 971b0cc4b082b..5042ff54ff187 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -32,6 +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_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" @@ -171,6 +172,8 @@ using SrgbToLinearFilterPipeline = SrgbToLinearFilterFragmentShader>; using GlyphAtlasPipeline = RenderPipelineT; +using GlyphAtlasColorPipeline = + RenderPipelineT; using PorterDuffBlendPipeline = RenderPipelineT; // Instead of requiring new shaders for clips, the solid fill stages are used @@ -469,6 +472,11 @@ class ContentContext { return GetPipeline(glyph_atlas_pipelines_, opts); } + std::shared_ptr> GetGlyphAtlasColorPipeline( + ContentContextOptions opts) const { + return GetPipeline(glyph_atlas_color_pipelines_, opts); + } + std::shared_ptr> GetGeometryColorPipeline( ContentContextOptions opts) const { return GetPipeline(geometry_color_pipelines_, opts); @@ -654,7 +662,8 @@ class ContentContext { std::shared_ptr GetContext() const; - std::shared_ptr GetGlyphAtlasContext() const; + std::shared_ptr GetGlyphAtlasContext( + GlyphAtlas::Type type) const; const Capabilities& GetDeviceCapabilities() const; @@ -722,6 +731,7 @@ class ContentContext { mutable Variants srgb_to_linear_filter_pipelines_; mutable Variants clip_pipelines_; mutable Variants glyph_atlas_pipelines_; + mutable Variants glyph_atlas_color_pipelines_; mutable Variants geometry_color_pipelines_; mutable Variants yuv_to_rgb_filter_pipelines_; mutable Variants porter_duff_blend_pipelines_; @@ -813,7 +823,8 @@ class ContentContext { bool is_valid_ = false; std::shared_ptr tessellator_; - std::shared_ptr glyph_atlas_context_; + std::shared_ptr alpha_glyph_atlas_context_; + std::shared_ptr color_glyph_atlas_context_; std::shared_ptr scene_context_; bool wireframe_ = false; diff --git a/impeller/entity/contents/text_contents.cc b/impeller/entity/contents/text_contents.cc index 1fba560b176f2..dc5a04096c9af 100644 --- a/impeller/entity/contents/text_contents.cc +++ b/impeller/entity/contents/text_contents.cc @@ -112,7 +112,6 @@ static bool CommonRender( 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 @@ -198,9 +197,6 @@ static bool CommonRender( point * glyph_position.glyph.bounds.size); } vtx.uv = uv_origin + point * uv_size; - vtx.has_color = - glyph_position.glyph.type == Glyph::Type::kBitmap ? 1.0 : 0.0; - vertex_builder.AppendVertex(vtx); } } @@ -224,16 +220,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."; @@ -245,7 +234,11 @@ 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(renderer, entity, pass, color, frame_, offset_, atlas, diff --git a/impeller/entity/shaders/glyph_atlas.frag b/impeller/entity/shaders/glyph_atlas.frag index adb1a48f507e7..21b26c976b646 100644 --- a/impeller/entity/shaders/glyph_atlas.frag +++ b/impeller/entity/shaders/glyph_atlas.frag @@ -4,23 +4,18 @@ #include -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; } diff --git a/impeller/entity/shaders/glyph_atlas.vert b/impeller/entity/shaders/glyph_atlas.vert index c15ceddaf25c0..3cf2ce7d88854 100644 --- a/impeller/entity/shaders/glyph_atlas.vert +++ b/impeller/entity/shaders/glyph_atlas.vert @@ -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; } diff --git a/impeller/entity/shaders/glyph_atlas_color.frag b/impeller/entity/shaders/glyph_atlas_color.frag new file mode 100644 index 0000000000000..ded0a3d618e3d --- /dev/null +++ b/impeller/entity/shaders/glyph_atlas_color.frag @@ -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 + +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; +} diff --git a/impeller/entity/shaders/glyph_atlas_sdf.frag b/impeller/entity/shaders/glyph_atlas_sdf.frag deleted file mode 100644 index 2c45e7072c385..0000000000000 --- a/impeller/entity/shaders/glyph_atlas_sdf.frag +++ /dev/null @@ -1,35 +0,0 @@ -// 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 - -uniform sampler2D glyph_atlas_sampler; - -uniform FragInfo { - vec4 text_color; -} -frag_info; - -in vec2 v_uv; - -out vec4 frag_color; - -void main() { - // Inspired by Metal by Example's SDF text rendering shader: - // https://github.com/metal-by-example/sample-code/blob/master/objc/12-TextRendering/TextRendering/Shaders.metal - - // Outline of glyph is the isocontour with value 50% - float edge_distance = 0.5; - // Sample the signed-distance field to find distance from this fragment to the - // glyph outline - float sample_distance = texture(glyph_atlas_sampler, v_uv).a; - // Use local automatic gradients to find anti-aliased anisotropic edge width, - // cf. Gustavson 2012 - float edge_width = length(vec2(dFdx(sample_distance), dFdy(sample_distance))); - // Smooth the glyph edge by interpolating across the boundary in a band with - // the width determined above - float insideness = smoothstep(edge_distance - edge_width, - edge_distance + edge_width, sample_distance); - frag_color = frag_info.text_color * insideness; -} diff --git a/impeller/entity/shaders/glyph_atlas_sdf.vert b/impeller/entity/shaders/glyph_atlas_sdf.vert deleted file mode 100644 index f859eea762ab6..0000000000000 --- a/impeller/entity/shaders/glyph_atlas_sdf.vert +++ /dev/null @@ -1,22 +0,0 @@ -// 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 - -#include - -uniform FrameInfo { - mat4 mvp; -} -frame_info; - -in vec4 position; -in vec2 uv; - -out vec2 v_uv; - -void main() { - gl_Position = frame_info.mvp * position; - v_uv = uv; -} diff --git a/impeller/tools/malioc.json b/impeller/tools/malioc.json index e9e21d268c9d4..0ea54a4a9d0c4 100644 --- a/impeller/tools/malioc.json +++ b/impeller/tools/malioc.json @@ -7431,15 +7431,16 @@ "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "varying" + "varying", + "texture" ], "longest_path_cycles": [ - 0.078125, - 0.0625, - 0.078125, + 0.03125, + 0.03125, + 0.03125, 0.0, 0.0, - 0.375, + 0.25, 0.25 ], "pipelines": [ @@ -7452,27 +7453,29 @@ "texture" ], "shortest_path_bound_pipelines": [ - "varying" + "varying", + "texture" ], "shortest_path_cycles": [ - 0.0625, - 0.0625, - 0.046875, + 0.03125, + 0.03125, 0.0, 0.0, - 0.375, + 0.0, + 0.25, 0.25 ], "total_bound_pipelines": [ - "varying" + "varying", + "texture" ], "total_cycles": [ - 0.078125, - 0.0625, - 0.078125, + 0.03125, + 0.03125, + 0.03125, 0.0, 0.0, - 0.375, + 0.25, 0.25 ] }, @@ -7518,10 +7521,11 @@ 1.0 ], "total_bound_pipelines": [ - "arithmetic" + "load_store", + "texture" ], "total_cycles": [ - 1.3333333730697632, + 0.6666666865348816, 1.0, 1.0 ] @@ -7541,16 +7545,16 @@ "type": "Vertex", "variants": { "Position": { - "fp16_arithmetic": 88, + "fp16_arithmetic": 0, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ "load_store" ], "longest_path_cycles": [ - 0.140625, - 0.140625, - 0.046875, + 0.265625, + 0.265625, + 0.0, 0.0, 2.0, 0.0 @@ -7567,9 +7571,9 @@ "load_store" ], "shortest_path_cycles": [ - 0.140625, - 0.140625, - 0.046875, + 0.265625, + 0.265625, + 0.0, 0.0, 2.0, 0.0 @@ -7578,9 +7582,9 @@ "load_store" ], "total_cycles": [ - 0.140625, - 0.140625, - 0.046875, + 0.265625, + 0.265625, + 0.0, 0.0, 2.0, 0.0 @@ -7599,11 +7603,11 @@ "load_store" ], "longest_path_cycles": [ - 0.03125, 0.0, - 0.03125, 0.0, - 4.0, + 0.0, + 0.0, + 3.0, 0.0 ], "pipelines": [ @@ -7618,29 +7622,29 @@ "load_store" ], "shortest_path_cycles": [ - 0.03125, 0.0, - 0.03125, 0.0, - 4.0, + 0.0, + 0.0, + 3.0, 0.0 ], "total_bound_pipelines": [ "load_store" ], "total_cycles": [ - 0.03125, 0.0, - 0.03125, 0.0, - 4.0, + 0.0, + 0.0, + 3.0, 0.0 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, "uniform_registers_used": 8, - "work_registers_used": 9 + "work_registers_used": 6 } } }, @@ -7658,7 +7662,7 @@ ], "longest_path_cycles": [ 2.9700000286102295, - 7.0, + 5.0, 0.0 ], "pipelines": [ @@ -7671,7 +7675,7 @@ ], "shortest_path_cycles": [ 2.9700000286102295, - 7.0, + 5.0, 0.0 ], "total_bound_pipelines": [ @@ -7679,7 +7683,7 @@ ], "total_cycles": [ 3.0, - 7.0, + 5.0, 0.0 ] }, @@ -7690,10 +7694,10 @@ } } }, - "flutter/impeller/entity/gles/glyph_atlas_sdf.frag.gles": { + "flutter/impeller/entity/gles/glyph_atlas_color.frag.gles": { "Mali-G78": { "core": "Mali-G78", - "filename": "flutter/impeller/entity/gles/glyph_atlas_sdf.frag.gles", + "filename": "flutter/impeller/entity/gles/glyph_atlas_color.frag.gles", "has_side_effects": false, "has_uniform_computation": false, "modifies_coverage": false, @@ -7703,19 +7707,18 @@ "uses_late_zs_update": false, "variants": { "Main": { - "fp16_arithmetic": 77, + "fp16_arithmetic": 100, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "arith_total", - "arith_fma", - "arith_sfu" + "varying", + "texture" ], "longest_path_cycles": [ - 0.3125, - 0.3125, - 0.046875, - 0.3125, + 0.03125, + 0.03125, + 0.03125, + 0.0, 0.0, 0.25, 0.25 @@ -7730,29 +7733,27 @@ "texture" ], "shortest_path_bound_pipelines": [ - "arith_total", - "arith_fma", - "arith_sfu" + "varying", + "texture" ], "shortest_path_cycles": [ - 0.3125, - 0.3125, - 0.015625, - 0.3125, + 0.03125, + 0.03125, + 0.0, + 0.0, 0.0, 0.25, 0.25 ], "total_bound_pipelines": [ - "arith_total", - "arith_fma", - "arith_sfu" + "varying", + "texture" ], "total_cycles": [ - 0.3125, - 0.3125, - 0.046875, - 0.3125, + 0.03125, + 0.03125, + 0.03125, + 0.0, 0.0, 0.25, 0.25 @@ -7760,14 +7761,14 @@ }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 8, - "work_registers_used": 20 + "uniform_registers_used": 4, + "work_registers_used": 19 } } }, "Mali-T880": { "core": "Mali-T880", - "filename": "flutter/impeller/entity/gles/glyph_atlas_sdf.frag.gles", + "filename": "flutter/impeller/entity/gles/glyph_atlas_color.frag.gles", "has_uniform_computation": false, "type": "Fragment", "variants": { @@ -7775,194 +7776,42 @@ "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "arithmetic" - ], - "longest_path_cycles": [ - 3.299999952316284, - 1.0, - 3.0 - ], - "pipelines": [ "arithmetic", "load_store", "texture" ], - "shortest_path_bound_pipelines": [ - "arithmetic" - ], - "shortest_path_cycles": [ - 3.299999952316284, + "longest_path_cycles": [ 1.0, - 3.0 - ], - "total_bound_pipelines": [ - "arithmetic" - ], - "total_cycles": [ - 3.6666667461395264, 1.0, - 3.0 - ] - }, - "thread_occupancy": 100, - "uniform_registers_used": 1, - "work_registers_used": 2 - } - } - } - }, - "flutter/impeller/entity/gles/glyph_atlas_sdf.vert.gles": { - "Mali-G78": { - "core": "Mali-G78", - "filename": "flutter/impeller/entity/gles/glyph_atlas_sdf.vert.gles", - "has_uniform_computation": false, - "type": "Vertex", - "variants": { - "Position": { - "fp16_arithmetic": 88, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "load_store" - ], - "longest_path_cycles": [ - 0.140625, - 0.140625, - 0.046875, - 0.0, - 2.0, - 0.0 + 1.0 ], "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", + "arithmetic", "load_store", "texture" ], "shortest_path_bound_pipelines": [ - "load_store" - ], - "shortest_path_cycles": [ - 0.140625, - 0.140625, - 0.046875, - 0.0, - 2.0, - 0.0 - ], - "total_bound_pipelines": [ - "load_store" - ], - "total_cycles": [ - 0.140625, - 0.140625, - 0.046875, - 0.0, - 2.0, - 0.0 - ] - }, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 16, - "work_registers_used": 32 - }, - "Varying": { - "fp16_arithmetic": null, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "load_store" - ], - "longest_path_cycles": [ - 0.0, - 0.0, - 0.0, - 0.0, - 3.0, - 0.0 - ], - "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", + "arithmetic", "load_store", "texture" ], - "shortest_path_bound_pipelines": [ - "load_store" - ], "shortest_path_cycles": [ - 0.0, - 0.0, - 0.0, - 0.0, - 3.0, - 0.0 + 1.0, + 1.0, + 1.0 ], "total_bound_pipelines": [ - "load_store" - ], - "total_cycles": [ - 0.0, - 0.0, - 0.0, - 0.0, - 3.0, - 0.0 - ] - }, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 8, - "work_registers_used": 6 - } - } - }, - "Mali-T880": { - "core": "Mali-T880", - "filename": "flutter/impeller/entity/gles/glyph_atlas_sdf.vert.gles", - "has_uniform_computation": false, - "type": "Vertex", - "variants": { - "Main": { - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "load_store" - ], - "longest_path_cycles": [ - 2.9700000286102295, - 5.0, - 0.0 - ], - "pipelines": [ - "arithmetic", "load_store", "texture" ], - "shortest_path_bound_pipelines": [ - "load_store" - ], - "shortest_path_cycles": [ - 2.9700000286102295, - 5.0, - 0.0 - ], - "total_bound_pipelines": [ - "load_store" - ], "total_cycles": [ - 3.0, - 5.0, - 0.0 + 0.6666666865348816, + 1.0, + 1.0 ] }, "thread_occupancy": 100, - "uniform_registers_used": 4, + "uniform_registers_used": 1, "work_registers_used": 2 } } @@ -11354,15 +11203,16 @@ "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "varying" + "varying", + "texture" ], "longest_path_cycles": [ - 0.0625, - 0.0625, - 0.046875, + 0.03125, + 0.03125, 0.0, 0.0, - 0.375, + 0.0, + 0.25, 0.25 ], "pipelines": [ @@ -11375,34 +11225,36 @@ "texture" ], "shortest_path_bound_pipelines": [ - "varying" + "varying", + "texture" ], "shortest_path_cycles": [ - 0.0625, - 0.0625, - 0.046875, + 0.03125, + 0.03125, 0.0, 0.0, - 0.375, + 0.0, + 0.25, 0.25 ], "total_bound_pipelines": [ - "varying" + "varying", + "texture" ], "total_cycles": [ - 0.0625, - 0.0625, - 0.046875, + 0.03125, + 0.03125, 0.0, 0.0, - 0.375, + 0.0, + 0.25, 0.25 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, "uniform_registers_used": 6, - "work_registers_used": 7 + "work_registers_used": 6 } } } @@ -11415,16 +11267,16 @@ "type": "Vertex", "variants": { "Position": { - "fp16_arithmetic": 100, + "fp16_arithmetic": 0, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ "load_store" ], "longest_path_cycles": [ - 0.125, - 0.125, - 0.0625, + 0.25, + 0.25, + 0.0, 0.0, 2.0, 0.0 @@ -11441,9 +11293,9 @@ "load_store" ], "shortest_path_cycles": [ - 0.125, - 0.125, - 0.0625, + 0.25, + 0.25, + 0.0, 0.0, 2.0, 0.0 @@ -11452,9 +11304,9 @@ "load_store" ], "total_cycles": [ - 0.125, - 0.125, - 0.0625, + 0.25, + 0.25, + 0.0, 0.0, 2.0, 0.0 @@ -11462,7 +11314,7 @@ }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 16, + "uniform_registers_used": 24, "work_registers_used": 32 }, "Varying": { @@ -11477,7 +11329,7 @@ 0.0, 0.0, 0.0, - 4.0, + 3.0, 0.0 ], "pipelines": [ @@ -11496,7 +11348,7 @@ 0.0, 0.0, 0.0, - 4.0, + 3.0, 0.0 ], "total_bound_pipelines": [ @@ -11507,22 +11359,22 @@ 0.0, 0.0, 0.0, - 4.0, + 3.0, 0.0 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 16, - "work_registers_used": 7 + "uniform_registers_used": 24, + "work_registers_used": 6 } } } }, - "flutter/impeller/entity/glyph_atlas_sdf.frag.vkspv": { + "flutter/impeller/entity/glyph_atlas_color.frag.vkspv": { "Mali-G78": { "core": "Mali-G78", - "filename": "flutter/impeller/entity/glyph_atlas_sdf.frag.vkspv", + "filename": "flutter/impeller/entity/glyph_atlas_color.frag.vkspv", "has_side_effects": false, "has_uniform_computation": true, "modifies_coverage": false, @@ -11532,87 +11384,21 @@ "uses_late_zs_update": false, "variants": { "Main": { - "fp16_arithmetic": 72, + "fp16_arithmetic": 100, "has_stack_spilling": false, "performance": { "longest_path_bound_pipelines": [ - "arith_total", - "arith_sfu" - ], - "longest_path_cycles": [ - 0.3125, - 0.25, - 0.015625, - 0.3125, - 0.0, - 0.25, - 0.25 - ], - "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", - "load_store", "varying", "texture" ], - "shortest_path_bound_pipelines": [ - "arith_total", - "arith_sfu" - ], - "shortest_path_cycles": [ - 0.3125, - 0.25, - 0.015625, - 0.3125, + "longest_path_cycles": [ + 0.03125, + 0.03125, + 0.0, 0.0, - 0.25, - 0.25 - ], - "total_bound_pipelines": [ - "arith_total", - "arith_sfu" - ], - "total_cycles": [ - 0.3125, - 0.25, - 0.015625, - 0.3125, 0.0, 0.25, 0.25 - ] - }, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 6, - "work_registers_used": 6 - } - } - } - }, - "flutter/impeller/entity/glyph_atlas_sdf.vert.vkspv": { - "Mali-G78": { - "core": "Mali-G78", - "filename": "flutter/impeller/entity/glyph_atlas_sdf.vert.vkspv", - "has_uniform_computation": true, - "type": "Vertex", - "variants": { - "Position": { - "fp16_arithmetic": 100, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "load_store" - ], - "longest_path_cycles": [ - 0.125, - 0.125, - 0.0625, - 0.0, - 2.0, - 0.0 ], "pipelines": [ "arith_total", @@ -11620,86 +11406,40 @@ "arith_cvt", "arith_sfu", "load_store", + "varying", "texture" ], "shortest_path_bound_pipelines": [ - "load_store" - ], - "shortest_path_cycles": [ - 0.125, - 0.125, - 0.0625, - 0.0, - 2.0, - 0.0 - ], - "total_bound_pipelines": [ - "load_store" - ], - "total_cycles": [ - 0.125, - 0.125, - 0.0625, - 0.0, - 2.0, - 0.0 - ] - }, - "stack_spill_bytes": 0, - "thread_occupancy": 100, - "uniform_registers_used": 16, - "work_registers_used": 32 - }, - "Varying": { - "fp16_arithmetic": null, - "has_stack_spilling": false, - "performance": { - "longest_path_bound_pipelines": [ - "load_store" - ], - "longest_path_cycles": [ - 0.0, - 0.0, - 0.0, - 0.0, - 3.0, - 0.0 - ], - "pipelines": [ - "arith_total", - "arith_fma", - "arith_cvt", - "arith_sfu", - "load_store", + "varying", "texture" ], - "shortest_path_bound_pipelines": [ - "load_store" - ], "shortest_path_cycles": [ + 0.03125, + 0.03125, 0.0, 0.0, 0.0, - 0.0, - 3.0, - 0.0 + 0.25, + 0.25 ], "total_bound_pipelines": [ - "load_store" + "varying", + "texture" ], "total_cycles": [ + 0.03125, + 0.03125, 0.0, 0.0, 0.0, - 0.0, - 3.0, - 0.0 + 0.25, + 0.25 ] }, "stack_spill_bytes": 0, "thread_occupancy": 100, - "uniform_registers_used": 16, - "work_registers_used": 6 + "uniform_registers_used": 4, + "work_registers_used": 4 } } } diff --git a/impeller/typographer/lazy_glyph_atlas.cc b/impeller/typographer/lazy_glyph_atlas.cc index 3e415716a528c..d88f0d9b6c577 100644 --- a/impeller/typographer/lazy_glyph_atlas.cc +++ b/impeller/typographer/lazy_glyph_atlas.cc @@ -18,12 +18,11 @@ LazyGlyphAtlas::~LazyGlyphAtlas() = default; void LazyGlyphAtlas::AddTextFrame(const TextFrame& frame) { FML_DCHECK(atlas_map_.empty()); - has_color_ |= frame.HasColor(); - frames_.emplace_back(frame); -} - -bool LazyGlyphAtlas::HasColor() const { - return has_color_; + if (frame.GetAtlasType() == GlyphAtlas::Type::kAlphaBitmap) { + alpha_frames_.emplace_back(frame); + } else { + color_frames_.emplace_back(frame); + } } std::shared_ptr LazyGlyphAtlas::CreateOrGetGlyphAtlas( @@ -42,11 +41,13 @@ std::shared_ptr LazyGlyphAtlas::CreateOrGetGlyphAtlas( return nullptr; } size_t i = 0; + auto frames = + type == GlyphAtlas::Type::kAlphaBitmap ? alpha_frames_ : color_frames_; TextRenderContext::FrameIterator iterator = [&]() -> const TextFrame* { - if (i >= frames_.size()) { + if (i >= frames.size()) { return nullptr; } - const auto& result = frames_[i]; + const auto& result = frames[i]; i++; return &result; }; diff --git a/impeller/typographer/lazy_glyph_atlas.h b/impeller/typographer/lazy_glyph_atlas.h index 841bb4f2e0e46..067601e65e64f 100644 --- a/impeller/typographer/lazy_glyph_atlas.h +++ b/impeller/typographer/lazy_glyph_atlas.h @@ -26,13 +26,11 @@ class LazyGlyphAtlas { std::shared_ptr atlas_context, std::shared_ptr context) const; - bool HasColor() const; - private: - std::vector frames_; + std::vector alpha_frames_; + std::vector color_frames_; mutable std::unordered_map> atlas_map_; - bool has_color_ = false; FML_DISALLOW_COPY_AND_ASSIGN(LazyGlyphAtlas); }; diff --git a/impeller/typographer/text_frame.cc b/impeller/typographer/text_frame.cc index d7c241b899283..ed3c97cc82b3e 100644 --- a/impeller/typographer/text_frame.cc +++ b/impeller/typographer/text_frame.cc @@ -42,8 +42,9 @@ const std::vector& TextFrame::GetRuns() const { return runs_; } -bool TextFrame::HasColor() const { - return has_color_; +GlyphAtlas::Type TextFrame::GetAtlasType() const { + return has_color_ ? GlyphAtlas::Type::kColorBitmap + : GlyphAtlas::Type::kAlphaBitmap; } bool TextFrame::MaybeHasOverlapping() const { diff --git a/impeller/typographer/text_frame.h b/impeller/typographer/text_frame.h index e43af08b2d6ea..a47e4c0e2252a 100644 --- a/impeller/typographer/text_frame.h +++ b/impeller/typographer/text_frame.h @@ -5,6 +5,7 @@ #pragma once #include "flutter/fml/macros.h" +#include "impeller/typographer/glyph_atlas.h" #include "impeller/typographer/text_run.h" namespace impeller { @@ -63,8 +64,8 @@ class TextFrame { bool MaybeHasOverlapping() const; //---------------------------------------------------------------------------- - /// @brief Whether any run in this frame has color. - bool HasColor() const; + /// @brief The type of atlas this run should be emplaced in. + GlyphAtlas::Type GetAtlasType() const; private: std::vector runs_; diff --git a/impeller/typographer/typographer_unittests.cc b/impeller/typographer/typographer_unittests.cc index 445cc283fe6c7..31c649fab0d4c 100644 --- a/impeller/typographer/typographer_unittests.cc +++ b/impeller/typographer/typographer_unittests.cc @@ -7,6 +7,7 @@ #include "impeller/typographer/backends/skia/text_frame_skia.h" #include "impeller/typographer/backends/skia/text_render_context_skia.h" #include "impeller/typographer/lazy_glyph_atlas.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkTextBlob.h" @@ -91,22 +92,28 @@ TEST_P(TypographerTest, LazyAtlasTracksColor) { ASSERT_TRUE(blob); auto frame = TextFrameFromTextBlob(blob); - ASSERT_FALSE(frame.HasColor()); + ASSERT_FALSE(frame.GetAtlasType() == GlyphAtlas::Type::kColorBitmap); LazyGlyphAtlas lazy_atlas; - ASSERT_FALSE(lazy_atlas.HasColor()); lazy_atlas.AddTextFrame(frame); - ASSERT_FALSE(lazy_atlas.HasColor()); - frame = TextFrameFromTextBlob(SkTextBlob::MakeFromString("😀 ", emoji_font)); - ASSERT_TRUE(frame.HasColor()); + ASSERT_TRUE(frame.GetAtlasType() == GlyphAtlas::Type::kColorBitmap); lazy_atlas.AddTextFrame(frame); - ASSERT_TRUE(lazy_atlas.HasColor()); + // Creates different atlases for color and alpha bitmap. + auto color_context = std::make_shared(); + auto bitmap_context = std::make_shared(); + auto color_atlas = lazy_atlas.CreateOrGetGlyphAtlas( + GlyphAtlas::Type::kColorBitmap, color_context, GetContext()); + + auto bitmap_atlas = lazy_atlas.CreateOrGetGlyphAtlas( + GlyphAtlas::Type::kAlphaBitmap, bitmap_context, GetContext()); + + ASSERT_FALSE(color_atlas == bitmap_atlas); } TEST_P(TypographerTest, GlyphAtlasWithOddUniqueGlyphSize) {