From 90674d1d2deae2d75a27f25bc686e5afafbf98b2 Mon Sep 17 00:00:00 2001 From: liufei Date: Mon, 18 Aug 2025 19:14:38 +0800 Subject: [PATCH] feat(core): implement typeface cache removal by unique ID - Add RemoveCacheByUniqueId function to SkGraphics - Implement typeface destruction callback and cache removal in SkTypeface - Update SkStrikeCache to remove strikes by typeface unique ID - Add cache removal methods to FontCollection and SkShaper - Modify GrDirectContext to free CPU cache for a specific typeface Signed-off-by: liufei --- include/core/SkGraphics.h | 3 ++ include/core/SkTypeface.h | 3 ++ include/gpu/GrDirectContext.h | 10 ++++++- m133/include/core/SkGraphics.h | 3 ++ m133/include/core/SkTypeface.h | 3 ++ m133/include/gpu/ganesh/GrDirectContext.h | 8 +++++ .../skparagraph/include/FontCollection.h | 1 + .../skparagraph/src/FontCollection.cpp | 8 +++++ .../skshaper/include/SkShaper_harfbuzz.h | 1 + .../skshaper/src/SkShaper_harfbuzz.cpp | 25 ++++++++++++++-- m133/src/core/SkGraphics.cpp | 6 ++++ m133/src/core/SkLRUCache.h | 15 ++++++++++ m133/src/core/SkStrikeCache.cpp | 30 +++++++++++++++++++ m133/src/core/SkStrikeCache.h | 9 ++++++ m133/src/core/SkTypeface.cpp | 13 +++++++- m133/src/gpu/ganesh/GrDirectContext.cpp | 15 ++++++++++ m133/src/text/gpu/StrikeCache.cpp | 25 ++++++++++++++++ m133/src/text/gpu/StrikeCache.h | 7 +++++ modules/skparagraph/include/FontCollection.h | 2 ++ modules/skparagraph/src/FontCollection.cpp | 8 +++++ modules/skshaper/include/SkShaper.h | 1 + modules/skshaper/src/SkShaper_harfbuzz.cpp | 27 +++++++++++++++-- src/core/SkGraphics.cpp | 6 ++++ src/core/SkLRUCache.h | 14 +++++++++ src/core/SkStrikeCache.cpp | 30 +++++++++++++++++++ src/core/SkStrikeCache.h | 7 +++++ src/core/SkTypeface.cpp | 13 ++++++++ src/gpu/GrDirectContext.cpp | 12 ++++++++ 28 files changed, 297 insertions(+), 8 deletions(-) diff --git a/include/core/SkGraphics.h b/include/core/SkGraphics.h index fc1e47cece..b4038bcf53 100644 --- a/include/core/SkGraphics.h +++ b/include/core/SkGraphics.h @@ -144,6 +144,9 @@ public: * Call early in main() to allow Skia to use a JIT to accelerate CPU-bound operations. */ static void AllowJIT(); +#ifdef OHOS_SUPPORT + static void RemoveCacheByUniqueId(uint32_t uniqueId); +#endif }; class SkAutoGraphics { diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h index e21f10790a..5e1581710b 100644 --- a/include/core/SkTypeface.h +++ b/include/core/SkTypeface.h @@ -9,6 +9,7 @@ #define SkTypeface_DEFINED #ifdef OHOS_SUPPORT +#include #include #endif @@ -140,6 +141,7 @@ public: #ifdef OHOS_SUPPORT static std::vector> GetSystemFonts(); + static void RegisterOnTypefaceDestroyed(std::function cb); #endif /** Return a new typeface based on this typeface but parameterized as specified in the @@ -494,6 +496,7 @@ private: bool fIsCustom = false; #ifdef OHOS_SUPPORT bool fIsTheme = false; + static std::function fTypefaceDestroyed; #endif using INHERITED = SkWeakRefCnt; }; diff --git a/include/gpu/GrDirectContext.h b/include/gpu/GrDirectContext.h index 1c86680279..ab581fe625 100644 --- a/include/gpu/GrDirectContext.h +++ b/include/gpu/GrDirectContext.h @@ -263,6 +263,14 @@ public: */ void freeGpuResources(); +#ifdef OHOS_SUPPORT + /** + * Frees CPU cache created by the context. Can be called to reduce CPU memory + * pressure. + */ + void freeCpuCache(uint32_t uniqueId); +#endif + /** * Purge GPU resources that haven't been used in the past 'msNotUsed' milliseconds or are * otherwise marked for deletion, regardless of whether the context is under budget. @@ -894,7 +902,7 @@ public: // OH ISSUE: intra frame and inter frame identification void beginFrame(); void endFrame(); - + // OH ISSUE: asyn memory reclaimer void setGpuMemoryAsyncReclaimerSwitch(bool enabled, const std::function& setThreadPriority); void flushGpuMemoryInWaitQueue(); diff --git a/m133/include/core/SkGraphics.h b/m133/include/core/SkGraphics.h index 58fd16b734..79c30cf805 100644 --- a/m133/include/core/SkGraphics.h +++ b/m133/include/core/SkGraphics.h @@ -164,6 +164,9 @@ public: std::unique_ptr (*)(const uint8_t* svg, size_t length); static OpenTypeSVGDecoderFactory SetOpenTypeSVGDecoderFactory(OpenTypeSVGDecoderFactory); static OpenTypeSVGDecoderFactory GetOpenTypeSVGDecoderFactory(); +#ifdef ENABLE_TEXT_ENHANCE + static void RemoveCacheByUniqueId(uint32_t uniqueId); +#endif }; #endif diff --git a/m133/include/core/SkTypeface.h b/m133/include/core/SkTypeface.h index 62f0c610ea..c0a5af75d0 100644 --- a/m133/include/core/SkTypeface.h +++ b/m133/include/core/SkTypeface.h @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -144,6 +145,7 @@ public: #ifdef ENABLE_TEXT_ENHANCE static std::vector> GetSystemFonts(); + static void RegisterOnTypefaceDestroyed(std::function cb); void getFontPath(SkString* path) const; #endif @@ -520,6 +522,7 @@ private: #ifdef ENABLE_TEXT_ENHANCE bool fIsCustom{false}; bool fIsTheme{false}; + static std::function fTypefaceDestroyed; #endif using INHERITED = SkWeakRefCnt; }; diff --git a/m133/include/gpu/ganesh/GrDirectContext.h b/m133/include/gpu/ganesh/GrDirectContext.h index f9fb6ad64e..f2bc85ec30 100644 --- a/m133/include/gpu/ganesh/GrDirectContext.h +++ b/m133/include/gpu/ganesh/GrDirectContext.h @@ -230,6 +230,14 @@ public: */ void freeGpuResources(); +#ifdef ENABLE_TEXT_ENHANCE + /** + * Frees CPU cache created by the context. Can be called to reduce CPU memory + * pressure. + */ + void freeCpuCache(uint32_t uniqueId); +#endif + /** * Purge GPU resources that haven't been used in the past 'msNotUsed' milliseconds or are * otherwise marked for deletion, regardless of whether the context is under budget. diff --git a/m133/modules/skparagraph/include/FontCollection.h b/m133/modules/skparagraph/include/FontCollection.h index 6384870af0..0f702a51fe 100644 --- a/m133/modules/skparagraph/include/FontCollection.h +++ b/m133/modules/skparagraph/include/FontCollection.h @@ -53,6 +53,7 @@ public: std::shared_ptr defaultFallback(); std::shared_ptr CloneTypeface(std::shared_ptr typeface, const std::optional& fontArgs); + void removeCacheByUniqueId(uint32_t uniqueId); #else void setAssetFontManager(sk_sp fontManager); void setDynamicFontManager(sk_sp fontManager); diff --git a/m133/modules/skparagraph/src/FontCollection.cpp b/m133/modules/skparagraph/src/FontCollection.cpp index 410d7966a1..030ee47f24 100644 --- a/m133/modules/skparagraph/src/FontCollection.cpp +++ b/m133/modules/skparagraph/src/FontCollection.cpp @@ -220,6 +220,14 @@ std::vector> FontCollection::findTypefaces(const std fTypefaces.emplace(familyKey, typefaces); return typefaces; } + +void FontCollection::removeCacheByUniqueId(uint32_t uniqueId) { + SkGraphics::RemoveCacheByUniqueId(uniqueId); + SkShapers::HB::RemoveCacheByUniqueId(uniqueId); + std::unique_lock writeLock(mutex_); + fTypefaces.clear(); + fParagraphCache.reset(); +} #else std::vector> FontCollection::findTypefaces(const std::vector& familyNames, SkFontStyle fontStyle, const std::optional& fontArgs) { diff --git a/m133/modules/skshaper/include/SkShaper_harfbuzz.h b/m133/modules/skshaper/include/SkShaper_harfbuzz.h index 8810c36c43..e62dec2e20 100644 --- a/m133/modules/skshaper/include/SkShaper_harfbuzz.h +++ b/m133/modules/skshaper/include/SkShaper_harfbuzz.h @@ -29,6 +29,7 @@ SKSHAPER_API std::unique_ptr ShapeThenWrap(sk_sp unicode, std::shared_ptr fallback); SKSHAPER_API std::unique_ptr ShapeDontWrapOrReorder(sk_sp unicode, std::shared_ptr fallback); +SKSHAPER_API void RemoveCacheByUniqueId(uint32_t uniqueId); #else SKSHAPER_API std::unique_ptr ShaperDrivenWrapper(sk_sp unicode, sk_sp fallback); diff --git a/m133/modules/skshaper/src/SkShaper_harfbuzz.cpp b/m133/modules/skshaper/src/SkShaper_harfbuzz.cpp index c1accc0b2f..0a095223de 100644 --- a/m133/modules/skshaper/src/SkShaper_harfbuzz.cpp +++ b/m133/modules/skshaper/src/SkShaper_harfbuzz.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include using namespace skia_private; @@ -1458,6 +1459,15 @@ public: void reset() { fLRUCache.reset(); } +#ifdef ENABLE_TEXT_ENHANCE + void removeByUniqueId(uint32_t uniqueId) { + if (fLRUCache.removePublic(uniqueId) == 0) { + fRemovedUniqueIds.emplace(uniqueId); + } + } +private: + std::unordered_set fRemovedUniqueIds; +#endif private: SkLRUCache& fLRUCache; SkMutex& fMutex; @@ -1533,15 +1543,17 @@ ShapedRun ShaperHarfBuzz::shape(char const * const utf8, SkTypefaceID dataId = font.currentFont().getTypeface()->uniqueID(); #endif HBFont* typefaceFontCached = cache.find(dataId); - if (!typefaceFontCached) { + if (typefaceFontCached != nullptr) { + hbFont = create_sub_hb_font(font.currentFont(), *typefaceFontCached); + } else { #ifdef ENABLE_TEXT_ENHANCE HBFont typefaceFont(create_typeface_hb_font(*const_cast(font.currentFont()).GetTypeface())); #else HBFont typefaceFont(create_typeface_hb_font(*font.currentFont().getTypeface())); #endif - typefaceFontCached = cache.insert(dataId, std::move(typefaceFont)); + hbFont = create_sub_hb_font(font.currentFont(), typefaceFont); + cache.insert(dataId, std::move(typefaceFont)); } - hbFont = create_sub_hb_font(font.currentFont(), *typefaceFontCached); } if (!hbFont) { return run; @@ -1778,6 +1790,13 @@ void PurgeCaches() { HBLockedFaceCache cache = get_hbFace_cache(); cache.reset(); } + +#ifdef ENABLE_TEXT_ENHANCE +void RemoveCacheByUniqueId(uint32_t uniqueId) { + HBLockedFaceCache cache = get_hbFace_cache(); + cache.removeByUniqueId(uniqueId); +} +#endif } // namespace SkShapers::HB #ifdef ENABLE_DRAWING_ADAPTER } // namespace SkiaRsText diff --git a/m133/src/core/SkGraphics.cpp b/m133/src/core/SkGraphics.cpp index d7de2f6413..55104267fc 100644 --- a/m133/src/core/SkGraphics.cpp +++ b/m133/src/core/SkGraphics.cpp @@ -102,3 +102,9 @@ SkGraphics::SetOpenTypeSVGDecoderFactory(OpenTypeSVGDecoderFactory svgDecoderFac SkGraphics::OpenTypeSVGDecoderFactory SkGraphics::GetOpenTypeSVGDecoderFactory() { return gSVGDecoderFactory; } + +#ifdef ENABLE_TEXT_ENHANCE +void SkGraphics::RemoveCacheByUniqueId(uint32_t uniqueId) { + SkStrikeCache::RemoveStrikeByUniqueId(uniqueId); +} +#endif \ No newline at end of file diff --git a/m133/src/core/SkLRUCache.h b/m133/src/core/SkLRUCache.h index 0741c287a9..b2c657ff28 100644 --- a/m133/src/core/SkLRUCache.h +++ b/m133/src/core/SkLRUCache.h @@ -106,6 +106,21 @@ public: } } +#ifdef ENABLE_TEXT_ENHANCE + int removePublic(const K& key) { + Entry** value = fMap.find(key); + if (value == nullptr || *value == nullptr || (*value)->fKey != key) { + return 1; + } + Entry* entry = *value; + PurgeCB()(key, &entry->fValue); + fMap.remove(key); + fLRU.remove(entry); + delete entry; + return 0; + } +#endif + private: struct Traits { static const K& GetKey(Entry* e) { diff --git a/m133/src/core/SkStrikeCache.cpp b/m133/src/core/SkStrikeCache.cpp index 2e03b23386..2e410279ca 100644 --- a/m133/src/core/SkStrikeCache.cpp +++ b/m133/src/core/SkStrikeCache.cpp @@ -50,6 +50,30 @@ sk_sp SkStrikeCache::findOrCreateScopedStrike(const SkStrikeSpec& return this->findOrCreateStrike(strikeSpec); } +#ifdef ENABLE_TEXT_ENHANCE +void SkStrikeCache::RemoveStrikeByUniqueId(uint32_t uniqueId) { + GlobalStrikeCache()->removeStrikeByUniqueId(uniqueId); +} + +void SkStrikeCache::removeStrikeByUniqueId(uint32_t uniqueId) { + SkAutoMutexExclusive ac(fLock); + std::vector strikes; + fStrikeLookup.foreach([&strikes, uniqueId](sk_sp* item) { + if (item && (*item) &&(*item)->strikeSpec().typeface().uniqueID() == uniqueId) { + strikes.push_back(item->get()); + } + }); + + if (!strikes.empty()) { + fRemovedUniqueIds.emplace(uniqueId); + } + + for (SkStrike* strike : strikes) { + this->internalRemoveStrike(strike); + } +} +#endif + void SkStrikeCache::PurgeAll() { GlobalStrikeCache()->purgeAll(); } @@ -137,7 +161,13 @@ auto SkStrikeCache::internalCreateStrike( std::unique_ptr scaler = strikeSpec.createScalerContext(); auto strike = sk_make_sp(this, strikeSpec, std::move(scaler), maybeMetrics, std::move(pinner)); +#ifdef ENABLE_TEXT_ENHANCE + if (!fRemovedUniqueIds.count(strikeSpec.typeface().uniqueID())) { + this->internalAttachToHead(strike); + } +#else this->internalAttachToHead(strike); +#endif return strike; } diff --git a/m133/src/core/SkStrikeCache.h b/m133/src/core/SkStrikeCache.h index 56ba3f5a86..e966ab6e58 100644 --- a/m133/src/core/SkStrikeCache.h +++ b/m133/src/core/SkStrikeCache.h @@ -20,6 +20,7 @@ #include #include #include +#include class SkDescriptor; class SkStrikeSpec; @@ -56,6 +57,14 @@ public: sk_sp findOrCreateScopedStrike( const SkStrikeSpec& strikeSpec) override SK_EXCLUDES(fLock); +#ifdef ENABLE_TEXT_ENHANCE + static void RemoveStrikeByUniqueId(uint32_t uniqueId); + void removeStrikeByUniqueId(uint32_t uniqueId) SK_EXCLUDES(fLock); +private: + std::unordered_set fRemovedUniqueIds; +public: +#endif + static void PurgeAll(); static void Dump(); diff --git a/m133/src/core/SkTypeface.cpp b/m133/src/core/SkTypeface.cpp index 9449f40957..2aaa442175 100644 --- a/m133/src/core/SkTypeface.cpp +++ b/m133/src/core/SkTypeface.cpp @@ -62,8 +62,19 @@ using namespace skia_private; SkTypeface::SkTypeface(const SkFontStyle& style, bool isFixedPitch) : fUniqueID(SkTypefaceCache::NewTypefaceID()), fStyle(style), fIsFixedPitch(isFixedPitch) { } +#ifdef ENABLE_TEXT_ENHANCE +std::function SkTypeface::fTypefaceDestroyed = nullptr; +SkTypeface::~SkTypeface() { + if (fTypefaceDestroyed) { + fTypefaceDestroyed(uniqueID()); + } +} +void SkTypeface::RegisterOnTypefaceDestroyed(std::function cb) { + fTypefaceDestroyed = cb; +} +#else SkTypeface::~SkTypeface() { } - +#endif /////////////////////////////////////////////////////////////////////////////// namespace { diff --git a/m133/src/gpu/ganesh/GrDirectContext.cpp b/m133/src/gpu/ganesh/GrDirectContext.cpp index 4417504f78..2629dac34e 100644 --- a/m133/src/gpu/ganesh/GrDirectContext.cpp +++ b/m133/src/gpu/ganesh/GrDirectContext.cpp @@ -241,6 +241,21 @@ void GrDirectContext::freeGpuResources() { fResourceCache->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources); } +#ifdef ENABLE_TEXT_ENHANCE +void GrDirectContext::freeCpuCache(uint32_t uniqueId) { + ASSERT_SINGLE_OWNER + + if (this->abandoned() || fStrikeCache == nullptr) { + return; + } + if (uniqueId == 0) { + fStrikeCache->freeAll(); + } else { + fStrikeCache->removeStrikeByUniqueId(uniqueId); + } +} +#endif + bool GrDirectContext::init() { ASSERT_SINGLE_OWNER if (!fGpu) { diff --git a/m133/src/text/gpu/StrikeCache.cpp b/m133/src/text/gpu/StrikeCache.cpp index 4caf3e1137..d7cb8e96f7 100644 --- a/m133/src/text/gpu/StrikeCache.cpp +++ b/m133/src/text/gpu/StrikeCache.cpp @@ -33,6 +33,26 @@ void StrikeCache::freeAll() { this->internalPurge(fTotalMemoryUsed); } +#ifdef ENABLE_TEXT_ENHANCE +void StrikeCache::removeStrikeByUniqueId(uint32_t uniqueId) { + std::vector strikes; + + fCache.foreach([&strikes, uniqueId](const sk_sp* item) { + if (item && (*item) && (*item)->strikeSpec().typeface().uniqueID() == uniqueId) { + strikes.push_back(item->get()); + } + }); + + if (!strikes.empty()) { + fRemovedUniqueIds.emplace(uniqueId); + } + + for (TextStrike* strike : strikes) { + this->internalRemoveStrike(strike); + } +} +#endif + sk_sp StrikeCache::findOrCreateStrike(const SkStrikeSpec& strikeSpec) { if (sk_sp* cached = fCache.find(strikeSpec.descriptor())) { return *cached; @@ -70,6 +90,11 @@ sk_sp StrikeCache::internalFindStrikeOrNull(const SkDescriptor& desc sk_sp StrikeCache::generateStrike(const SkStrikeSpec& strikeSpec) { sk_sp strike = sk_make_sp(this, strikeSpec); +#ifdef ENABLE_TEXT_ENHANCE + if (fRemovedUniqueIds.count(strikeSpec.typeface().uniqueID())) { + return strike; + } +#endif this->internalAttachToHead(strike); return strike; } diff --git a/m133/src/text/gpu/StrikeCache.h b/m133/src/text/gpu/StrikeCache.h index 007c45c6c6..f3f10ea14a 100644 --- a/m133/src/text/gpu/StrikeCache.h +++ b/m133/src/text/gpu/StrikeCache.h @@ -16,6 +16,7 @@ #include #include +#include struct SkPackedGlyphID; @@ -81,6 +82,12 @@ public: sk_sp findOrCreateStrike(const SkStrikeSpec& strikeSpec); void freeAll(); +#ifdef ENABLE_TEXT_ENHANCE + void removeStrikeByUniqueId(uint32_t uniqueId); +private: + std::unordered_set fRemovedUniqueIds; +public: +#endif private: friend class TextStrike; // for TextStrike::getGlyph diff --git a/modules/skparagraph/include/FontCollection.h b/modules/skparagraph/include/FontCollection.h index 084f88f66f..25e987ed97 100644 --- a/modules/skparagraph/include/FontCollection.h +++ b/modules/skparagraph/include/FontCollection.h @@ -107,6 +107,8 @@ public: { return fIsAdpaterTextHeightEnabled; } + + void removeCacheByUniqueId(uint32_t uniqueId); #endif private: #ifndef USE_SKIA_TXT diff --git a/modules/skparagraph/src/FontCollection.cpp b/modules/skparagraph/src/FontCollection.cpp index b790754e42..f4b77e9f11 100644 --- a/modules/skparagraph/src/FontCollection.cpp +++ b/modules/skparagraph/src/FontCollection.cpp @@ -34,6 +34,14 @@ std::unordered_map> g_faceTypeCache(MAX_VA #ifdef OHOS_SUPPORT bool FontCollection::fIsAdpaterTextHeightEnabled = false; + +void FontCollection::removeCacheByUniqueId(uint32_t uniqueId) { + SkGraphics::RemoveCacheByUniqueId(uniqueId); + SkShaper::RemoveCacheByUniqueId(uniqueId); + std::unique_lock writeLock(mutex_); + fTypefaces.clear(); + fParagraphCache.reset(); +} #endif bool FontCollection::FamilyKey::operator==(const FontCollection::FamilyKey& other) const { diff --git a/modules/skshaper/include/SkShaper.h b/modules/skshaper/include/SkShaper.h index 2ecba5fdca..7a3a55f0b7 100644 --- a/modules/skshaper/include/SkShaper.h +++ b/modules/skshaper/include/SkShaper.h @@ -63,6 +63,7 @@ public: static std::unique_ptr MakeShapeThenWrap(std::shared_ptr = nullptr); static std::unique_ptr MakeShapeDontWrapOrReorder(std::unique_ptr unicode, std::shared_ptr = nullptr); + static void RemoveCacheByUniqueId(uint32_t uniqueId); #endif static void PurgeHarfBuzzCache(); #endif diff --git a/modules/skshaper/src/SkShaper_harfbuzz.cpp b/modules/skshaper/src/SkShaper_harfbuzz.cpp index 485bb53475..16e432fd03 100644 --- a/modules/skshaper/src/SkShaper_harfbuzz.cpp +++ b/modules/skshaper/src/SkShaper_harfbuzz.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -1495,11 +1496,25 @@ public: return fLRUCache.find(fontId); } HBFont* insert(uint32_t fontId, HBFont hbFont) { +#ifdef USE_SKIA_TXT + if (fRemovedUniqueIds.count(fontId)) { + return nullptr; + } +#endif return fLRUCache.insert(fontId, std::move(hbFont)); } void reset() { fLRUCache.reset(); } +#ifdef USE_SKIA_TXT + void removeByUniqueId(uint32_t uniqueId) { + if (fLRUCache.removePublic(uniqueId) == 0) { + fRemovedUniqueIds.emplace(uniqueId); + } + } +private: + std::unordered_set fRemovedUniqueIds; +#endif private: SkLRUCache& fLRUCache; SkMutex& fMutex; @@ -1575,15 +1590,17 @@ ShapedRun ShaperHarfBuzz::shape(char const * const utf8, uint32_t dataId = const_cast(font.currentFont()).GetTypeface()->GetUniqueID(); #endif HBFont* typefaceFontCached = cache.find(dataId); - if (!typefaceFontCached) { + if (typefaceFontCached != nullptr) { + hbFont = create_sub_hb_font(font.currentFont(), *typefaceFontCached); + } else { #ifndef USE_SKIA_TXT HBFont typefaceFont(create_typeface_hb_font(*font.currentFont().getTypeface())); #else HBFont typefaceFont(create_typeface_hb_font(*const_cast(font.currentFont()).GetTypeface())); #endif - typefaceFontCached = cache.insert(dataId, std::move(typefaceFont)); + hbFont = create_sub_hb_font(font.currentFont(), typefaceFont); + cache.insert(dataId, std::move(typefaceFont)); } - hbFont = create_sub_hb_font(font.currentFont(), *typefaceFontCached); } if (!hbFont) { return run; @@ -1776,5 +1793,9 @@ void SkShaper::PurgeHarfBuzzCache() { cache.reset(); } #ifdef USE_SKIA_TXT +void SkShaper::RemoveCacheByUniqueId(uint32_t uniqueId) { + HBLockedFaceCache cache = get_hbFace_cache(); + cache.removeByUniqueId(uniqueId); +} } // namespace SkiaRsText #endif \ No newline at end of file diff --git a/src/core/SkGraphics.cpp b/src/core/SkGraphics.cpp index 1ca5b8c1da..0ab84cc6fc 100644 --- a/src/core/SkGraphics.cpp +++ b/src/core/SkGraphics.cpp @@ -130,3 +130,9 @@ extern bool gSkVMAllowJIT; void SkGraphics::AllowJIT() { gSkVMAllowJIT = true; } + +#ifdef OHOS_SUPPORT +void SkGraphics::RemoveCacheByUniqueId(uint32_t uniqueId) { + SkStrikeCache::RemoveStrikeByUniqueId(uniqueId); +} +#endif \ No newline at end of file diff --git a/src/core/SkLRUCache.h b/src/core/SkLRUCache.h index 50429d500f..a1966342e4 100644 --- a/src/core/SkLRUCache.h +++ b/src/core/SkLRUCache.h @@ -97,6 +97,20 @@ public: } } +#ifdef USE_SKIA_TXT + int removePublic(const K& key) { + Entry** value = fMap.find(key); + if (value == nullptr || (*value) == nullptr || (*value)->fKey != key) { + return 1; + } + Entry* entry = *value; + fMap.remove(key); + fLRU.remove(entry); + delete entry; + return 0; + } +#endif + private: struct Traits { static const K& GetKey(Entry* e) { diff --git a/src/core/SkStrikeCache.cpp b/src/core/SkStrikeCache.cpp index 149bdba262..c9d2f0798b 100644 --- a/src/core/SkStrikeCache.cpp +++ b/src/core/SkStrikeCache.cpp @@ -47,6 +47,30 @@ SkScopedStrikeForGPU SkStrikeCache::findOrCreateScopedStrike(const SkStrikeSpec& return SkScopedStrikeForGPU{this->findOrCreateStrike(strikeSpec).release()}; } +#ifdef OHOS_SUPPORT +void SkStrikeCache::RemoveStrikeByUniqueId(uint32_t uniqueId) { + GlobalStrikeCache()->removeStrikeByUniqueId(uniqueId); +} + +void SkStrikeCache::removeStrikeByUniqueId(uint32_t uniqueId) { + SkAutoMutexExclusive ac(fLock); + std::vector strikes; + fStrikeLookup.foreach([&strikes, uniqueId](sk_sp* item) { + if (item && (*item) &&(*item)->strikeSpec().typeface().uniqueID() == uniqueId) { + strikes.push_back(item->get()); + } + }); + + if (!strikes.empty()) { + fRemovedUniqueIds.emplace(uniqueId); + } + + for (SkStrike* strike : strikes) { + this->internalRemoveStrike(strike); + } +} +#endif + void SkStrikeCache::PurgeAll() { GlobalStrikeCache()->purgeAll(); } @@ -164,7 +188,13 @@ auto SkStrikeCache::internalCreateStrike( std::unique_ptr scaler = strikeSpec.createScalerContext(); auto strike = sk_make_sp(this, strikeSpec, std::move(scaler), maybeMetrics, std::move(pinner)); +#ifdef OHOS_SUPPORT + if (!fRemovedUniqueIds.count(strikeSpec.typeface().uniqueID())) { + this->internalAttachToHead(strike); + } +#else this->internalAttachToHead(strike); +#endif return strike; } diff --git a/src/core/SkStrikeCache.h b/src/core/SkStrikeCache.h index f484cf2de6..0eea5522be 100644 --- a/src/core/SkStrikeCache.h +++ b/src/core/SkStrikeCache.h @@ -173,6 +173,13 @@ public: SkScopedStrikeForGPU findOrCreateScopedStrike( const SkStrikeSpec& strikeSpec) override SK_EXCLUDES(fLock); +#ifdef OHOS_SUPPORT + static void RemoveStrikeByUniqueId(uint32_t uniqueId); + void removeStrikeByUniqueId(uint32_t uniqueId) SK_EXCLUDES(fLock); +private: + std::unordered_set fRemovedUniqueIds; +public: +#endif static void PurgeAll(); static void Dump(); diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp index 42267a6243..25d0065b41 100644 --- a/src/core/SkTypeface.cpp +++ b/src/core/SkTypeface.cpp @@ -28,7 +28,20 @@ SkTypeface::SkTypeface(const SkFontStyle& style, bool isFixedPitch) : fUniqueID(SkTypefaceCache::NewFontID()), fStyle(style), fIsFixedPitch(isFixedPitch) { } +#ifdef OHOS_SUPPORT +std::function SkTypeface::fTypefaceDestroyed = nullptr; +SkTypeface::~SkTypeface() { + if (fTypefaceDestroyed) { + fTypefaceDestroyed(uniqueID()); + } +} + +void SkTypeface::RegisterOnTypefaceDestroyed(std::function cb) { + fTypefaceDestroyed = cb; +} +#else SkTypeface::~SkTypeface() { } +#endif /////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp index 04bd9ce808..669c169a43 100644 --- a/src/gpu/GrDirectContext.cpp +++ b/src/gpu/GrDirectContext.cpp @@ -211,6 +211,18 @@ void GrDirectContext::freeGpuResources() { fResourceCache->purgeUnlockedResources(); } +#ifdef OHOS_SUPPORT +void GrDirectContext::freeCpuCache(uint32_t uniqueId) { + ASSERT_SINGLE_OWNER + + if (this->abandoned() || fStrikeCache == nullptr) { + return; + } + + fStrikeCache->freeAll(); +} +#endif + bool GrDirectContext::init() { ASSERT_SINGLE_OWNER if (!fGpu) { -- Gitee