diff options
author | Herb Derby <herb@google.com> | 2018-03-19 15:39:16 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-03-20 19:11:31 +0000 |
commit | aeb425dbf1735eaad7daef5c1f2d599d170a5a38 (patch) | |
tree | 5e51a25c5baa5e339d163665f0c90f610664a25f | |
parent | b0ca84f3a840e80f7775b9b4fbd3872513c14d7d (diff) |
Regularize SkGlyphCache creation.
This allows no need for downcasting for specialized use
of SkScalerContext for the remote case. This allows
cache priming to be used in a single process.
BUG=skia:7515
Change-Id: I963a50e36af9deef5a3414fc8a4c94ccfc38deaf
Reviewed-on: https://skia-review.googlesource.com/115121
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
-rw-r--r-- | src/core/SkGlyphCache.cpp | 63 | ||||
-rw-r--r-- | src/core/SkGlyphCache.h | 42 | ||||
-rw-r--r-- | src/core/SkScalerContext.cpp | 4 | ||||
-rw-r--r-- | src/core/SkTypeface_remote.cpp | 6 | ||||
-rw-r--r-- | src/core/SkTypeface_remote.h | 7 | ||||
-rw-r--r-- | tools/remote_demo.cpp | 10 |
6 files changed, 64 insertions, 68 deletions
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp index 4332419bbb..e030c4b9a3 100644 --- a/src/core/SkGlyphCache.cpp +++ b/src/core/SkGlyphCache.cpp @@ -33,15 +33,15 @@ static SkGlyphCache_Globals& get_globals() { } /////////////////////////////////////////////////////////////////////////////// - -SkGlyphCache::SkGlyphCache(const SkDescriptor& desc, std::unique_ptr<SkScalerContext> ctx) - : fDesc(desc.copy()) - , fScalerContext(std::move(ctx)) +SkGlyphCache::SkGlyphCache( + const SkDescriptor& desc, + std::unique_ptr<SkScalerContext> scaler, + const SkPaint::FontMetrics& fontMetrics) + : fDesc{desc.copy()} + , fScalerContext{std::move(scaler)} + , fFontMetrics(fontMetrics) { - SkASSERT(fScalerContext); - - fScalerContext->getFontMetrics(&fFontMetrics); - + SkASSERT(fScalerContext != nullptr); fMemoryUsed = sizeof(*this); } @@ -53,10 +53,6 @@ SkGlyphCache::~SkGlyphCache() { }); } -void SkGlyphCache::PurgeAll() { - get_globals().purgeAll(); -} - SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(SkPackedUnicharID packedUnicharID) { if (!fPackedUnicharIDToPackedGlyphID) { fPackedUnicharIDToPackedGlyphID.reset(new CharGlyphRec[kHashCount]); @@ -497,12 +493,32 @@ SkExclusiveStrikePtr SkGlyphCache::FindStrikeExclusive(const SkDescriptor& desc) return SkExclusiveStrikePtr(nullptr); } +std::unique_ptr<SkScalerContext> SkGlyphCache::CreateScalerContext( + const SkDescriptor& desc, + const SkScalerContextEffects& effects, + const SkTypeface& typeface) { + auto scaler = typeface.createScalerContext(effects, &desc, true /* can fail */); + + // Check if we can create a scaler-context before creating the glyphcache. + // If not, we may have exhausted OS/font resources, so try purging the + // cache once and try again + // pass true the first time, to notice if the scalercontext failed, + if (scaler == nullptr) { + get_globals().purgeAll(); + scaler = typeface.createScalerContext(effects, &desc, false /* must succeed */); + } + return scaler; +} + SkExclusiveStrikePtr SkGlyphCache::FindOrCreateStrikeExclusive( const SkDescriptor& desc, const SkScalerContextEffects& effects, const SkTypeface& typeface) { - auto creator = [&effects, &typeface](const SkDescriptor& descriptor, bool canFail) { - return typeface.createScalerContext(effects, &descriptor, canFail); - }; - return FindOrCreateStrikeExclusive(desc, creator); + + auto cache = SkGlyphCache::FindStrikeExclusive(desc); + if (cache == nullptr) { + auto scaler = CreateScalerContext(desc, effects, typeface); + cache = SkGlyphCache::CreateStrikeExclusive(desc, std::move(scaler)); + } + return cache; } SkExclusiveStrikePtr SkGlyphCache::FindOrCreateStrikeExclusive( @@ -522,6 +538,21 @@ SkExclusiveStrikePtr SkGlyphCache::FindOrCreateStrikeExclusive( return FindOrCreateStrikeExclusive(*desc, effects, *tf); } +SkExclusiveStrikePtr SkGlyphCache::CreateStrikeExclusive( + const SkDescriptor& desc, + std::unique_ptr<SkScalerContext> scaler, + SkPaint::FontMetrics* maybeMetrics) +{ + SkPaint::FontMetrics fontMetrics; + if (maybeMetrics != nullptr) { + fontMetrics = *maybeMetrics; + } else { + scaler->getFontMetrics(&fontMetrics); + } + + return SkExclusiveStrikePtr(new SkGlyphCache(desc, std::move(scaler), fontMetrics)); +} + void SkGlyphCache::ForEachStrike(std::function<void(const SkGlyphCache&)> visitor) { SkGlyphCache_Globals& globals = get_globals(); SkAutoExclusive ac(globals.fLock); diff --git a/src/core/SkGlyphCache.h b/src/core/SkGlyphCache.h index f42a52bee2..3db63fe63c 100644 --- a/src/core/SkGlyphCache.h +++ b/src/core/SkGlyphCache.h @@ -126,21 +126,15 @@ public: void dump() const; + static std::unique_ptr<SkScalerContext> CreateScalerContext( + const SkDescriptor& desc, + const SkScalerContextEffects& effects, + const SkTypeface& typeface); + SkScalerContext* getScalerContext() const { return fScalerContext.get(); } static SkExclusiveStrikePtr FindStrikeExclusive(const SkDescriptor& desc); - template <typename ScalerContextCreator> - static SkExclusiveStrikePtr FindOrCreateStrikeExclusive( - const SkDescriptor& desc, ScalerContextCreator&& creator) - { - auto cache = FindStrikeExclusive(desc); - if (cache == nullptr) { - cache = CreateStrikeExclusive(desc, creator); - } - return cache; - } - static SkExclusiveStrikePtr FindOrCreateStrikeExclusive( const SkDescriptor& desc, const SkScalerContextEffects& effects, @@ -157,24 +151,10 @@ public: paint, nullptr, SkScalerContextFlags::kFakeGammaAndBoostContrast, nullptr); } - template <typename ScalerContextCreator> static SkExclusiveStrikePtr CreateStrikeExclusive( - const SkDescriptor& desc, ScalerContextCreator creator) - { - // Check if we can create a scaler-context before creating the glyphcache. - // If not, we may have exhausted OS/font resources, so try purging the - // cache once and try again - // pass true the first time, to notice if the scalercontext failed, - // so we can try the purge. - auto context = creator(desc, true/* can fail */); - if (!context) { - PurgeAll(); - context = creator(desc, false/* must succeed */); - SkASSERT(context); - } - - return SkExclusiveStrikePtr(new SkGlyphCache(desc, std::move(context))); - } + const SkDescriptor& desc, + std::unique_ptr<SkScalerContext> scaler, + SkPaint::FontMetrics* maybeMetrics = nullptr); static void Dump(); @@ -230,12 +210,10 @@ private: SkPackedGlyphID fPackedGlyphID; }; - SkGlyphCache(const SkDescriptor& desc, std::unique_ptr<SkScalerContext> scaler); + SkGlyphCache(const SkDescriptor& desc, std::unique_ptr<SkScalerContext> scaler, + const SkPaint::FontMetrics&); ~SkGlyphCache(); - // Purge all the things. - static void PurgeAll(); - // Return the SkGlyph* associated with MakeID. The id parameter is the // combined glyph/x/y id generated by MakeID. If it is just a glyph id // then x and y are assumed to be zero. diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index b8778282e2..6302a80dc1 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -805,6 +805,10 @@ std::unique_ptr<SkScalerContext> SkTypeface::createScalerContext( c = skstd::make_unique<SkScalerContext_Empty>(sk_ref_sp(const_cast<SkTypeface*>(this)), effects, desc); } + + // !allowFailure implies c != nullptr + SkASSERT(c || allowFailure); + return c; } diff --git a/src/core/SkTypeface_remote.cpp b/src/core/SkTypeface_remote.cpp index ce3c7f5ba6..504d2413ec 100644 --- a/src/core/SkTypeface_remote.cpp +++ b/src/core/SkTypeface_remote.cpp @@ -31,11 +31,7 @@ void SkScalerContextProxy::generatePath(SkGlyphID glyphID, SkPath* path) { } void SkScalerContextProxy::generateFontMetrics(SkPaint::FontMetrics* metrics) { - if (!fHaveFontMetrics) { - fRemote->generateFontMetrics(*this->typefaceProxy(), this->getRec(), &fFontMetrics); - } - fHaveFontMetrics = true; - *metrics = fFontMetrics; + fRemote->generateFontMetrics(*this->typefaceProxy(), this->getRec(), metrics); } SkTypefaceProxy* SkScalerContextProxy::typefaceProxy() { diff --git a/src/core/SkTypeface_remote.h b/src/core/SkTypeface_remote.h index 750ec21ebe..03516be481 100644 --- a/src/core/SkTypeface_remote.h +++ b/src/core/SkTypeface_remote.h @@ -47,11 +47,6 @@ public: const SkDescriptor* desc, SkRemoteScalerContext* rsc); - void setFontMetrics(const SkPaint::FontMetrics& fontMetrics) { - fFontMetrics = fontMetrics; - fHaveFontMetrics = true; - } - protected: unsigned generateGlyphCount(void) override { SK_ABORT("Should never be called."); return 0;} uint16_t generateCharToGlyph(SkUnichar uni) override { @@ -75,8 +70,6 @@ private: SkArenaAlloc fAlloc{kMinAllocAmount}; SkRemoteScalerContext* const fRemote; - bool fHaveFontMetrics{false}; - SkPaint::FontMetrics fFontMetrics; typedef SkScalerContext INHERITED; }; diff --git a/tools/remote_demo.cpp b/tools/remote_demo.cpp index 8ff7d2986d..7cedaea00b 100644 --- a/tools/remote_demo.cpp +++ b/tools/remote_demo.cpp @@ -774,14 +774,8 @@ static void prepopulate_cache( // TODO: implement effects handling. SkScalerContextEffects effects; if ((strike = SkGlyphCache::FindStrikeExclusive(*desc)) == nullptr) { - auto creator = [&effects, &tf, &fontMetrics]( - const SkDescriptor& descriptor, bool canFail) - { - auto scaler = tf->createScalerContext(effects, &descriptor, canFail); - ((SkScalerContextProxy*)scaler.get())->setFontMetrics(*fontMetrics); - return scaler; - }; - strike = SkGlyphCache::CreateStrikeExclusive(*desc,creator); + auto scaler = SkGlyphCache::CreateScalerContext(*desc, effects, *tf); + strike = SkGlyphCache::CreateStrikeExclusive(*desc, std::move(scaler), fontMetrics); } #if INSTRUMENT std::cout << std::hex << "prepop cache " << (intptr_t)cache |