Skip to content

Commit

Permalink
[Impeller] recycle glyph atlas texture more aggressively. (flutter#48888
Browse files Browse the repository at this point in the history
)

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

For more context, see flutter/flutter#138798 which is much slower in Impeller. This change does not fix the problem by itself.
  • Loading branch information
jonahwilliams authored Dec 12, 2023
1 parent ea1a306 commit 362d0cb
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
14 changes: 14 additions & 0 deletions impeller/typographer/backends/skia/typographer_context_skia.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
// ---------------------------------------------------------------------------
Expand Down
37 changes: 36 additions & 1 deletion impeller/typographer/typographer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit 362d0cb

Please sign in to comment.