SimpleFontData* FontCache::getCachedFontData(const FontPlatformData* platformData) { if (!platformData) return 0; if (!gFontDataCache) { gFontDataCache = new FontDataCache; gInactiveFontData = new InactiveFontDataHashSet; } FontDataCache::iterator result = gFontDataCache->find(*platformData); if (result == gFontDataCache->end()) { if (gInactiveFontData->size() > cMaxInactiveFontData) purgeInactiveFontData((int)(cMaxInactiveFontData * cInactiveFontDataPurgeRatio)); pair<SimpleFontData*, unsigned> newValue(new SimpleFontData(*platformData), 1); // 6/15/09 CSidhall -Moved the add ref into the constructor of SimpleFontData gFontDataCache->set(*platformData, newValue); return newValue.first; } if (!result.get()->second.second++) { if(gInactiveFontData->contains(result.get()->second.first)) gInactiveFontData->remove(result.get()->second.first); } return result.get()->second.first; }
void FontCache::invalidate() { if (!gClients) { ASSERT(fontPlatformDataCache().isEmpty()); return; } fontPlatformDataCache().clear(); #if ENABLE(OPENTYPE_VERTICAL) fontVerticalDataCache().clear(); #endif invalidateFontCascadeCache(); gGeneration++; Vector<Ref<FontSelector>> clients; clients.reserveInitialCapacity(gClients->size()); for (auto it = gClients->begin(), end = gClients->end(); it != end; ++it) clients.uncheckedAppend(**it); for (unsigned i = 0; i < clients.size(); ++i) clients[i]->fontCacheInvalidated(); purgeInactiveFontData(); }
void FontCache::purgeInactiveFontDataIfNeeded() { bool underMemoryPressure = MemoryPressureHandler::singleton().isUnderMemoryPressure(); unsigned inactiveFontDataLimit = underMemoryPressure ? cMaxUnderMemoryPressureInactiveFontData : cMaxInactiveFontData; if (cachedFonts().size() < inactiveFontDataLimit) return; unsigned inactiveCount = inactiveFontCount(); if (inactiveCount <= inactiveFontDataLimit) return; unsigned targetFontDataLimit = underMemoryPressure ? cTargetUnderMemoryPressureInactiveFontData : cTargetInactiveFontData; purgeInactiveFontData(inactiveCount - targetFontDataLimit); }