Add SkShaper::PurgeCaches.
Allows the user to signal that any global outstanding cached data should be cleaned up to free resources. Change-Id: I59d4bb2bbb4356920dea8caf912d9cb5f13014cf Bug: skia:10763 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/360079 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Julia Lavrova <jlavrova@google.com>
This commit is contained in:
parent
0ca2f599dd
commit
dd9449c23b
@ -3,6 +3,7 @@
|
||||
#include "modules/skparagraph/include/FontCollection.h"
|
||||
#include "modules/skparagraph/include/Paragraph.h"
|
||||
#include "modules/skparagraph/src/ParagraphImpl.h"
|
||||
#include "modules/skshaper/include/SkShaper.h"
|
||||
|
||||
namespace skia {
|
||||
namespace textlayout {
|
||||
@ -150,6 +151,7 @@ void FontCollection::enableFontFallback() { fEnableFontFallback = true; }
|
||||
void FontCollection::clearCaches() {
|
||||
fParagraphCache.reset();
|
||||
fTypefaces.reset();
|
||||
SkShaper::PurgeCaches();
|
||||
}
|
||||
|
||||
} // namespace textlayout
|
||||
|
@ -41,12 +41,6 @@ class SkFont;
|
||||
class SkFontMgr;
|
||||
class SkUnicode;
|
||||
|
||||
/**
|
||||
Shapes text using HarfBuzz and places the shaped text into a
|
||||
client-managed buffer.
|
||||
|
||||
If compiled without HarfBuzz, fall back on SkPaint::textToGlyphs.
|
||||
*/
|
||||
class SKSHAPER_API SkShaper {
|
||||
public:
|
||||
static std::unique_ptr<SkShaper> MakePrimitive();
|
||||
@ -54,12 +48,14 @@ public:
|
||||
static std::unique_ptr<SkShaper> MakeShaperDrivenWrapper(sk_sp<SkFontMgr> = nullptr);
|
||||
static std::unique_ptr<SkShaper> MakeShapeThenWrap(sk_sp<SkFontMgr> = nullptr);
|
||||
static std::unique_ptr<SkShaper> MakeShapeDontWrapOrReorder(sk_sp<SkFontMgr> = nullptr);
|
||||
static void PurgeHarfBuzzCache();
|
||||
#endif
|
||||
#ifdef SK_SHAPER_CORETEXT_AVAILABLE
|
||||
static std::unique_ptr<SkShaper> MakeCoreText();
|
||||
#endif
|
||||
|
||||
static std::unique_ptr<SkShaper> Make(sk_sp<SkFontMgr> = nullptr);
|
||||
static void PurgeCaches();
|
||||
|
||||
SkShaper();
|
||||
virtual ~SkShaper();
|
||||
|
@ -36,6 +36,12 @@ std::unique_ptr<SkShaper> SkShaper::Make(sk_sp<SkFontMgr> fontmgr) {
|
||||
return SkShaper::MakePrimitive();
|
||||
}
|
||||
|
||||
void SkShaper::PurgeCaches() {
|
||||
#ifdef SK_SHAPER_HARFBUZZ_AVAILABLE
|
||||
PurgeHarfBuzzCache();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<SkShaper::BiDiRunIterator>
|
||||
SkShaper::MakeBiDiRunIterator(const char* utf8, size_t utf8Bytes, uint8_t bidiLevel) {
|
||||
#ifdef SK_UNICODE_AVAILABLE
|
||||
|
@ -1256,6 +1256,41 @@ void ShapeDontWrapOrReorder::wrap(char const * const utf8, size_t utf8Bytes,
|
||||
handler->commitLine();
|
||||
}
|
||||
|
||||
class HBLockedFaceCache {
|
||||
public:
|
||||
HBLockedFaceCache(SkLRUCache<SkFontID, HBFace>& lruCache, SkMutex& mutex)
|
||||
: fLRUCache(lruCache), fMutex(mutex)
|
||||
{
|
||||
fMutex.acquire();
|
||||
}
|
||||
HBLockedFaceCache(const HBLockedFaceCache&) = delete;
|
||||
HBLockedFaceCache& operator=(const HBLockedFaceCache&) = delete;
|
||||
HBLockedFaceCache(HBLockedFaceCache&&) = delete;
|
||||
HBLockedFaceCache& operator=(HBLockedFaceCache&&) = delete;
|
||||
|
||||
~HBLockedFaceCache() {
|
||||
fMutex.release();
|
||||
}
|
||||
|
||||
HBFace* find(SkFontID fontId) {
|
||||
return fLRUCache.find(fontId);
|
||||
}
|
||||
HBFace* insert(SkFontID fontId, HBFace hbFace) {
|
||||
return fLRUCache.insert(fontId, std::move(hbFace));
|
||||
}
|
||||
void reset() {
|
||||
fLRUCache.reset();
|
||||
}
|
||||
private:
|
||||
SkLRUCache<SkFontID, HBFace>& fLRUCache;
|
||||
SkMutex& fMutex;
|
||||
};
|
||||
static HBLockedFaceCache get_hbFace_cache() {
|
||||
static SkMutex gHBFaceCacheMutex;
|
||||
static SkLRUCache<SkFontID, HBFace> gHBFaceCache(100);
|
||||
return HBLockedFaceCache(gHBFaceCache, gHBFaceCacheMutex);
|
||||
}
|
||||
|
||||
ShapedRun ShaperHarfBuzz::shape(char const * const utf8,
|
||||
size_t const utf8Bytes,
|
||||
char const * const utf8Start,
|
||||
@ -1312,16 +1347,14 @@ ShapedRun ShaperHarfBuzz::shape(char const * const utf8,
|
||||
// An HBFont is fairly inexpensive.
|
||||
// An HBFace is actually tied to the data, not the typeface.
|
||||
// The size of 100 here is completely arbitrary and used to match libtxt.
|
||||
static SkLRUCache<SkFontID, HBFace> gHBFaceCache(100);
|
||||
static SkMutex gHBFaceCacheMutex;
|
||||
HBFont hbFont;
|
||||
{
|
||||
SkAutoMutexExclusive lock(gHBFaceCacheMutex);
|
||||
HBLockedFaceCache cache = get_hbFace_cache();
|
||||
SkFontID dataId = font.currentFont().getTypeface()->uniqueID();
|
||||
HBFace* hbFaceCached = gHBFaceCache.find(dataId);
|
||||
HBFace* hbFaceCached = cache.find(dataId);
|
||||
if (!hbFaceCached) {
|
||||
HBFace hbFace(create_hb_face(*font.currentFont().getTypeface()));
|
||||
hbFaceCached = gHBFaceCache.insert(dataId, std::move(hbFace));
|
||||
hbFaceCached = cache.insert(dataId, std::move(hbFace));
|
||||
}
|
||||
hbFont = create_hb_font(font.currentFont(), *hbFaceCached);
|
||||
}
|
||||
@ -1478,3 +1511,8 @@ std::unique_ptr<SkShaper> SkShaper::MakeShapeDontWrapOrReorder(sk_sp<SkFontMgr>
|
||||
return std::make_unique<ShapeDontWrapOrReorder>
|
||||
(std::move(unicode), nullptr, nullptr, std::move(buffer), std::move(fontmgr));
|
||||
}
|
||||
|
||||
void SkShaper::PurgeHarfBuzzCache() {
|
||||
HBLockedFaceCache cache = get_hbFace_cache();
|
||||
cache.reset();
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ protected:
|
||||
paint.setColor(fg);
|
||||
|
||||
for (int i = 9; i < 24; i += 2) {
|
||||
SkShaper::PurgeCaches();
|
||||
SkTextBlobBuilderRunHandler builder(gText, { margin, margin });
|
||||
SkFont srcFont(nullptr, SkIntToScalar(i));
|
||||
srcFont.setEdging(SkFont::Edging::kSubpixelAntiAlias);
|
||||
|
Loading…
Reference in New Issue
Block a user