[Impeller] recycle glyph atlas texture more aggressively. (flutter/engine#48888)

If we need to remake the glyph atlas texture but the size is the same, then reuse the old texture.

For more context, see https://github.com/flutter/flutter/issues/138798 which is much slower in Impeller. This change does not fix the problem by itself.
This commit is contained in:
Jonah Williams
2023-12-11 16:08:51 -08:00
committed by GitHub
parent 64c9aac3a6
commit 1006f98435
2 changed files with 50 additions and 1 deletions

View File

@@ -446,6 +446,20 @@ std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas(
}
atlas_context_skia.UpdateBitmap(bitmap);
// If the new atlas size is the same size as the previous texture, reuse the
// texture and treat this as an updated that replaces all glyphs.
if (last_atlas && last_atlas->GetTexture()) {
std::shared_ptr<Texture> last_texture = last_atlas->GetTexture();
if (atlas_size == last_texture->GetSize()) {
if (!UpdateGlyphTextureAtlas(bitmap, last_texture)) {
return nullptr;
}
glyph_atlas->SetTexture(last_texture);
return glyph_atlas;
}
}
// ---------------------------------------------------------------------------
// Step 7b: Upload the atlas as a texture.
// ---------------------------------------------------------------------------

View File

@@ -9,7 +9,6 @@
#include "impeller/typographer/backends/skia/typographer_context_skia.h"
#include "impeller/typographer/lazy_glyph_atlas.h"
#include "impeller/typographer/rectangle_packer.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkFont.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkRect.h"
@@ -339,6 +338,42 @@ TEST_P(TypographerTest, RectanglePackerAddsNonoverlapingRectangles) {
ASSERT_EQ(packer->percentFull(), 0);
}
TEST_P(TypographerTest, GlyphAtlasTextureIsRecycledWhenContentsAreRecreated) {
auto context = TypographerContextSkia::Make();
auto atlas_context = context->CreateGlyphAtlasContext();
ASSERT_TRUE(context && context->IsValid());
SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
auto blob = SkTextBlob::MakeFromString("ABCDEFGHIJKLMNOPQRSTUVQXYZ123456789",
sk_font);
ASSERT_TRUE(blob);
auto atlas = CreateGlyphAtlas(
*GetContext(), context.get(), GlyphAtlas::Type::kColorBitmap, 32.0f,
atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
auto old_packer = atlas_context->GetRectPacker();
ASSERT_NE(atlas, nullptr);
ASSERT_NE(atlas->GetTexture(), nullptr);
ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
auto* first_texture = atlas->GetTexture().get();
// Now create a new glyph atlas with a completely different textblob.
// everything should be different except for the underlying atlas texture.
auto blob2 = SkTextBlob::MakeFromString("abcdefghijklmnopqrstuvwxyz123456789",
sk_font);
auto next_atlas = CreateGlyphAtlas(
*GetContext(), context.get(), GlyphAtlas::Type::kColorBitmap, 32.0f,
atlas_context, *MakeTextFrameFromTextBlobSkia(blob2));
ASSERT_NE(atlas, next_atlas);
auto* second_texture = next_atlas->GetTexture().get();
auto new_packer = atlas_context->GetRectPacker();
ASSERT_EQ(second_texture, first_texture);
ASSERT_NE(old_packer, new_packer);
}
} // namespace testing
} // namespace impeller