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>
This commit is contained in:
parent
b0ca84f3a8
commit
aeb425dbf1
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user