Changeset 201551 in webkit


Ignore:
Timestamp:
Jun 1, 2016, 7:29:30 AM (9 years ago)
Author:
Antti Koivisto
Message:

Precache primary font in a secondary thread
https://bugs.webkit.org/show_bug.cgi?id=158243

Reviewed by Andreas Kling.

We know the font families and descriptions to use on style resolution. The actual fonts are only needed for
layout. There is often time to load and cache fonts asynchronously before they are accessed. This can substantially
reduce font related workload in the main thread.

  • css/CSSFontFace.cpp:

(WebCore::CSSFontFace::font):
(WebCore::CSSFontFace::resolveFamilies):
(WebCore::CSSFontFace::hasSVGFontFaceSource):

  • css/CSSFontFace.h:
  • css/CSSFontFaceSource.cpp:

(WebCore::CSSFontFaceSource::font):
(WebCore::CSSFontFaceSource::url):
(WebCore::CSSFontFaceSource::isSVGFontFaceSource):

  • css/CSSFontFaceSource.h:
  • css/CSSFontSelector.cpp:

(WebCore::CSSFontSelector::fallbackFontAt):
(WebCore::CSSFontSelector::resolveFamilies):

Add a function for resolving font families of a cascade to their final values.

  • css/CSSFontSelector.h:
  • css/CSSSegmentedFontFace.cpp:

(WebCore::CSSSegmentedFontFace::fontRanges):
(WebCore::CSSSegmentedFontFace::resolveFamilies):

  • css/CSSSegmentedFontFace.h:
  • platform/graphics/FontCache.cpp:

(WebCore::fontPlatformDataCache):
(WebCore::precacheTasksInProgress):
(WebCore::alternateFamilyName):
(WebCore::FontCache::getCachedFontPlatformData):
(WebCore::FontCache::invalidate):
(WebCore::FontCache::precache):

Precache fonts by trying to load them asyncronously one by one. On success the font is cached into font platform data cache.

(WebCore::FontCache::similarFont):

  • platform/graphics/FontCache.h:
  • platform/graphics/FontCascade.cpp:

(WebCore::pruneSystemFallbackFonts):
(WebCore::precachePrimaryFamily):

When initializing a new font cascade resolve any platform fonts to their actual names using FontSelector,
then precache the primary font for the cascade.

Web fonts are ignored for now.

(WebCore::retrieveOrAddCachedFonts):

  • platform/graphics/FontSelector.h:

(WebCore::FontSelector::~FontSelector):

  • platform/graphics/cocoa/FontCacheCoreText.cpp:

(WebCore::FontCache::setFontWhitelist):
(WebCore::fontWithFamily):
(WebCore::autoActivateFont):
(WebCore::createFontPlatformDataThreadSafe):

Factor thread safe part of createFontPlatformData to a function.

(WebCore::FontCache::createFontPlatformData):

Do the main thread only hash lookups here then call to createFontPlatformDataThreadSafe.

(WebCore::fallbackDedupSet):
(WebCore::FontCache::systemFallbackForCharacters):
(WebCore::FontCache::platformPrecache):

Try to initialize font asynchronously in a dispatch queue, call completion handler on success or failure.

(WebCore::FontCache::platformCancelPrecache):

Cancel ongoing precache operation.

(WebCore::platformFontLookupWithFamily): Deleted.

This was inlined to the only client, fontWithFamily.

Location:
trunk/Source/WebCore
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r201549 r201551  
     12016-05-31  Antti Koivisto  <antti@apple.com>
     2
     3        Precache primary font in a secondary thread
     4        https://bugs.webkit.org/show_bug.cgi?id=158243
     5
     6        Reviewed by Andreas Kling.
     7
     8        We know the font families and descriptions to use on style resolution. The actual fonts are only needed for
     9        layout. There is often time to load and cache fonts asynchronously before they are accessed. This can substantially
     10        reduce font related workload in the main thread.
     11
     12        * css/CSSFontFace.cpp:
     13        (WebCore::CSSFontFace::font):
     14        (WebCore::CSSFontFace::resolveFamilies):
     15        (WebCore::CSSFontFace::hasSVGFontFaceSource):
     16        * css/CSSFontFace.h:
     17        * css/CSSFontFaceSource.cpp:
     18        (WebCore::CSSFontFaceSource::font):
     19        (WebCore::CSSFontFaceSource::url):
     20        (WebCore::CSSFontFaceSource::isSVGFontFaceSource):
     21        * css/CSSFontFaceSource.h:
     22        * css/CSSFontSelector.cpp:
     23        (WebCore::CSSFontSelector::fallbackFontAt):
     24        (WebCore::CSSFontSelector::resolveFamilies):
     25
     26            Add a function for resolving font families of a cascade to their final values.
     27
     28        * css/CSSFontSelector.h:
     29        * css/CSSSegmentedFontFace.cpp:
     30        (WebCore::CSSSegmentedFontFace::fontRanges):
     31        (WebCore::CSSSegmentedFontFace::resolveFamilies):
     32        * css/CSSSegmentedFontFace.h:
     33        * platform/graphics/FontCache.cpp:
     34        (WebCore::fontPlatformDataCache):
     35        (WebCore::precacheTasksInProgress):
     36        (WebCore::alternateFamilyName):
     37        (WebCore::FontCache::getCachedFontPlatformData):
     38        (WebCore::FontCache::invalidate):
     39        (WebCore::FontCache::precache):
     40
     41            Precache fonts by trying to load them asyncronously one by one. On success the font is cached into font platform data cache.
     42
     43        (WebCore::FontCache::similarFont):
     44        * platform/graphics/FontCache.h:
     45        * platform/graphics/FontCascade.cpp:
     46        (WebCore::pruneSystemFallbackFonts):
     47        (WebCore::precachePrimaryFamily):
     48
     49            When initializing a new font cascade resolve any platform fonts to their actual names using FontSelector,
     50            then precache the primary font for the cascade.
     51
     52            Web fonts are ignored for now.
     53
     54        (WebCore::retrieveOrAddCachedFonts):
     55        * platform/graphics/FontSelector.h:
     56        (WebCore::FontSelector::~FontSelector):
     57        * platform/graphics/cocoa/FontCacheCoreText.cpp:
     58        (WebCore::FontCache::setFontWhitelist):
     59        (WebCore::fontWithFamily):
     60        (WebCore::autoActivateFont):
     61        (WebCore::createFontPlatformDataThreadSafe):
     62
     63            Factor thread safe part of createFontPlatformData to a function.
     64
     65        (WebCore::FontCache::createFontPlatformData):
     66
     67            Do the main thread only hash lookups here then call to createFontPlatformDataThreadSafe.
     68
     69        (WebCore::fallbackDedupSet):
     70        (WebCore::FontCache::systemFallbackForCharacters):
     71        (WebCore::FontCache::platformPrecache):
     72
     73            Try to initialize font asynchronously in a dispatch queue, call completion handler on success or failure.
     74
     75        (WebCore::FontCache::platformCancelPrecache):
     76
     77            Cancel ongoing precache operation.
     78
     79        (WebCore::platformFontLookupWithFamily): Deleted.
     80
     81            This was inlined to the only client, fontWithFamily.
     82
    1832016-06-01  Adam Bergkvist  <adam.bergkvist@ericsson.com>
    284
  • trunk/Source/WebCore/css/CSSFontFace.cpp

    r201358 r201551  
    521521}
    522522
     523Vector<ResolvedFontFamily> CSSFontFace::resolveFamilies() const
     524{
     525    Vector<ResolvedFontFamily> result;
     526    for (auto& source : m_sources) {
     527        if (source->familyNameOrURI().isEmpty())
     528            continue;
     529        if (source->status() == CSSFontFaceSource::Status::Failure)
     530            continue;
     531        result.append({ source->familyNameOrURI(), source->url() });
     532    }
     533    return result;
     534}
     535
    523536#if ENABLE(SVG_FONTS)
    524537bool CSSFontFace::hasSVGFontFaceSource() const
  • trunk/Source/WebCore/css/CSSFontFace.h

    r200547 r201551  
    2828#include "CSSFontFaceRule.h"
    2929#include "FontFeatureSettings.h"
     30#include "FontSelector.h"
    3031#include "TextFlags.h"
    3132#include <memory>
     
    136137    Ref<FontFace> wrapper();
    137138
     139    Vector<ResolvedFontFamily> resolveFamilies() const;
     140
    138141#if ENABLE(SVG_FONTS)
    139142    bool hasSVGFontFaceSource() const;
  • trunk/Source/WebCore/css/CSSFontFaceSource.cpp

    r200921 r201551  
    189189}
    190190
     191Optional<URL> CSSFontFaceSource::url() const
     192{
     193    if (!m_font)
     194        return Nullopt;
     195    return m_font->url();
     196}
     197
    191198#if ENABLE(SVG_FONTS)
    192199bool CSSFontFaceSource::isSVGFontFaceSource() const
  • trunk/Source/WebCore/css/CSSFontFaceSource.h

    r200921 r201551  
    2929#include "CachedFontClient.h"
    3030#include "CachedResourceHandle.h"
     31#include "URL.h"
    3132#include <runtime/ArrayBufferView.h>
    3233#include <wtf/text/AtomicString.h>
     
    7273#endif
    7374
     75    Optional<URL> url() const;
     76
    7477private:
    7578    void fontLoaded(CachedFont&) override;
  • trunk/Source/WebCore/css/CSSFontSelector.cpp

    r200895 r201551  
    335335}
    336336
    337 }
     337Vector<ResolvedFontFamily> CSSFontSelector::resolveFamilies(const Vector<AtomicString>& families, const FontDescription& fontDescription, UChar32 character)
     338{
     339    Vector<ResolvedFontFamily> result;
     340
     341    for (auto& family : families) {
     342        if (family.isEmpty())
     343            continue;
     344        auto* segmentedFace = m_cssFontFaceSet->getFontFace(fontDescription.traitsMask(), family);
     345        if (!segmentedFace) {
     346            result.append({ resolveGenericFamily(m_document, fontDescription, family), { } });
     347            continue;
     348        }
     349        result.appendVector(segmentedFace->resolveFamilies(character));
     350    }
     351
     352    return result;
     353}
     354
     355}
  • trunk/Source/WebCore/css/CSSFontSelector.h

    r197563 r201551  
    6565    RefPtr<Font> fallbackFontAt(const FontDescription&, size_t) override;
    6666
     67    Vector<ResolvedFontFamily> resolveFamilies(const Vector<AtomicString>&, const FontDescription&, UChar32) override;
     68
    6769    void clearDocument();
    6870
  • trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp

    r200803 r201551  
    139139}
    140140
     141Vector<ResolvedFontFamily> CSSSegmentedFontFace::resolveFamilies(UChar32 character) const
     142{
     143    for (auto& face : m_fontFaces) {
     144        bool inRange = face->ranges().isEmpty();
     145        for (auto& range : face->ranges()) {
     146            if (character >= range.from && character <= range.to) {
     147                inRange = true;
     148                break;
     149            }
     150        }
     151        if (inRange)
     152            return face->resolveFamilies();
     153    }
     154    return { };
    141155}
     156
     157}
  • trunk/Source/WebCore/css/CSSSegmentedFontFace.h

    r201113 r201551  
    2929#include "CSSFontFace.h"
    3030#include "FontCache.h"
     31#include "FontSelector.h"
    3132#include <wtf/HashMap.h>
    3233#include <wtf/RefCounted.h>
     
    5859    void deref() override { RefCounted<CSSSegmentedFontFace>::deref(); }
    5960
     61    Vector<ResolvedFontFamily> resolveFamilies(UChar32 character) const;
     62
    6063private:
    6164    CSSSegmentedFontFace();
  • trunk/Source/WebCore/platform/graphics/FontCache.cpp

    r200364 r201551  
    107107        , m_fontFaceVariantSettings(fontFaceVariantSettings ? *fontFaceVariantSettings : FontVariantSettings())
    108108    { }
     109    FontPlatformDataCacheKey(const FontPlatformDataCacheKey&) = default;
    109110
    110111    explicit FontPlatformDataCacheKey(HashTableDeletedValueType t)
     
    160161}
    161162
     163#if PLATFORM(COCOA) && ENABLE(PLATFORM_FONT_LOOKUP)
     164using PrecacheMap = HashMap<FontPlatformDataCacheKey, FontCache::PrecacheTask*, FontPlatformDataCacheKeyHash, WTF::SimpleClassHashTraits<FontPlatformDataCacheKey>>;
     165
     166static PrecacheMap& precacheTasksInProgress()
     167{
     168    static NeverDestroyed<PrecacheMap> map;
     169    return map;
     170}
     171#endif
     172
    162173static AtomicString alternateFamilyName(const AtomicString& familyName)
    163174{
     
    243254
    244255    FontPlatformDataCacheKey key(familyName, fontDescription, fontFaceFeatures, fontFaceVariantSettings);
     256
     257#if PLATFORM(COCOA) && ENABLE(PLATFORM_FONT_LOOKUP)
     258    auto* precacheTask = precacheTasksInProgress().get(key);
     259    if (precacheTask)
     260        platformCancelPrecache(*precacheTask);
     261#endif
    245262
    246263    auto addResult = fontPlatformDataCache().add(key, nullptr);
     
    490507}
    491508
     509#if PLATFORM(COCOA) && ENABLE(PLATFORM_FONT_LOOKUP)
     510void FontCache::precache(const Vector<AtomicString>& resolvedFamilies, const FontDescription& fontDescription)
     511{
     512    if (resolvedFamilies.isEmpty())
     513        return;
     514    auto& family = resolvedFamilies.first();
     515
     516    FontPlatformDataCacheKey key(family, fontDescription, nullptr, nullptr);
     517
     518    // Maybe we have it already?
     519    auto it = fontPlatformDataCache().find(key);
     520    if (it != fontPlatformDataCache().end()) {
     521        if (it->value)
     522            return;
     523
     524        // We already know this font isn't available. Try the next.
     525        Vector<AtomicString> remainingFamilies;
     526        remainingFamilies.appendRange(resolvedFamilies.begin() + 1, resolvedFamilies.end());
     527        precache(remainingFamilies, fontDescription);
     528        return;
     529    }
     530
     531    auto taskAdd = precacheTasksInProgress().add(key, nullptr);
     532    if (!taskAdd.isNewEntry)
     533        return;
     534
     535    auto& task = platformPrecache(family, fontDescription, [key, resolvedFamilies, fontDescription] (auto platformData, bool wasCanceled) {
     536        precacheTasksInProgress().remove(key);
     537
     538        if (wasCanceled)
     539            return;
     540
     541        if (platformData) {
     542            auto r = fontPlatformDataCache().add(key, WTFMove(platformData));
     543            fprintf(stderr, "success %d\n", r.isNewEntry);
     544            return;
     545        }
     546
     547        // Didn't find the font. Try the next one.
     548        Vector<AtomicString> remainingFamilies;
     549
     550        auto alternateName = alternateFamilyName(resolvedFamilies.first());
     551        if (!alternateName.isNull()) {
     552            remainingFamilies = resolvedFamilies;
     553            remainingFamilies.first() = alternateName;
     554        } else {
     555            fontPlatformDataCache().add(key, nullptr);
     556            remainingFamilies.appendRange(resolvedFamilies.begin() + 1, resolvedFamilies.end());
     557        }
     558
     559        singleton().precache(remainingFamilies, fontDescription);
     560    });
     561
     562    taskAdd.iterator->value = &task;
     563}
     564#else
     565void FontCache::precache(const Vector<AtomicString>&, const FontDescription&)
     566{
     567}
     568#endif
     569
    492570#if !PLATFORM(COCOA)
    493571RefPtr<Font> FontCache::similarFont(const FontDescription&, const AtomicString&)
  • trunk/Source/WebCore/platform/graphics/FontCache.h

    r200237 r201551  
    194194    RefPtr<Font> similarFont(const FontDescription&, const AtomicString& family);
    195195
     196    void precache(const Vector<AtomicString>& resolvedFamilies, const FontDescription&);
     197
    196198    void addClient(FontSelector&);
    197199    void removeClient(FontSelector&);
     
    213215#endif
    214216
     217    struct PrecacheTask;
     218
    215219private:
    216220    FontCache();
     
    227231#endif
    228232    std::unique_ptr<FontPlatformData> createFontPlatformData(const FontDescription&, const AtomicString& family, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings);
     233
     234#if PLATFORM(COCOA) && ENABLE(PLATFORM_FONT_LOOKUP)
     235    using PrecacheCompletionHandler = std::function<void (std::unique_ptr<FontPlatformData>, bool wasCanceled)>;
     236    PrecacheTask& platformPrecache(const AtomicString& family, const FontDescription&, PrecacheCompletionHandler&&);
     237    void platformCancelPrecache(PrecacheTask&);
     238#endif
    229239
    230240    Timer m_purgeTimer;
  • trunk/Source/WebCore/platform/graphics/FontCascade.cpp

    r201333 r201551  
    262262}
    263263
     264static void precachePrimaryFamily(const FontCascadeDescription& fontDescription, FontSelector& fontSelector)
     265{
     266    Vector<AtomicString> families;
     267    for (unsigned i = 0; i < fontDescription.familyCount(); ++i)
     268        families.append(fontDescription.familyAt(i));
     269
     270    // Primary family lookup falls back to the standard family.
     271    families.append(standardFamily);
     272
     273    auto resolvedPrimaryFamilies = fontSelector.resolveFamilies(families, fontDescription, ' ');
     274
     275    Vector<AtomicString> resolvedPrimaryFamilyNames;
     276    for (auto& family : resolvedPrimaryFamilies) {
     277        // This doesn't handle web fonts for now.
     278        if (family.url)
     279            break;
     280        resolvedPrimaryFamilyNames.append(family.name);
     281    }
     282
     283    // Asynchronously find first available font and precache it so it is likely to be available when needed.
     284    FontCache::singleton().precache(resolvedPrimaryFamilyNames, fontDescription);
     285}
     286
    264287static Ref<FontCascadeFonts> retrieveOrAddCachedFonts(const FontCascadeDescription& fontDescription, RefPtr<FontSelector>&& fontSelector)
    265288{
     
    270293    if (!addResult.isNewEntry && keysMatch(addResult.iterator->value->key, key))
    271294        return addResult.iterator->value->fonts.get();
     295
     296    if (fontSelector)
     297        precachePrimaryFamily(fontDescription, *fontSelector);
    272298
    273299    auto& newEntry = addResult.iterator->value;
  • trunk/Source/WebCore/platform/graphics/FontSelector.h

    r200601 r201551  
    2727
    2828#include "FontRanges.h"
     29#include "URL.h"
    2930#include <wtf/Forward.h>
    3031#include <wtf/PassRefPtr.h>
     
    4546};
    4647
     48struct ResolvedFontFamily {
     49    AtomicString name;
     50    Optional<URL> url;
     51};
     52
    4753class FontSelector : public RefCounted<FontSelector> {
    4854public:
     
    5965    virtual void unregisterForInvalidationCallbacks(FontSelectorClient&) = 0;
    6066
     67    virtual Vector<ResolvedFontFamily> resolveFamilies(const Vector<AtomicString>& families, const FontDescription&, UChar32 character) = 0;
     68
    6169    virtual unsigned uniqueId() const = 0;
    6270    virtual unsigned version() const = 0;
  • trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp

    r200094 r201551  
    3535#include <wtf/MainThread.h>
    3636#include <wtf/NeverDestroyed.h>
     37#include <wtf/RunLoop.h>
     38#include <wtf/WorkQueue.h>
    3739
    3840namespace WebCore {
     
    661663}
    662664
    663 #if ENABLE(PLATFORM_FONT_LOOKUP)
    664 static RetainPtr<CTFontRef> platformFontLookupWithFamily(const AtomicString& family, CTFontSymbolicTraits requestedTraits, FontWeight weight, float size)
    665 {
    666     const auto& whitelist = fontWhitelist();
    667     if (whitelist.size() && !whitelist.contains(family))
    668         return nullptr;
    669 
    670     return adoptCF(CTFontCreateForCSS(family.string().createCFString().get(), toCoreTextFontWeight(weight), requestedTraits, size));
    671 }
    672 #endif
    673 
    674 static RetainPtr<CTFontRef> fontWithFamily(const AtomicString& family, CTFontSymbolicTraits desiredTraits, FontWeight weight, const FontFeatureSettings& featureSettings, const FontVariantSettings& variantSettings, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, const TextRenderingMode& textRenderingMode, float size)
     665static RetainPtr<CTFontRef> fontWithFamily(const String& family, CTFontSymbolicTraits desiredTraits, FontWeight weight, const FontFeatureSettings& featureSettings, const FontVariantSettings& variantSettings, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, const TextRenderingMode& textRenderingMode, float size, bool isWhitelisted)
    675666{
    676667    if (family.isEmpty())
     
    680671    if (!foundFont) {
    681672#if ENABLE(PLATFORM_FONT_LOOKUP)
    682         foundFont = platformFontLookupWithFamily(family, desiredTraits, weight, size);
     673        if (!isWhitelisted)
     674            return nullptr;
     675        foundFont = adoptCF(CTFontCreateForCSS(family.createCFString().get(), toCoreTextFontWeight(weight), desiredTraits, size));
    683676#else
     677        UNUSED_PARAM(isWhitelisted);
    684678        foundFont = platformFontWithFamily(family, desiredTraits, weight, textRenderingMode, size);
    685679#endif
     
    720714#endif
    721715
    722 std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings)
     716// This is only thread safe with ENABLE(PLATFORM_FONT_LOOKUP) due to fontWithFamily() implementation
     717static std::unique_ptr<FontPlatformData> createFontPlatformDataThreadSafe(const FontDescription& fontDescription, const String& family, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings, bool isWhitelisted, bool shouldAutoActivateIfNeeded)
    723718{
    724719    CTFontSymbolicTraits traits = computeTraits(fontDescription);
    725720    float size = fontDescription.computedPixelSize();
    726721
    727     RetainPtr<CTFontRef> font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontFaceFeatures, fontFaceVariantSettings, fontDescription.textRenderingMode(), size);
     722    RetainPtr<CTFontRef> font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontFaceFeatures, fontFaceVariantSettings, fontDescription.textRenderingMode(), size, isWhitelisted);
    728723
    729724#if PLATFORM(MAC)
    730     if (!font) {
    731         if (!shouldAutoActivateFontIfNeeded(family))
    732             return nullptr;
    733 
     725    if (!font && shouldAutoActivateIfNeeded) {
    734726        // Auto activate the font before looking for it a second time.
    735727        // Ignore the result because we want to use our own algorithm to actually find the font.
    736         autoActivateFont(family.string(), size);
    737 
    738         font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontFaceFeatures, fontFaceVariantSettings, fontDescription.textRenderingMode(), size);
    739     }
     728        autoActivateFont(family, size);
     729
     730        font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontFaceFeatures, fontFaceVariantSettings, fontDescription.textRenderingMode(), size, isWhitelisted);
     731    }
     732#else
     733    UNUSED_PARAM(shouldAutoActivateIfNeeded);
    740734#endif
    741735
     
    747741
    748742    return std::make_unique<FontPlatformData>(font.get(), size, syntheticBold, syntheticOblique, fontDescription.orientation(), fontDescription.widthVariant(), fontDescription.textRenderingMode());
     743}
     744
     745std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family, const FontFeatureSettings* fontFaceFeatures, const FontVariantSettings* fontFaceVariantSettings)
     746{
     747    const auto& whitelist = fontWhitelist();
     748    bool isWhitelisted = whitelist.isEmpty() || whitelist.contains(family);
     749
     750    bool shouldAutoActivateIfNeeded = false;
     751#if PLATFORM(MAC)
     752    shouldAutoActivateIfNeeded = shouldAutoActivateFontIfNeeded(family);
     753#endif
     754
     755    return createFontPlatformDataThreadSafe(fontDescription, family, fontFaceFeatures, fontFaceVariantSettings, isWhitelisted, shouldAutoActivateIfNeeded);
    749756}
    750757
     
    797804}
    798805
    799 }
     806#if ENABLE(PLATFORM_FONT_LOOKUP)
     807struct FontCache::PrecacheTask {
     808    String family;
     809    FontDescription fontDescription;
     810    bool shouldAutoActivateIfNeeded { false };
     811    bool isWhitelisted { true };
     812    PrecacheCompletionHandler completionHandler;
     813
     814    std::unique_ptr<FontPlatformData> result;
     815    std::atomic_bool isCanceled { false };
     816};
     817
     818FontCache::PrecacheTask& FontCache::platformPrecache(const AtomicString& family, const FontDescription& fontDescription, PrecacheCompletionHandler&& completionHandler)
     819{
     820    static WorkQueue& queue = WorkQueue::create("org.webkit.font-precache", WorkQueue::Type::Serial, WorkQueue::QOS::UserInitiated).leakRef();
     821
     822    auto task = std::make_unique<PrecacheTask>();
     823    task->family = family;
     824    task->fontDescription = fontDescription;
     825    const auto& whitelist = fontWhitelist();
     826    task->isWhitelisted = whitelist.isEmpty() || whitelist.contains(family);
     827#if PLATFORM(MAC)
     828    task->shouldAutoActivateIfNeeded = shouldAutoActivateFontIfNeeded(family);
     829#endif
     830    task->completionHandler = WTFMove(completionHandler);
     831
     832    auto& resultTask = *task;
     833
     834    queue.dispatch([task = task.release()] {
     835        if (!task->isCanceled) {
     836            auto family = task->family.isolatedCopy();
     837            task->result = createFontPlatformDataThreadSafe(task->fontDescription, family, nullptr, nullptr, task->isWhitelisted, task->shouldAutoActivateIfNeeded);
     838        }
     839
     840        RunLoop::main().dispatch([task] {
     841            std::unique_ptr<PrecacheTask> deleter(task);
     842            task->completionHandler(WTFMove(task->result), task->isCanceled);
     843        });
     844    });
     845
     846    return resultTask;
     847}
     848
     849void FontCache::platformCancelPrecache(FontCache::PrecacheTask& task)
     850{
     851    task.isCanceled = true;
     852}
     853#endif
     854
     855}
Note: See TracChangeset for help on using the changeset viewer.