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