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(
|
||||||
SkGlyphCache::SkGlyphCache(const SkDescriptor& desc, std::unique_ptr<SkScalerContext> ctx)
|
const SkDescriptor& desc,
|
||||||
: fDesc(desc.copy())
|
std::unique_ptr<SkScalerContext> scaler,
|
||||||
, fScalerContext(std::move(ctx))
|
const SkPaint::FontMetrics& fontMetrics)
|
||||||
|
: fDesc{desc.copy()}
|
||||||
|
, fScalerContext{std::move(scaler)}
|
||||||
|
, fFontMetrics(fontMetrics)
|
||||||
{
|
{
|
||||||
SkASSERT(fScalerContext);
|
SkASSERT(fScalerContext != nullptr);
|
||||||
|
|
||||||
fScalerContext->getFontMetrics(&fFontMetrics);
|
|
||||||
|
|
||||||
fMemoryUsed = sizeof(*this);
|
fMemoryUsed = sizeof(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,10 +53,6 @@ SkGlyphCache::~SkGlyphCache() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkGlyphCache::PurgeAll() {
|
|
||||||
get_globals().purgeAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(SkPackedUnicharID packedUnicharID) {
|
SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(SkPackedUnicharID packedUnicharID) {
|
||||||
if (!fPackedUnicharIDToPackedGlyphID) {
|
if (!fPackedUnicharIDToPackedGlyphID) {
|
||||||
fPackedUnicharIDToPackedGlyphID.reset(new CharGlyphRec[kHashCount]);
|
fPackedUnicharIDToPackedGlyphID.reset(new CharGlyphRec[kHashCount]);
|
||||||
@ -497,12 +493,32 @@ SkExclusiveStrikePtr SkGlyphCache::FindStrikeExclusive(const SkDescriptor& desc)
|
|||||||
return SkExclusiveStrikePtr(nullptr);
|
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(
|
SkExclusiveStrikePtr SkGlyphCache::FindOrCreateStrikeExclusive(
|
||||||
const SkDescriptor& desc, const SkScalerContextEffects& effects, const SkTypeface& typeface) {
|
const SkDescriptor& desc, const SkScalerContextEffects& effects, const SkTypeface& typeface) {
|
||||||
auto creator = [&effects, &typeface](const SkDescriptor& descriptor, bool canFail) {
|
|
||||||
return typeface.createScalerContext(effects, &descriptor, canFail);
|
auto cache = SkGlyphCache::FindStrikeExclusive(desc);
|
||||||
};
|
if (cache == nullptr) {
|
||||||
return FindOrCreateStrikeExclusive(desc, creator);
|
auto scaler = CreateScalerContext(desc, effects, typeface);
|
||||||
|
cache = SkGlyphCache::CreateStrikeExclusive(desc, std::move(scaler));
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkExclusiveStrikePtr SkGlyphCache::FindOrCreateStrikeExclusive(
|
SkExclusiveStrikePtr SkGlyphCache::FindOrCreateStrikeExclusive(
|
||||||
@ -522,6 +538,21 @@ SkExclusiveStrikePtr SkGlyphCache::FindOrCreateStrikeExclusive(
|
|||||||
return FindOrCreateStrikeExclusive(*desc, effects, *tf);
|
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) {
|
void SkGlyphCache::ForEachStrike(std::function<void(const SkGlyphCache&)> visitor) {
|
||||||
SkGlyphCache_Globals& globals = get_globals();
|
SkGlyphCache_Globals& globals = get_globals();
|
||||||
SkAutoExclusive ac(globals.fLock);
|
SkAutoExclusive ac(globals.fLock);
|
||||||
|
@ -126,21 +126,15 @@ public:
|
|||||||
|
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
|
static std::unique_ptr<SkScalerContext> CreateScalerContext(
|
||||||
|
const SkDescriptor& desc,
|
||||||
|
const SkScalerContextEffects& effects,
|
||||||
|
const SkTypeface& typeface);
|
||||||
|
|
||||||
SkScalerContext* getScalerContext() const { return fScalerContext.get(); }
|
SkScalerContext* getScalerContext() const { return fScalerContext.get(); }
|
||||||
|
|
||||||
static SkExclusiveStrikePtr FindStrikeExclusive(const SkDescriptor& desc);
|
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(
|
static SkExclusiveStrikePtr FindOrCreateStrikeExclusive(
|
||||||
const SkDescriptor& desc,
|
const SkDescriptor& desc,
|
||||||
const SkScalerContextEffects& effects,
|
const SkScalerContextEffects& effects,
|
||||||
@ -157,24 +151,10 @@ public:
|
|||||||
paint, nullptr, SkScalerContextFlags::kFakeGammaAndBoostContrast, nullptr);
|
paint, nullptr, SkScalerContextFlags::kFakeGammaAndBoostContrast, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ScalerContextCreator>
|
|
||||||
static SkExclusiveStrikePtr CreateStrikeExclusive(
|
static SkExclusiveStrikePtr CreateStrikeExclusive(
|
||||||
const SkDescriptor& desc, ScalerContextCreator creator)
|
const SkDescriptor& desc,
|
||||||
{
|
std::unique_ptr<SkScalerContext> scaler,
|
||||||
// Check if we can create a scaler-context before creating the glyphcache.
|
SkPaint::FontMetrics* maybeMetrics = nullptr);
|
||||||
// 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)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Dump();
|
static void Dump();
|
||||||
|
|
||||||
@ -230,12 +210,10 @@ private:
|
|||||||
SkPackedGlyphID fPackedGlyphID;
|
SkPackedGlyphID fPackedGlyphID;
|
||||||
};
|
};
|
||||||
|
|
||||||
SkGlyphCache(const SkDescriptor& desc, std::unique_ptr<SkScalerContext> scaler);
|
SkGlyphCache(const SkDescriptor& desc, std::unique_ptr<SkScalerContext> scaler,
|
||||||
|
const SkPaint::FontMetrics&);
|
||||||
~SkGlyphCache();
|
~SkGlyphCache();
|
||||||
|
|
||||||
// Purge all the things.
|
|
||||||
static void PurgeAll();
|
|
||||||
|
|
||||||
// Return the SkGlyph* associated with MakeID. The id parameter is the
|
// 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
|
// combined glyph/x/y id generated by MakeID. If it is just a glyph id
|
||||||
// then x and y are assumed to be zero.
|
// 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)),
|
c = skstd::make_unique<SkScalerContext_Empty>(sk_ref_sp(const_cast<SkTypeface*>(this)),
|
||||||
effects, desc);
|
effects, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !allowFailure implies c != nullptr
|
||||||
|
SkASSERT(c || allowFailure);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,11 +31,7 @@ void SkScalerContextProxy::generatePath(SkGlyphID glyphID, SkPath* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SkScalerContextProxy::generateFontMetrics(SkPaint::FontMetrics* metrics) {
|
void SkScalerContextProxy::generateFontMetrics(SkPaint::FontMetrics* metrics) {
|
||||||
if (!fHaveFontMetrics) {
|
fRemote->generateFontMetrics(*this->typefaceProxy(), this->getRec(), metrics);
|
||||||
fRemote->generateFontMetrics(*this->typefaceProxy(), this->getRec(), &fFontMetrics);
|
|
||||||
}
|
|
||||||
fHaveFontMetrics = true;
|
|
||||||
*metrics = fFontMetrics;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SkTypefaceProxy* SkScalerContextProxy::typefaceProxy() {
|
SkTypefaceProxy* SkScalerContextProxy::typefaceProxy() {
|
||||||
|
@ -47,11 +47,6 @@ public:
|
|||||||
const SkDescriptor* desc,
|
const SkDescriptor* desc,
|
||||||
SkRemoteScalerContext* rsc);
|
SkRemoteScalerContext* rsc);
|
||||||
|
|
||||||
void setFontMetrics(const SkPaint::FontMetrics& fontMetrics) {
|
|
||||||
fFontMetrics = fontMetrics;
|
|
||||||
fHaveFontMetrics = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned generateGlyphCount(void) override { SK_ABORT("Should never be called."); return 0;}
|
unsigned generateGlyphCount(void) override { SK_ABORT("Should never be called."); return 0;}
|
||||||
uint16_t generateCharToGlyph(SkUnichar uni) override {
|
uint16_t generateCharToGlyph(SkUnichar uni) override {
|
||||||
@ -75,8 +70,6 @@ private:
|
|||||||
|
|
||||||
SkArenaAlloc fAlloc{kMinAllocAmount};
|
SkArenaAlloc fAlloc{kMinAllocAmount};
|
||||||
SkRemoteScalerContext* const fRemote;
|
SkRemoteScalerContext* const fRemote;
|
||||||
bool fHaveFontMetrics{false};
|
|
||||||
SkPaint::FontMetrics fFontMetrics;
|
|
||||||
typedef SkScalerContext INHERITED;
|
typedef SkScalerContext INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -774,14 +774,8 @@ static void prepopulate_cache(
|
|||||||
// TODO: implement effects handling.
|
// TODO: implement effects handling.
|
||||||
SkScalerContextEffects effects;
|
SkScalerContextEffects effects;
|
||||||
if ((strike = SkGlyphCache::FindStrikeExclusive(*desc)) == nullptr) {
|
if ((strike = SkGlyphCache::FindStrikeExclusive(*desc)) == nullptr) {
|
||||||
auto creator = [&effects, &tf, &fontMetrics](
|
auto scaler = SkGlyphCache::CreateScalerContext(*desc, effects, *tf);
|
||||||
const SkDescriptor& descriptor, bool canFail)
|
strike = SkGlyphCache::CreateStrikeExclusive(*desc, std::move(scaler), fontMetrics);
|
||||||
{
|
|
||||||
auto scaler = tf->createScalerContext(effects, &descriptor, canFail);
|
|
||||||
((SkScalerContextProxy*)scaler.get())->setFontMetrics(*fontMetrics);
|
|
||||||
return scaler;
|
|
||||||
};
|
|
||||||
strike = SkGlyphCache::CreateStrikeExclusive(*desc,creator);
|
|
||||||
}
|
}
|
||||||
#if INSTRUMENT
|
#if INSTRUMENT
|
||||||
std::cout << std::hex << "prepop cache " << (intptr_t)cache
|
std::cout << std::hex << "prepop cache " << (intptr_t)cache
|
||||||
|
Loading…
Reference in New Issue
Block a user