Smarter cache eviction
This commit is contained in:
@@ -219,13 +219,6 @@ int32_t FontDecompressor::findGlyphIndex(const EpdFontData* fontData, uint32_t c
|
|||||||
int FontDecompressor::prewarmCache(const EpdFontData* fontData, const char* utf8Text) {
|
int FontDecompressor::prewarmCache(const EpdFontData* fontData, const char* utf8Text) {
|
||||||
if (!fontData || !fontData->groups || !utf8Text) return 0;
|
if (!fontData || !fontData->groups || !utf8Text) return 0;
|
||||||
|
|
||||||
// Allocate the next available slot (caller must call freePageBuffer/clearCache to reset)
|
|
||||||
if (pageSlotCount >= MAX_PAGE_SLOTS) {
|
|
||||||
LOG_ERR("FDC", "All %u page buffer slots full, cannot prewarm fontData=%p", MAX_PAGE_SLOTS, (void*)fontData);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
PageSlot& slot = pageSlots[pageSlotCount];
|
|
||||||
|
|
||||||
// Step 1: Collect unique glyph indices needed for this page
|
// Step 1: Collect unique glyph indices needed for this page
|
||||||
uint32_t neededGlyphs[MAX_PAGE_GLYPHS];
|
uint32_t neededGlyphs[MAX_PAGE_GLYPHS];
|
||||||
uint16_t glyphCount = 0;
|
uint16_t glyphCount = 0;
|
||||||
@@ -239,7 +232,29 @@ int FontDecompressor::prewarmCache(const EpdFontData* fontData, const char* utf8
|
|||||||
int32_t glyphIdx = findGlyphIndex(fontData, cp);
|
int32_t glyphIdx = findGlyphIndex(fontData, cp);
|
||||||
if (glyphIdx < 0) continue;
|
if (glyphIdx < 0) continue;
|
||||||
|
|
||||||
// Deduplicate
|
// Deduplicate against already prewarmed slots
|
||||||
|
bool alreadyCached = false;
|
||||||
|
for (uint8_t s = 0; s < pageSlotCount; s++) {
|
||||||
|
if (pageSlots[s].fontData != fontData || pageSlots[s].glyphCount == 0) continue;
|
||||||
|
int left = 0, right = pageSlots[s].glyphCount - 1;
|
||||||
|
while (left <= right) {
|
||||||
|
int mid = left + (right - left) / 2;
|
||||||
|
if (pageSlots[s].glyphs[mid].glyphIndex == static_cast<uint32_t>(glyphIdx)) {
|
||||||
|
if (pageSlots[s].glyphs[mid].bufferOffset != UINT32_MAX) {
|
||||||
|
alreadyCached = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pageSlots[s].glyphs[mid].glyphIndex < static_cast<uint32_t>(glyphIdx))
|
||||||
|
left = mid + 1;
|
||||||
|
else
|
||||||
|
right = mid - 1;
|
||||||
|
}
|
||||||
|
if (alreadyCached) break;
|
||||||
|
}
|
||||||
|
if (alreadyCached) continue;
|
||||||
|
|
||||||
|
// Deduplicate within the current page pass
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (uint16_t i = 0; i < glyphCount; i++) {
|
for (uint16_t i = 0; i < glyphCount; i++) {
|
||||||
if (neededGlyphs[i] == static_cast<uint32_t>(glyphIdx)) {
|
if (neededGlyphs[i] == static_cast<uint32_t>(glyphIdx)) {
|
||||||
@@ -297,6 +312,13 @@ int FontDecompressor::prewarmCache(const EpdFontData* fontData, const char* utf8
|
|||||||
|
|
||||||
if (glyphCount == 0) return 0;
|
if (glyphCount == 0) return 0;
|
||||||
|
|
||||||
|
// Allocate the next available slot
|
||||||
|
if (pageSlotCount >= MAX_PAGE_SLOTS) {
|
||||||
|
LOG_ERR("FDC", "All %u page buffer slots full, cannot prewarm fontData=%p", MAX_PAGE_SLOTS, (void*)fontData);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PageSlot& slot = pageSlots[pageSlotCount];
|
||||||
|
|
||||||
// Step 2: Compute total buffer size and collect unique groups
|
// Step 2: Compute total buffer size and collect unique groups
|
||||||
uint32_t totalBytes = 0;
|
uint32_t totalBytes = 0;
|
||||||
uint16_t neededGroups[128];
|
uint16_t neededGroups[128];
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
class FontDecompressor {
|
class FontDecompressor {
|
||||||
public:
|
public:
|
||||||
static constexpr uint16_t MAX_PAGE_GLYPHS = 512;
|
static constexpr uint16_t MAX_PAGE_GLYPHS = 512;
|
||||||
static constexpr uint8_t MAX_PAGE_SLOTS = 8; // Provide enough slots for heavily stylized HTML pages
|
static constexpr uint8_t MAX_PAGE_SLOTS = 4; // One per font style (R/B/I/BI)
|
||||||
|
|
||||||
FontDecompressor() = default;
|
FontDecompressor() = default;
|
||||||
~FontDecompressor();
|
~FontDecompressor();
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ void FontCacheManager::clearCache() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FontCacheManager::prewarmCache(int fontId, const char* utf8Text, uint8_t styleMask) {
|
void FontCacheManager::prewarmCache(int fontId, const char* utf8Text, uint8_t styleMask) {
|
||||||
clearCache();
|
|
||||||
|
|
||||||
// SD card font prewarm path: prewarm all requested styles in one call
|
// SD card font prewarm path: prewarm all requested styles in one call
|
||||||
auto sdIt = sdCardFonts_.find(fontId);
|
auto sdIt = sdCardFonts_.find(fontId);
|
||||||
if (sdIt != sdCardFonts_.end()) {
|
if (sdIt != sdCardFonts_.end()) {
|
||||||
@@ -52,6 +50,11 @@ void FontCacheManager::prewarmCache(int fontId, const char* utf8Text, uint8_t st
|
|||||||
const EpdFontData* data = fontMap_.at(fontId).getData(style);
|
const EpdFontData* data = fontMap_.at(fontId).getData(style);
|
||||||
if (!data || !data->groups) continue;
|
if (!data || !data->groups) continue;
|
||||||
int missed = fontDecompressor_->prewarmCache(data, utf8Text);
|
int missed = fontDecompressor_->prewarmCache(data, utf8Text);
|
||||||
|
if (missed < 0) {
|
||||||
|
LOG_DBG("FCM", "prewarmCache: Cache slots full! Clearing and retrying slot allocation.");
|
||||||
|
clearCache();
|
||||||
|
missed = fontDecompressor_->prewarmCache(data, utf8Text);
|
||||||
|
}
|
||||||
if (missed > 0) {
|
if (missed > 0) {
|
||||||
LOG_DBG("FCM", "prewarmCache: %d glyph(s) not cached for style %d", missed, i);
|
LOG_DBG("FCM", "prewarmCache: %d glyph(s) not cached for style %d", missed, i);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user