diff --git a/display_list/BUILD.gn b/display_list/BUILD.gn index dd6aba8d3814b..614ff1260f65b 100644 --- a/display_list/BUILD.gn +++ b/display_list/BUILD.gn @@ -131,6 +131,7 @@ if (enable_unittests) { ":display_list", ":display_list_fixtures", "//flutter/display_list/testing:display_list_testing", + "//flutter/impeller/typographer/backends/skia:typographer_skia_backend", "//flutter/testing", "//flutter/testing:skia", ] diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index ef423aa7f29f8..3d27a6a378837 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -22,6 +22,7 @@ #include "flutter/testing/display_list_testing.h" #include "flutter/testing/testing.h" +#include "impeller/typographer/backends/skia/text_frame_skia.h" #include "third_party/skia/include/core/SkBBHFactory.h" #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkPictureRecorder.h" @@ -4331,5 +4332,30 @@ TEST_F(DisplayListTest, DrawDisplayListForwardsBackdropFlag) { EXPECT_TRUE(parent_dl->root_has_backdrop_filter()); } +TEST_F(DisplayListTest, TextFrameOpacityPeephole) { + // Single character can have opacity peephole applied. + { + std::string message = "A"; + sk_sp blob = CreateTextBlob(message); + auto frame = impeller::MakeTextFrameFromTextBlobSkia(blob); + DisplayListBuilder builder; + builder.DrawTextFrame(frame, 0, 0, {}); + auto dl = builder.Build(); + EXPECT_TRUE(dl->can_apply_group_opacity()); + } + + // Multiple characters cannot have opacity peephole applied. + { + std::string message = "ABC"; + sk_sp blob = CreateTextBlob(message); + + auto frame = impeller::MakeTextFrameFromTextBlobSkia(blob); + DisplayListBuilder builder; + builder.DrawTextFrame(frame, 0, 0, {}); + auto dl = builder.Build(); + EXPECT_FALSE(dl->can_apply_group_opacity()); + } +} + } // namespace testing } // namespace flutter diff --git a/display_list/dl_builder.cc b/display_list/dl_builder.cc index 944219c974cf1..bacacb2454945 100644 --- a/display_list/dl_builder.cc +++ b/display_list/dl_builder.cc @@ -1698,7 +1698,11 @@ void DisplayListBuilder::drawTextFrame( // they will protect overlapping glyphs from the effects of overdraw // so we must make the conservative assessment that this DL layer is // not compatible with group opacity inheritance. - UpdateLayerOpacityCompatibility(false); + // A single glyph can still have the opacity peephole applied (this is + // likely a glyph used as an Icon) + const bool is_single_glyph = text_frame->GetRunCount() == 1u && + text_frame->GetRuns()[0].GetGlyphCount() == 1u; + UpdateLayerOpacityCompatibility(is_single_glyph); UpdateLayerResult(result); } } diff --git a/display_list/testing/dl_test_snippets.cc b/display_list/testing/dl_test_snippets.cc index 56b36804f6a0b..6cbab1415881b 100644 --- a/display_list/testing/dl_test_snippets.cc +++ b/display_list/testing/dl_test_snippets.cc @@ -980,5 +980,12 @@ sk_sp GetTestTextBlob(int index) { return blob; } +sk_sp CreateTextBlob(std::string& message) { + sk_sp blob = + SkTextBlob::MakeFromText(message.c_str(), message.size(), + CreateTestFontOfSize(20), SkTextEncoding::kUTF8); + return blob; +} + } // namespace testing } // namespace flutter diff --git a/display_list/testing/dl_test_snippets.h b/display_list/testing/dl_test_snippets.h index e8a8631a2f0e8..393b1217b3988 100644 --- a/display_list/testing/dl_test_snippets.h +++ b/display_list/testing/dl_test_snippets.h @@ -227,6 +227,8 @@ SkFont CreateTestFontOfSize(SkScalar scalar); sk_sp GetTestTextBlob(int index); +sk_sp CreateTextBlob(std::string& message); + struct DisplayListInvocation { // ---------------------------------- // Required fields for initialization