perf(text): fold Ensure+Lookup into FontAtlas::EnsureAndGet (#53)

Per glyph, ShapeText did cache_.contains(key) (in Ensure) then
cache_.find(key) (in Lookup) — two independent hashes + node-chases of
the same key. Add EnsureAndGet returning const Glyph* with a single
find, insert-on-miss, returning &it->second. It returns nullptr only on
ShelfPlace failure, preserving the existing `if (g==nullptr) continue;`
behavior. Ensure now delegates to it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
catbot 2026-06-16 15:43:58 +00:00
commit 77a6501ced
3 changed files with 13 additions and 6 deletions

View file

@ -70,8 +70,12 @@ bool FontAtlas::ShelfPlace(int w, int h, int& outX, int& outY) {
}
bool FontAtlas::Ensure(Font& font, std::uint32_t codepoint) {
return EnsureAndGet(font, codepoint) != nullptr;
}
const Glyph* FontAtlas::EnsureAndGet(Font& font, std::uint32_t codepoint) {
Key key{&font, codepoint};
if (cache_.contains(key)) return true;
if (auto it = cache_.find(key); it != cache_.end()) return &it->second;
float fontScale = stbtt_ScaleForPixelHeight(&font.font, kBaseSize);
@ -94,7 +98,7 @@ bool FontAtlas::Ensure(Font& font, std::uint32_t codepoint) {
int px = 0, py = 0;
if (!ShelfPlace(sw, sh, px, py)) {
stbtt_FreeSDF(sdf, nullptr);
return false;
return nullptr;
}
std::uint8_t* dst = PixelPtr();
for (int row = 0; row < sh; ++row) {
@ -115,8 +119,7 @@ bool FontAtlas::Ensure(Font& font, std::uint32_t codepoint) {
dirty = true;
}
cache_.emplace(key, g);
return true;
return &cache_.emplace(key, g).first->second;
}
const Glyph* FontAtlas::Lookup(Font& font, std::uint32_t codepoint) const {