Changeset 177979 in webkit


Ignore:
Timestamp:
Jan 6, 2015, 11:37:42 AM (10 years ago)
Author:
Antti Koivisto
Message:

REGRESSION (r177876): 35% regression in Parser/html5-full-render
https://bugs.webkit.org/show_bug.cgi?id=140123

Reviewed by Darin Adler.

Resolving system fallbacks is extremely slow. GlyphPageTree used to cache them globally.

This patch brings back a simple global cache for system fallbacks.

  • platform/graphics/SimpleFontData.cpp:

(WebCore::SimpleFontData::~SimpleFontData):
(WebCore::systemFallbackCache):
(WebCore::SimpleFontData::systemFallbackFontDataForCharacter):
(WebCore::SimpleFontData::removeFromSystemFallbackCache):

  • platform/graphics/SimpleFontData.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r177975 r177979  
     12015-01-06  Antti Koivisto  <antti@apple.com>
     2
     3        REGRESSION (r177876): 35% regression in Parser/html5-full-render
     4        https://bugs.webkit.org/show_bug.cgi?id=140123
     5
     6        Reviewed by Darin Adler.
     7
     8        Resolving system fallbacks is extremely slow. GlyphPageTree used to cache them globally.
     9
     10        This patch brings back a simple global cache for system fallbacks.
     11
     12        * platform/graphics/SimpleFontData.cpp:
     13        (WebCore::SimpleFontData::~SimpleFontData):
     14        (WebCore::systemFallbackCache):
     15        (WebCore::SimpleFontData::systemFallbackFontDataForCharacter):
     16        (WebCore::SimpleFontData::removeFromSystemFallbackCache):
     17        * platform/graphics/SimpleFontData.h:
     18
    1192015-01-06  Antti Koivisto  <antti@apple.com>
    220
  • trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp

    r177975 r177979  
    157157    if (!isSVGFont())
    158158        platformDestroy();
     159
     160    removeFromSystemFallbackCache();
    159161}
    160162
     
    197199    unsigned bufferLength;
    198200    // Fill in a buffer with the entire "page" of characters that we want to look up glyphs for.
    199     if (start < 0x10000) {
     201    if (U_IS_BMP(start)) {
    200202        bufferLength = GlyphPage::size;
    201203        for (unsigned i = 0; i < GlyphPage::size; i++)
     
    428430}
    429431
    430 RefPtr<SimpleFontData> SimpleFontData::systemFallbackFontDataForCharacter(UChar32 c, const FontDescription& description, bool isForPlatformFont) const
    431 {
    432     UChar codeUnits[2];
    433     int codeUnitsLength;
    434     if (c <= 0xFFFF) {
    435         codeUnits[0] = Font::normalizeSpaces(c);
    436         codeUnitsLength = 1;
    437     } else {
    438         codeUnits[0] = U16_LEAD(c);
    439         codeUnits[1] = U16_TRAIL(c);
    440         codeUnitsLength = 2;
    441     }
    442 
    443     return fontCache().systemFallbackForCharacters(description, this, isForPlatformFont, codeUnits, codeUnitsLength);
     432// FontDatas are not refcounted to avoid cycles.
     433typedef HashMap<std::pair<UChar32, unsigned>, SimpleFontData*> CharacterFallbackMap;
     434typedef HashMap<const SimpleFontData*, CharacterFallbackMap> SystemFallbackCache;
     435
     436static SystemFallbackCache& systemFallbackCache()
     437{
     438    static NeverDestroyed<SystemFallbackCache> map;
     439    return map.get();
     440}
     441
     442RefPtr<SimpleFontData> SimpleFontData::systemFallbackFontDataForCharacter(UChar32 character, const FontDescription& description, bool isForPlatformFont) const
     443{
     444    auto fontAddResult = systemFallbackCache().add(this, CharacterFallbackMap());
     445
     446    auto key = std::make_pair(character, isForPlatformFont);
     447    auto characterAddResult = fontAddResult.iterator->value.add(key, nullptr);
     448
     449    SimpleFontData*& fallbackFontData = characterAddResult.iterator->value;
     450
     451    if (!fallbackFontData) {
     452        UChar codeUnits[2];
     453        int codeUnitsLength;
     454        if (U_IS_BMP(character)) {
     455            codeUnits[0] = Font::normalizeSpaces(character);
     456            codeUnitsLength = 1;
     457        } else {
     458            codeUnits[0] = U16_LEAD(character);
     459            codeUnits[1] = U16_TRAIL(character);
     460            codeUnitsLength = 2;
     461        }
     462
     463        fallbackFontData = fontCache().systemFallbackForCharacters(description, this, false, codeUnits, codeUnitsLength).get();
     464        if (fallbackFontData)
     465            fallbackFontData->m_isUsedInSystemFallbackCache = true;
     466    }
     467
     468    return fallbackFontData;
     469}
     470
     471void SimpleFontData::removeFromSystemFallbackCache()
     472{
     473    systemFallbackCache().remove(this);
     474
     475    if (!m_isUsedInSystemFallbackCache)
     476        return;
     477
     478    for (auto& characterMap : systemFallbackCache().values()) {
     479        Vector<std::pair<UChar32, unsigned>, 512> toRemove;
     480        for (auto& entry : characterMap) {
     481            if (entry.value == this)
     482                toRemove.append(entry.key);
     483        }
     484        for (auto& key : toRemove)
     485            characterMap.remove(key);
     486    }
    444487}
    445488
  • trunk/Source/WebCore/platform/graphics/SimpleFontData.h

    r177975 r177979  
    233233    virtual const SimpleFontData& simpleFontDataForFirstRange() const override;
    234234
     235    void removeFromSystemFallbackCache();
     236
    235237#if PLATFORM(WIN)
    236238    void initGDIFont();
     
    264266    bool m_isTextOrientationFallback;
    265267    bool m_isBrokenIdeographFallback;
     268
     269    bool m_isUsedInSystemFallbackCache { false };
     270
    266271    mutable RefPtr<OpenTypeMathData> m_mathData;
    267272#if ENABLE(OPENTYPE_VERTICAL)
Note: See TracChangeset for help on using the changeset viewer.