diff --git a/engine/src/flutter/impeller/typographer/backends/skia/typographer_context_skia.cc b/engine/src/flutter/impeller/typographer/backends/skia/typographer_context_skia.cc index 13dc254e67..6ef7c10abb 100644 --- a/engine/src/flutter/impeller/typographer/backends/skia/typographer_context_skia.cc +++ b/engine/src/flutter/impeller/typographer/backends/skia/typographer_context_skia.cc @@ -415,7 +415,7 @@ TypographerContextSkia::CollectNewGlyphs( std::vector glyph_sizes; size_t generation_id = atlas->GetAtlasGeneration(); for (const auto& frame : text_frames) { - if (frame->IsFrameComplete() && + if (atlas->IsValid() && frame->IsFrameComplete() && frame->GetAtlasGeneration() == generation_id && !frame->GetFrameBounds(0).is_placeholder) { continue; diff --git a/engine/src/flutter/impeller/typographer/typographer_unittests.cc b/engine/src/flutter/impeller/typographer/typographer_unittests.cc index 4b8cc1cbc9..d067c6032f 100644 --- a/engine/src/flutter/impeller/typographer/typographer_unittests.cc +++ b/engine/src/flutter/impeller/typographer/typographer_unittests.cc @@ -612,6 +612,49 @@ TEST_P(TypographerTest, TextFrameAtlasGenerationTracksState) { EXPECT_EQ(frame->GetAtlasGeneration(), 2u); } +TEST_P(TypographerTest, InvalidAtlasForcesRepopulation) { + SkFont font = flutter::testing::CreateTestFontOfSize(12); + auto blob = SkTextBlob::MakeFromString( + "the quick brown fox jumped over the lazy dog.", font); + ASSERT_TRUE(blob); + auto frame = MakeTextFrameFromTextBlobSkia(blob); + + EXPECT_FALSE(frame->IsFrameComplete()); + + auto context = TypographerContextSkia::Make(); + auto atlas_context = + context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); + + auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer, + GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f, + atlas_context, frame); + + // The glyph position in the atlas was not known when this value + // was recorded. It is marked as a placeholder. + EXPECT_TRUE(frame->IsFrameComplete()); + EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder); + if (GetBackend() == PlaygroundBackend::kOpenGLES) { + // OpenGLES must always increase the atlas backend if the texture grows. + EXPECT_EQ(frame->GetAtlasGeneration(), 1u); + } else { + EXPECT_EQ(frame->GetAtlasGeneration(), 0u); + } + + auto second_context = TypographerContextSkia::Make(); + auto second_atlas_context = + second_context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap); + + EXPECT_FALSE(second_atlas_context->GetGlyphAtlas()->IsValid()); + + atlas = CreateGlyphAtlas(*GetContext(), second_context.get(), *host_buffer, + GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f, + second_atlas_context, frame); + + EXPECT_TRUE(second_atlas_context->GetGlyphAtlas()->IsValid()); +} + } // namespace testing } // namespace impeller