Rename FontDescriptionFontDataCacheKey to FontDescriptionKey
[WebKit-https.git] / Source / WebCore / platform / graphics / FontCache.cpp
index de82034..368c4b9 100644 (file)
@@ -30,8 +30,7 @@
 #include "config.h"
 #include "FontCache.h"
 
-#include "Font.h"
-#include "FontGlyphs.h"
+#include "FontCascade.h"
 #include "FontPlatformData.h"
 #include "FontSelector.h"
 #include "MemoryPressureHandler.h"
 #include <wtf/Noncopyable.h>
 
 // FIXME: We may be able to simplify this code using C++11 threading primitives, including std::call_once().
-static pthread_mutex_t fontDataLock;
+static pthread_mutex_t fontLock;
 
 static void initFontCacheLockOnce()
 {
     pthread_mutexattr_t mutexAttribute;
     pthread_mutexattr_init(&mutexAttribute);
     pthread_mutexattr_settype(&mutexAttribute, PTHREAD_MUTEX_RECURSIVE);
-    pthread_mutex_init(&fontDataLock, &mutexAttribute);
+    pthread_mutex_init(&fontLock, &mutexAttribute);
     pthread_mutexattr_destroy(&mutexAttribute);
 }
 
@@ -71,13 +70,13 @@ public:
     FontLocker()
     {
         pthread_once(&initFontLockControl, initFontCacheLockOnce);
-        int lockcode = pthread_mutex_lock(&fontDataLock);
-        ASSERT_WITH_MESSAGE_UNUSED(lockcode, !lockcode, "fontDataLock lock failed with code:%d", lockcode);    
+        int lockcode = pthread_mutex_lock(&fontLock);
+        ASSERT_WITH_MESSAGE_UNUSED(lockcode, !lockcode, "fontLock lock failed with code:%d", lockcode);    
     }
     ~FontLocker()
     {
-        int lockcode = pthread_mutex_unlock(&fontDataLock);
-        ASSERT_WITH_MESSAGE_UNUSED(lockcode, !lockcode, "fontDataLock unlock failed with code:%d", lockcode);
+        int lockcode = pthread_mutex_unlock(&fontLock);
+        ASSERT_WITH_MESSAGE_UNUSED(lockcode, !lockcode, "fontLock unlock failed with code:%d", lockcode);
     }
 };
 #endif // PLATFORM(IOS)
@@ -86,7 +85,7 @@ using namespace WTF;
 
 namespace WebCore {
 
-FontCache& fontCache()
+FontCache& FontCache::singleton()
 {
     static NeverDestroyed<FontCache> globalFontCache;
     return globalFontCache;
@@ -114,22 +113,17 @@ public:
         return equalIgnoringCase(m_family, other.m_family) && m_fontDescriptionKey == other.m_fontDescriptionKey;
     }
 
-    FontDescriptionFontDataCacheKey m_fontDescriptionKey;
+    FontDescriptionKey m_fontDescriptionKey;
     AtomicString m_family;
 
 private:
     static unsigned hashTableDeletedSize() { return 0xFFFFFFFFU; }
 };
 
-inline unsigned computeHash(const FontPlatformDataCacheKey& fontKey)
-{
-    return pairIntHash(CaseFoldingHash::hash(fontKey.m_family), fontKey.m_fontDescriptionKey.computeHash());
-}
-
 struct FontPlatformDataCacheKeyHash {
-    static unsigned hash(const FontPlatformDataCacheKey& font)
+    static unsigned hash(const FontPlatformDataCacheKey& fontKey)
     {
-        return computeHash(font);
+        return pairIntHash(CaseFoldingHash::hash(fontKey.m_family), fontKey.m_fontDescriptionKey.computeHash());
     }
          
     static bool equal(const FontPlatformDataCacheKey& a, const FontPlatformDataCacheKey& b)
@@ -140,9 +134,7 @@ struct FontPlatformDataCacheKeyHash {
     static const bool safeToCompareToEmptyOrDeleted = true;
 };
 
-struct FontPlatformDataCacheKeyTraits : WTF::SimpleClassHashTraits<FontPlatformDataCacheKey> { };
-
-typedef HashMap<FontPlatformDataCacheKey, std::unique_ptr<FontPlatformData>, FontPlatformDataCacheKeyHash, FontPlatformDataCacheKeyTraits> FontPlatformDataCache;
+typedef HashMap<FontPlatformDataCacheKey, std::unique_ptr<FontPlatformData>, FontPlatformDataCacheKeyHash, WTF::SimpleClassHashTraits<FontPlatformDataCacheKey>> FontPlatformDataCache;
 
 static FontPlatformDataCache& fontPlatformDataCache()
 {
@@ -321,7 +313,7 @@ PassRefPtr<OpenTypeVerticalData> FontCache::getVerticalData(const FontFileKey& k
 
     RefPtr<OpenTypeVerticalData> verticalData = OpenTypeVerticalData::create(platformData);
     if (!verticalData->isOpenType())
-        verticalData.clear();
+        verticalData = nullptr;
     fontVerticalDataCache.set(key, verticalData);
     return verticalData;
 }
@@ -343,7 +335,6 @@ struct FontDataCacheKeyHash {
 
 struct FontDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformData> {
     static const bool emptyValueIsZero = true;
-    static const bool needsDestruction = true;
     static const FontPlatformData& emptyValue()
     {
         static NeverDestroyed<FontPlatformData> key(0.f, false, false);
@@ -359,7 +350,7 @@ struct FontDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformData> {
     }
 };
 
-typedef HashMap<FontPlatformData, RefPtr<SimpleFontData>, FontDataCacheKeyHash, FontDataCacheKeyTraits> FontDataCache;
+typedef HashMap<FontPlatformData, RefPtr<Font>, FontDataCacheKeyHash, FontDataCacheKeyTraits> FontDataCache;
 
 static FontDataCache& cachedFonts()
 {
@@ -369,17 +360,17 @@ static FontDataCache& cachedFonts()
 
 
 #if PLATFORM(IOS)
-const int cMaxInactiveFontData = 120;
-const int cTargetInactiveFontData = 100;
+const unsigned cMaxInactiveFontData = 120;
+const unsigned cTargetInactiveFontData = 100;
 #else
-const int cMaxInactiveFontData = 5;
-const int cTargetInactiveFontData = 200;
+const unsigned cMaxInactiveFontData = 225;
+const unsigned cTargetInactiveFontData = 200;
 #endif
 
-const int cMaxUnderMemoryPressureInactiveFontData = 50;
-const int cTargetUnderMemoryPressureInactiveFontData = 30;
+const unsigned cMaxUnderMemoryPressureInactiveFontData = 50;
+const unsigned cTargetUnderMemoryPressureInactiveFontData = 30;
 
-RefPtr<SimpleFontData> FontCache::fontForFamily(const FontDescription& fontDescription, const AtomicString& family, bool checkingAlternateName)
+RefPtr<Font> FontCache::fontForFamily(const FontDescription& fontDescription, const AtomicString& family, bool checkingAlternateName)
 {
     if (!m_purgeTimer.isActive())
         m_purgeTimer.startOneShot(std::chrono::milliseconds::zero());
@@ -391,7 +382,7 @@ RefPtr<SimpleFontData> FontCache::fontForFamily(const FontDescription& fontDescr
     return fontForPlatformData(*platformData);
 }
 
-Ref<SimpleFontData> FontCache::fontForPlatformData(const FontPlatformData& platformData)
+Ref<Font> FontCache::fontForPlatformData(const FontPlatformData& platformData)
 {
 #if PLATFORM(IOS)
     FontLocker fontLocker;
@@ -399,7 +390,7 @@ Ref<SimpleFontData> FontCache::fontForPlatformData(const FontPlatformData& platf
     
     auto addResult = cachedFonts().add(platformData, nullptr);
     if (addResult.isNewEntry)
-        addResult.iterator->value = SimpleFontData::create(platformData);
+        addResult.iterator->value = Font::create(platformData);
 
     return *addResult.iterator->value;
 }
@@ -411,37 +402,43 @@ void FontCache::purgeTimerFired()
 
 void FontCache::purgeInactiveFontDataIfNeeded()
 {
-    bool underMemoryPressure = memoryPressureHandler().isUnderMemoryPressure();
-    int inactiveFontDataLimit = underMemoryPressure ? cMaxUnderMemoryPressureInactiveFontData : cMaxInactiveFontData;
+    bool underMemoryPressure = MemoryPressureHandler::singleton().isUnderMemoryPressure();
+    unsigned inactiveFontDataLimit = underMemoryPressure ? cMaxUnderMemoryPressureInactiveFontData : cMaxInactiveFontData;
 
     if (cachedFonts().size() < inactiveFontDataLimit)
         return;
-    int inactiveCount = inactiveFontDataCount();
+    unsigned inactiveCount = inactiveFontCount();
     if (inactiveCount <= inactiveFontDataLimit)
         return;
 
-    int targetFontDataLimit = underMemoryPressure ? cTargetUnderMemoryPressureInactiveFontData : cTargetInactiveFontData;
+    unsigned targetFontDataLimit = underMemoryPressure ? cTargetUnderMemoryPressureInactiveFontData : cTargetInactiveFontData;
     purgeInactiveFontData(inactiveCount - targetFontDataLimit);
 }
 
-void FontCache::purgeInactiveFontData(int purgeCount)
+void FontCache::purgeInactiveFontData(unsigned purgeCount)
 {
-    pruneUnreferencedEntriesFromFontGlyphsCache();
+    pruneUnreferencedEntriesFromFontCascadeCache();
+    pruneSystemFallbackFonts();
 
 #if PLATFORM(IOS)
     FontLocker fontLocker;
 #endif
 
-    Vector<RefPtr<SimpleFontData>, 20> fontsToDelete;
-    for (auto& font : cachedFonts().values()) {
-        if (!font->hasOneRef())
-            continue;
-        fontsToDelete.append(WTF::move(font));
-        if (!--purgeCount)
+    while (purgeCount) {
+        Vector<RefPtr<Font>, 20> fontsToDelete;
+        for (auto& font : cachedFonts().values()) {
+            if (!font->hasOneRef())
+                continue;
+            fontsToDelete.append(WTF::move(font));
+            if (!--purgeCount)
+                break;
+        }
+        // Fonts may ref other fonts so we loop until there are no changes.
+        if (fontsToDelete.isEmpty())
             break;
-    }
-    for (auto& font : fontsToDelete)
-        cachedFonts().remove(font->platformData());
+        for (auto& font : fontsToDelete)
+            cachedFonts().remove(font->platformData());
+    };
 
     Vector<FontPlatformDataCacheKey> keysToRemove;
     keysToRemove.reserveInitialCapacity(fontPlatformDataCache().size());
@@ -460,8 +457,8 @@ void FontCache::purgeInactiveFontData(int purgeCount)
             if (verticalData)
                 verticalData->m_inFontCache = false;
         }
-        for (auto& fontData : cachedFonts().values()) {
-            auto* verticalData = const_cast<OpenTypeVerticalData*>(fontData->verticalData());
+        for (auto& font : cachedFonts().values()) {
+            auto* verticalData = const_cast<OpenTypeVerticalData*>(font->verticalData());
             if (verticalData)
                 verticalData->m_inFontCache = true;
         }
@@ -477,12 +474,12 @@ void FontCache::purgeInactiveFontData(int purgeCount)
 #endif
 }
 
-size_t FontCache::fontDataCount()
+size_t FontCache::fontCount()
 {
     return cachedFonts().size();
 }
 
-size_t FontCache::inactiveFontDataCount()
+size_t FontCache::inactiveFontCount()
 {
 #if PLATFORM(IOS)
     FontLocker fontLocker;
@@ -529,7 +526,7 @@ void FontCache::invalidate()
     }
 
     fontPlatformDataCache().clear();
-    invalidateFontGlyphsCache();
+    invalidateFontCascadeCache();
 
     gGeneration++;
 
@@ -545,7 +542,7 @@ void FontCache::invalidate()
 }
 
 #if !PLATFORM(COCOA)
-RefPtr<SimpleFontData> FontCache::similarFontPlatformData(const FontDescription&)
+RefPtr<Font> FontCache::similarFont(const FontDescription&)
 {
     return nullptr;
 }