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