Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[Impeller] reuse texture
  • Loading branch information
jonahwilliams committed Nov 11, 2022
commit a31ac1ee8b5122d31b609bbc750653c77d5c122d
63 changes: 45 additions & 18 deletions impeller/typographer/backends/skia/text_render_context_skia.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "impeller/typographer/backends/skia/text_render_context_skia.h"

#include <iostream>
#include <utility>

#include "flutter/fml/logging.h"
Expand Down Expand Up @@ -297,34 +298,41 @@ static std::shared_ptr<SkBitmap> CreateAtlasBitmap(const GlyphAtlas& atlas,
return bitmap;
}

static std::shared_ptr<Texture> UploadGlyphTextureAtlas(
static std::shared_ptr<Texture> CreateGlyphTextureAtlas(
const std::shared_ptr<Allocator>& allocator,
std::shared_ptr<SkBitmap> bitmap,
const ISize& atlas_size,
PixelFormat format) {
TRACE_EVENT0("impeller", __FUNCTION__);
if (!allocator) {
return nullptr;
}

FML_DCHECK(bitmap != nullptr);
const auto& pixmap = bitmap->pixmap();

TextureDescriptor texture_descriptor;
texture_descriptor.storage_mode = StorageMode::kHostVisible;
texture_descriptor.format = format;
texture_descriptor.size = atlas_size;

if (pixmap.rowBytes() * pixmap.height() !=
texture_descriptor.GetByteSizeOfBaseMipLevel()) {
return nullptr;
}

auto texture = allocator->CreateTexture(texture_descriptor);
if (!texture || !texture->IsValid()) {
return nullptr;
}
texture->SetLabel("GlyphAtlas");
return texture;
}

bool UploadGlyphTextureAtlas(const std::shared_ptr<Texture>& texture,
std::shared_ptr<SkBitmap> bitmap) {
TRACE_EVENT0("impeller", __FUNCTION__);

FML_DCHECK(bitmap != nullptr);
const auto& pixmap = bitmap->pixmap();

auto texture_descriptor = texture->GetTextureDescriptor();
if (pixmap.rowBytes() * pixmap.height() !=
texture_descriptor.GetByteSizeOfBaseMipLevel()) {
std::cerr << "descriptor mismatch" << std::endl;
return false;
}

auto mapping = std::make_shared<fml::NonOwnedMapping>(
reinterpret_cast<const uint8_t*>(bitmap->getAddr(0, 0)), // data
Expand All @@ -333,9 +341,10 @@ static std::shared_ptr<Texture> UploadGlyphTextureAtlas(
);

if (!texture->SetContents(mapping)) {
return nullptr;
std::cerr << "contents cant be set" << std::endl;
return false;
}
return texture;
return true;
}

std::shared_ptr<GlyphAtlas> TextRenderContextSkia::CreateGlyphAtlas(
Expand Down Expand Up @@ -421,16 +430,34 @@ std::shared_ptr<GlyphAtlas> TextRenderContextSkia::CreateGlyphAtlas(
format = PixelFormat::kR8G8B8A8UNormInt;
break;
}
auto texture = UploadGlyphTextureAtlas(GetContext()->GetResourceAllocator(),
bitmap, atlas_size, format);
if (!texture) {
return nullptr;
}

// ---------------------------------------------------------------------------
// Step 8: Record the texture in the glyph atlas.
//
// If the last_texture is the same size and type, reuse this instead of
// creating a new texture.
// ---------------------------------------------------------------------------
glyph_atlas->SetTexture(std::move(texture));
auto old_texture = last_atlas->GetTexture();
if (old_texture != nullptr &&
old_texture->GetTextureDescriptor().size == atlas_size) {
std::cerr << "reuse atlas" << std::endl;
if (!UploadGlyphTextureAtlas(old_texture, bitmap)) {
return nullptr;
}
glyph_atlas->SetTexture(std::move(old_texture));
} else {
std::cerr << "can't reuse "
<< (old_texture != nullptr
? old_texture->GetTextureDescriptor().size
: ISize(0, 0))
<< " : " << atlas_size << std::endl;
auto texture = CreateGlyphTextureAtlas(GetContext()->GetResourceAllocator(),
atlas_size, format);
if (!texture || !UploadGlyphTextureAtlas(texture, bitmap)) {
return nullptr;
}
glyph_atlas->SetTexture(std::move(texture));
}

return glyph_atlas;
}
Expand Down