@@ -297,34 +297,40 @@ static std::shared_ptr<SkBitmap> CreateAtlasBitmap(const GlyphAtlas& atlas,
297297 return bitmap;
298298}
299299
300- static std::shared_ptr<Texture> UploadGlyphTextureAtlas (
300+ static std::shared_ptr<Texture> CreateGlyphTextureAtlas (
301301 const std::shared_ptr<Allocator>& allocator,
302- std::shared_ptr<SkBitmap> bitmap,
303302 const ISize& atlas_size,
304303 PixelFormat format) {
305304 TRACE_EVENT0 (" impeller" , __FUNCTION__);
306305 if (!allocator) {
307306 return nullptr ;
308307 }
309308
310- FML_DCHECK (bitmap != nullptr );
311- const auto & pixmap = bitmap->pixmap ();
312-
313309 TextureDescriptor texture_descriptor;
314310 texture_descriptor.storage_mode = StorageMode::kHostVisible ;
315311 texture_descriptor.format = format;
316312 texture_descriptor.size = atlas_size;
317313
318- if (pixmap.rowBytes () * pixmap.height () !=
319- texture_descriptor.GetByteSizeOfBaseMipLevel ()) {
320- return nullptr ;
321- }
322-
323314 auto texture = allocator->CreateTexture (texture_descriptor);
324315 if (!texture || !texture->IsValid ()) {
325316 return nullptr ;
326317 }
327318 texture->SetLabel (" GlyphAtlas" );
319+ return texture;
320+ }
321+
322+ bool UploadGlyphTextureAtlas (const std::shared_ptr<Texture>& texture,
323+ std::shared_ptr<SkBitmap> bitmap) {
324+ TRACE_EVENT0 (" impeller" , __FUNCTION__);
325+
326+ FML_DCHECK (bitmap != nullptr );
327+ const auto & pixmap = bitmap->pixmap ();
328+
329+ auto texture_descriptor = texture->GetTextureDescriptor ();
330+ if (pixmap.rowBytes () * pixmap.height () !=
331+ texture_descriptor.GetByteSizeOfBaseMipLevel ()) {
332+ return false ;
333+ }
328334
329335 auto mapping = std::make_shared<fml::NonOwnedMapping>(
330336 reinterpret_cast <const uint8_t *>(bitmap->getAddr (0 , 0 )), // data
@@ -333,9 +339,9 @@ static std::shared_ptr<Texture> UploadGlyphTextureAtlas(
333339 );
334340
335341 if (!texture->SetContents (mapping)) {
336- return nullptr ;
342+ return false ;
337343 }
338- return texture ;
344+ return true ;
339345}
340346
341347std::shared_ptr<GlyphAtlas> TextRenderContextSkia::CreateGlyphAtlas (
@@ -421,16 +427,29 @@ std::shared_ptr<GlyphAtlas> TextRenderContextSkia::CreateGlyphAtlas(
421427 format = PixelFormat::kR8G8B8A8UNormInt ;
422428 break ;
423429 }
424- auto texture = UploadGlyphTextureAtlas (GetContext ()->GetResourceAllocator (),
425- bitmap, atlas_size, format);
426- if (!texture) {
427- return nullptr ;
428- }
429430
430431 // ---------------------------------------------------------------------------
431432 // Step 8: Record the texture in the glyph atlas.
433+ //
434+ // If the last_texture is the same size and type, reuse this instead of
435+ // creating a new texture.
432436 // ---------------------------------------------------------------------------
433- glyph_atlas->SetTexture (std::move (texture));
437+ auto old_texture = last_atlas->GetTexture ();
438+ if (old_texture != nullptr &&
439+ old_texture->GetTextureDescriptor ().size == atlas_size &&
440+ old_texture->GetTextureDescriptor ().format == format) {
441+ if (!UploadGlyphTextureAtlas (old_texture, bitmap)) {
442+ return nullptr ;
443+ }
444+ glyph_atlas->SetTexture (std::move (old_texture));
445+ } else {
446+ auto texture = CreateGlyphTextureAtlas (GetContext ()->GetResourceAllocator (),
447+ atlas_size, format);
448+ if (!texture || !UploadGlyphTextureAtlas (texture, bitmap)) {
449+ return nullptr ;
450+ }
451+ glyph_atlas->SetTexture (std::move (texture));
452+ }
434453
435454 return glyph_atlas;
436455}
0 commit comments