[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:
@@ -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.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user