352 TRACE_EVENT0(
"impeller", __FUNCTION__);
356 std::shared_ptr<GlyphAtlas> last_atlas = atlas_context->GetGlyphAtlas();
357 FML_DCHECK(last_atlas->GetType() ==
type);
359 if (font_glyph_map.empty()) {
368 std::vector<Rect> glyph_sizes;
369 std::vector<FontGlyphPair> new_glyphs;
370 for (
const auto& font_value : font_glyph_map) {
371 const ScaledFont& scaled_font = font_value.first;
372 const FontGlyphAtlas* font_glyph_atlas =
373 last_atlas->GetFontGlyphAtlas(scaled_font.font, scaled_font.scale);
375 auto metrics = scaled_font.font.GetMetrics();
379 metrics.point_size, metrics.scaleX, metrics.skewX);
380 sk_font.setEdging(SkFont::Edging::kAntiAlias);
381 sk_font.setHinting(SkFontHinting::kSlight);
382 sk_font.setEmbolden(metrics.embolden);
386 sk_font.setSize(sk_font.getSize() * scaled_font.scale);
387 sk_font.setSubpixel(
true);
389 if (font_glyph_atlas) {
390 for (
const SubpixelGlyph& glyph : font_value.second) {
391 if (!font_glyph_atlas->FindGlyphBounds(glyph)) {
392 new_glyphs.emplace_back(scaled_font, glyph);
393 glyph_sizes.push_back(
398 for (
const SubpixelGlyph& glyph : font_value.second) {
399 new_glyphs.emplace_back(scaled_font, glyph);
400 glyph_sizes.push_back(
405 if (new_glyphs.size() == 0) {
413 std::vector<Rect> glyph_positions;
414 glyph_positions.reserve(new_glyphs.size());
415 size_t first_missing_index = 0;
417 if (last_atlas->GetTexture()) {
420 last_atlas, new_glyphs, glyph_positions, glyph_sizes,
421 atlas_context->GetAtlasSize(), atlas_context->GetHeightAdjustment(),
422 atlas_context->GetRectPacker());
428 for (
size_t i = 0; i < first_missing_index; i++) {
429 last_atlas->AddTypefaceGlyphPositionAndBounds(
430 new_glyphs[i], glyph_positions[i], glyph_sizes[i]);
433 std::shared_ptr<CommandBuffer> cmd_buffer = context.CreateCommandBuffer();
434 std::shared_ptr<BlitPass> blit_pass = cmd_buffer->CreateBlitPass();
436 fml::ScopedCleanupClosure closure([&]() {
437 blit_pass->EncodeCommands(context.GetResourceAllocator());
438 context.GetCommandQueue()->Submit({std::move(cmd_buffer)});
446 last_atlas->GetTexture(), new_glyphs, 0,
447 first_missing_index)) {
452 if (first_missing_index == new_glyphs.size()) {
457 int64_t height_adjustment = atlas_context->GetAtlasSize().height;
458 const int64_t max_texture_height =
459 context.GetResourceAllocator()->GetMaxTextureSizeSupported().height;
466 bool blit_old_atlas =
true;
467 std::shared_ptr<GlyphAtlas> new_atlas = last_atlas;
468 if (atlas_context->GetAtlasSize().height >= max_texture_height ||
470 blit_old_atlas =
false;
471 first_missing_index = 0;
472 glyph_positions.clear();
473 height_adjustment = 0;
474 new_atlas = std::make_shared<GlyphAtlas>(
type);
475 atlas_context->UpdateRectPacker(
nullptr);
476 atlas_context->UpdateGlyphAtlas(new_atlas, {0, 0}, 0);
488 atlas_context->UpdateGlyphAtlas(new_atlas, atlas_size, height_adjustment);
489 if (atlas_size.IsEmpty()) {
492 FML_DCHECK(new_glyphs.size() == glyph_positions.size());
494 TextureDescriptor descriptor;
498 context.GetCapabilities()->GetDefaultGlyphAtlasFormat();
504 descriptor.size = atlas_size;
507 std::shared_ptr<Texture> new_texture =
508 context.GetResourceAllocator()->CreateTexture(descriptor);
513 new_texture->SetLabel(
"GlyphAtlas");
515 std::shared_ptr<CommandBuffer> cmd_buffer = context.CreateCommandBuffer();
516 std::shared_ptr<BlitPass> blit_pass = cmd_buffer->CreateBlitPass();
522 TRACE_EVENT0(
"flutter",
"ClearGlyphAtlas");
524 new_texture->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
534 fml::ScopedCleanupClosure closure([&]() {
535 blit_pass->EncodeCommands(context.GetResourceAllocator());
536 context.GetCommandQueue()->Submit({std::move(cmd_buffer)});
540 if (new_atlas->GetTexture() && blit_old_atlas) {
541 blit_pass->AddCopy(new_atlas->GetTexture(), new_texture,
547 new_atlas->SetTexture(std::move(new_texture));
553 for (
size_t i = first_missing_index; i < glyph_positions.size(); i++) {
554 new_atlas->AddTypefaceGlyphPositionAndBounds(
555 new_glyphs[i], glyph_positions[i], glyph_sizes[i]);
563 new_atlas->GetTexture(), new_glyphs,
564 first_missing_index, new_glyphs.size())) {