1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef _NS_FONTCACHE_H_
7 #define _NS_FONTCACHE_H_
10 #include <sys/types.h>
11 #include "mozilla/RefPtr.h"
13 #include "nsFontMetrics.h"
14 #include "nsIObserver.h"
15 #include "nsISupports.h"
17 #include "nsThreadUtils.h"
25 class nsFontCache final
: public nsIObserver
{
27 nsFontCache() : mContext(nullptr) {}
29 NS_DECL_THREADSAFE_ISUPPORTS
32 void Init(nsPresContext
* aContext
);
35 already_AddRefed
<nsFontMetrics
> GetMetricsFor(
36 const nsFont
& aFont
, const nsFontMetrics::Params
& aParams
);
38 void FontMetricsDeleted(const nsFontMetrics
* aFontMetrics
);
41 // Flush aFlushCount oldest entries, or all if aFlushCount is negative
42 void Flush(int32_t aFlushCount
= -1);
44 void UpdateUserFonts(gfxUserFontSet
* aUserFontSet
);
47 // If the array of cached entries is about to exceed this threshold,
48 // we'll discard the oldest ones so as to keep the size reasonable.
49 // In practice, the great majority of cache hits are among the last
50 // few entries; keeping thousands of older entries becomes counter-
51 // productive because it can then take too long to scan the cache.
52 static constexpr int32_t kMaxCacheEntries
= 128;
54 // Number of cache misses before we assume that a font fingerprinting attempt
55 // is being made. Usually fingerprinters will lookup the same font-family
56 // three times, as "sans-serif", "serif" and "monospace".
57 static constexpr int32_t kFingerprintingCacheMissThreshold
= 3 * 20;
58 // We assume that fingerprinters will lookup a large number of fonts in a
59 // short amount of time.
60 static constexpr PRTime kFingerprintingTimeout
=
61 PRTime(PR_USEC_PER_SEC
) * 3; // 3 seconds
63 static_assert(kFingerprintingCacheMissThreshold
< kMaxCacheEntries
);
65 ~nsFontCache() = default;
67 nsPresContext
* mContext
; // owner
68 RefPtr
<nsAtom
> mLocaleLanguage
;
70 // We may not flush older entries immediately the array reaches
71 // kMaxCacheEntries length, because this usually happens on a stylo
72 // thread where we can't safely delete metrics objects. So we allocate an
73 // oversized autoarray buffer here, so that we're unlikely to overflow
74 // it and need separate heap allocation before the flush happens on the
76 AutoTArray
<nsFontMetrics
*, kMaxCacheEntries
* 2> mFontMetrics
;
78 bool mFlushPending
= false;
80 class FlushFontMetricsTask
: public mozilla::Runnable
{
82 explicit FlushFontMetricsTask(nsFontCache
* aCache
)
83 : mozilla::Runnable("FlushFontMetricsTask"), mCache(aCache
) {}
84 NS_IMETHOD
Run() override
{
85 // Partially flush the cache, leaving the kMaxCacheEntries/2 most
87 mCache
->Flush(mCache
->mFontMetrics
.Length() - kMaxCacheEntries
/ 2);
88 mCache
->mFlushPending
= false;
93 RefPtr
<nsFontCache
> mCache
;
96 PRTime mLastCacheMiss
= 0;
97 uint64_t mCacheMisses
= 0;
98 bool mReportedProbableFingerprinting
= false;
101 #endif /* _NS_FONTCACHE_H_ */