xref: /aosp_15_r20/external/skia/src/core/SkStrikeCache.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2010 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkStrikeCache_DEFINED
9 #define SkStrikeCache_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/private/base/SkLoadUserConfig.h" // IWYU pragma: keep
13 #include "include/private/base/SkMutex.h"
14 #include "include/private/base/SkThreadAnnotations.h"
15 #include "src/core/SkStrike.h"
16 #include "src/core/SkTHash.h"
17 #include "src/text/StrikeForGPU.h"
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <functional>
22 #include <memory>
23 
24 class SkDescriptor;
25 class SkStrikeSpec;
26 class SkTraceMemoryDump;
27 struct SkFontMetrics;
28 
29 //  SK_DEFAULT_FONT_CACHE_COUNT_LIMIT and SK_DEFAULT_FONT_CACHE_LIMIT can be set using -D on your
30 //  compiler commandline, or by using the defines in SkUserConfig.h
31 #ifndef SK_DEFAULT_FONT_CACHE_COUNT_LIMIT
32     #define SK_DEFAULT_FONT_CACHE_COUNT_LIMIT   2048
33 #endif
34 
35 #ifndef SK_DEFAULT_FONT_CACHE_LIMIT
36     #define SK_DEFAULT_FONT_CACHE_LIMIT     (2 * 1024 * 1024)
37 #endif
38 
39 ///////////////////////////////////////////////////////////////////////////////
40 
41 class SkStrikeCache final : public sktext::StrikeForGPUCacheInterface {
42 public:
43     SkStrikeCache() = default;
44 
45     static SkStrikeCache* GlobalStrikeCache();
46 
47     sk_sp<SkStrike> findStrike(const SkDescriptor& desc) SK_EXCLUDES(fLock);
48 
49     sk_sp<SkStrike> createStrike(
50             const SkStrikeSpec& strikeSpec,
51             SkFontMetrics* maybeMetrics = nullptr,
52             std::unique_ptr<SkStrikePinner> = nullptr) SK_EXCLUDES(fLock);
53 
54     sk_sp<SkStrike> findOrCreateStrike(const SkStrikeSpec& strikeSpec) SK_EXCLUDES(fLock);
55 
56     sk_sp<sktext::StrikeForGPU> findOrCreateScopedStrike(
57             const SkStrikeSpec& strikeSpec) override SK_EXCLUDES(fLock);
58 
59     static void PurgeAll();
60     static void Dump();
61 
62     // Dump memory usage statistics of all the attaches caches in the process using the
63     // SkTraceMemoryDump interface.
64     static void DumpMemoryStatistics(SkTraceMemoryDump* dump);
65 
66     void purgeAll() SK_EXCLUDES(fLock); // does not change budget
67     void purgePinned(size_t minBytesNeeded = 0) SK_EXCLUDES(fLock);
68 
69     int getCacheCountLimit() const SK_EXCLUDES(fLock);
70     int setCacheCountLimit(int limit) SK_EXCLUDES(fLock);
71     int getCacheCountUsed() const SK_EXCLUDES(fLock);
72 
73     size_t getCacheSizeLimit() const SK_EXCLUDES(fLock);
74     size_t setCacheSizeLimit(size_t limit) SK_EXCLUDES(fLock);
75     size_t getTotalMemoryUsed() const SK_EXCLUDES(fLock);
76 
77 private:
78     friend class SkStrike;  // for SkStrike::updateDelta
79     static constexpr char kGlyphCacheDumpName[] = "skia/sk_glyph_cache";
80     sk_sp<SkStrike> internalFindStrikeOrNull(const SkDescriptor& desc) SK_REQUIRES(fLock);
81     sk_sp<SkStrike> internalCreateStrike(
82             const SkStrikeSpec& strikeSpec,
83             SkFontMetrics* maybeMetrics = nullptr,
84             std::unique_ptr<SkStrikePinner> = nullptr) SK_REQUIRES(fLock);
85 
86     // The following methods can only be called when mutex is already held.
87     void internalRemoveStrike(SkStrike* strike) SK_REQUIRES(fLock);
88     void internalAttachToHead(sk_sp<SkStrike> strike) SK_REQUIRES(fLock);
89 
90     // Checkout budgets, modulated by the specified min-bytes-needed-to-purge,
91     // and attempt to purge caches to match.
92     // Returns number of bytes freed.
93     size_t internalPurge(size_t minBytesNeeded = 0, bool checkPinners = false) SK_REQUIRES(fLock);
94 
95     // A simple accounting of what each glyph cache reports and the strike cache total.
96     void validate() const SK_REQUIRES(fLock);
97 
98     void forEachStrike(std::function<void(const SkStrike&)> visitor) const SK_EXCLUDES(fLock);
99 
100     mutable SkMutex fLock;
SK_GUARDED_BY(fLock)101     SkStrike* fHead SK_GUARDED_BY(fLock) {nullptr};
SK_GUARDED_BY(fLock)102     SkStrike* fTail SK_GUARDED_BY(fLock) {nullptr};
103     struct StrikeTraits {
104         static const SkDescriptor& GetKey(const sk_sp<SkStrike>& strike);
105         static uint32_t Hash(const SkDescriptor& descriptor);
106     };
107     skia_private::THashTable<sk_sp<SkStrike>, SkDescriptor, StrikeTraits> fStrikeLookup
108             SK_GUARDED_BY(fLock);
109 
110     size_t  fCacheSizeLimit{SK_DEFAULT_FONT_CACHE_LIMIT};
SK_GUARDED_BY(fLock)111     size_t  fTotalMemoryUsed SK_GUARDED_BY(fLock) {0};
112     int32_t fCacheCountLimit{SK_DEFAULT_FONT_CACHE_COUNT_LIMIT};
SK_GUARDED_BY(fLock)113     int32_t fCacheCount SK_GUARDED_BY(fLock) {0};
SK_GUARDED_BY(fLock)114     int32_t fPinnerCount SK_GUARDED_BY(fLock) {0};
115 };
116 
117 #endif  // SkStrikeCache_DEFINED
118