Use SkStrikeSpec to consolidate SkDescriptor, Effects and Typeface.

Introduce SkStrikeSpec. Allow an SkStrikeInterface to return on
that represents the strike. Have GrTextBlob::Run::setFont() use
SkStrikeSpecs.

Misc Cleanups
* In SkStrikeCache::Node - rename fCache -> fStrike
* Parameter reformatting

Change-Id: I1b289e2cb4e5252d5c3cb776f3b2a31c6e1948b3
Reviewed-on: https://skia-review.googlesource.com/c/192029
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2019-02-13 11:46:19 -05:00 committed by Skia Commit-Bot
parent 65e841715e
commit a4c6487f6c
8 changed files with 68 additions and 39 deletions

View File

@ -708,7 +708,7 @@ void GrTextBlob::generateFromGlyphRunList(GrStrikeCache* glyphCache,
SkExclusiveStrikePtr fallbackCache = SkStrikeCache::FindOrCreateStrikeExclusive(
fallbackFont, fallbackPaint, fProps, fScalerContextFlags, glyphCacheMatrix);
sk_sp<GrTextStrike> strike = fGrStrikeCache->getStrike(fallbackCache->getDescriptor());
fRun->setupFont(fallbackPaint, fallbackFont, fallbackCache->getDescriptor());
fRun->setupFont(fallbackCache->strikeSpec());
SkASSERT(strike != nullptr);
subRun->setStrike(strike);
@ -770,10 +770,10 @@ void GrTextBlob::generateFromGlyphRunList(GrStrikeCache* glyphCache,
hasWCoord);
{
SkExclusiveStrikePtr cache =SkStrikeCache::FindOrCreateStrikeExclusive(
SkExclusiveStrikePtr cache = SkStrikeCache::FindOrCreateStrikeExclusive(
distanceFieldFont, distanceFieldPaint, props, flags, SkMatrix::I());
sk_sp<GrTextStrike> currStrike = glyphCache->getStrike(cache->getDescriptor());
run->setupFont(distanceFieldPaint, distanceFieldFont, cache->getDescriptor());
run->setupFont(cache->strikeSpec());
auto perEmpty = [](const SkGlyph&, SkPoint) {};
@ -846,10 +846,10 @@ void GrTextBlob::generateFromGlyphRunList(GrStrikeCache* glyphCache,
auto processEmpties = [](SkSpan<const SkGlyph*>glyphs) {};
auto processMasks =
[run, glyphCache, &runFont, &runPaint]
[run, glyphCache]
(SkSpan<const SkGlyphRunListPainter::GlyphAndPos> masks,
SkStrikeInterface* strike) {
run->setupFont(runPaint, runFont, strike->getDescriptor());
run->setupFont(strike->strikeSpec());
sk_sp<GrTextStrike> currStrike = glyphCache->getStrike(strike->getDescriptor());
for (const auto& mask : masks) {
SkPoint pt{SkScalarFloorToScalar(mask.position.fX),

View File

@ -19,11 +19,32 @@ class GrColorSpaceInfo;
class GrRenderTargetContext;
#endif
class SkStrikeSpec {
public:
SkStrikeSpec(const SkDescriptor& desc,
const SkTypeface& typeface,
const SkScalerContextEffects& effects)
: fDesc{desc}
, fTypeface{typeface}
, fEffects{effects} {}
const SkDescriptor& desc() const { return fDesc; }
const SkTypeface& typeface() const { return fTypeface; }
SkScalerContextEffects effects() const {return fEffects; }
private:
const SkDescriptor& fDesc;
const SkTypeface& fTypeface;
const SkScalerContextEffects fEffects;
};
class SkStrikeInterface {
public:
virtual ~SkStrikeInterface() = default;
virtual SkVector rounding() const = 0;
virtual const SkDescriptor& getDescriptor() const = 0;
virtual SkStrikeSpec strikeSpec() const = 0;
virtual const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) = 0;
virtual bool decideCouldDrawFromPath(const SkGlyph& glyph) = 0;
virtual void onAboutToExitScope() = 0;

View File

@ -366,8 +366,7 @@ SkStrikeServer::SkGlyphCacheState* SkStrikeServer::getOrCreateCache(
// Create a new cache state and insert it into the map.
auto newHandle = fDiscardableHandleManager->createHandle();
auto cacheState = skstd::make_unique<SkGlyphCacheState>(
desc, std::move(context), newHandle);
auto cacheState = skstd::make_unique<SkGlyphCacheState>(desc, std::move(context), newHandle);
auto* cacheStatePtr = cacheState.get();

View File

@ -33,6 +33,10 @@ public:
return *fDescriptor.getDesc();
}
SkStrikeSpec strikeSpec() const override {
return SkStrikeSpec(this->getDescriptor(), *fTypeface, fEffects);
}
void setTypefaceAndEffects(const SkTypeface* typeface, SkScalerContextEffects effects);
SkVector rounding() const override;

View File

@ -129,6 +129,12 @@ public:
const SkDescriptor& getDescriptor() const override;
SkStrikeSpec strikeSpec() const override {
return SkStrikeSpec{this->getDescriptor(),
*this->getScalerContext()->getTypeface(),
this->getScalerContext()->getEffects()};
}
void onAboutToExitScope() override;
/** Return the approx RAM usage for this cache. */

View File

@ -25,23 +25,27 @@ public:
const SkFontMetrics& metrics,
std::unique_ptr<SkStrikePinner> pinner)
: fStrikeCache{strikeCache}
, fCache{desc, std::move(scaler), metrics}
, fStrike{desc, std::move(scaler), metrics}
, fPinner{std::move(pinner)} {}
SkVector rounding() const override {
return fCache.rounding();
return fStrike.rounding();
}
const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) override {
return fCache.getGlyphMetrics(glyphID, position);
return fStrike.getGlyphMetrics(glyphID, position);
}
bool decideCouldDrawFromPath(const SkGlyph& glyph) override {
return fCache.decideCouldDrawFromPath(glyph);
return fStrike.decideCouldDrawFromPath(glyph);
}
const SkDescriptor& getDescriptor() const override {
return fCache.getDescriptor();
return fStrike.getDescriptor();
}
SkStrikeSpec strikeSpec() const override {
return fStrike.strikeSpec();
}
void onAboutToExitScope() override {
@ -51,7 +55,7 @@ public:
SkStrikeCache* const fStrikeCache;
Node* fNext{nullptr};
Node* fPrev{nullptr};
SkStrike fCache;
SkStrike fStrike;
std::unique_ptr<SkStrikePinner> fPinner;
};
@ -88,7 +92,7 @@ SkStrikeCache::ExclusiveStrikePtr::~ExclusiveStrikePtr() {
}
SkStrike* SkStrikeCache::ExclusiveStrikePtr::get() const {
return &fNode->fCache;
return &fNode->fStrike;
}
SkStrike* SkStrikeCache::ExclusiveStrikePtr::operator -> () const {
@ -301,7 +305,7 @@ void SkStrikeCache::attachNode(Node* node) {
SkAutoExclusive ac(fLock);
this->validate();
node->fCache.validate();
node->fStrike.validate();
this->internalAttachToHead(node);
this->internalPurge();
@ -315,7 +319,7 @@ auto SkStrikeCache::findAndDetachStrike(const SkDescriptor& desc) -> Node* {
SkAutoExclusive ac(fLock);
for (Node* node = internalGetHead(); node != nullptr; node = node->fNext) {
if (node->fCache.getDescriptor() == desc) {
if (node->fStrike.getDescriptor() == desc) {
this->internalDetachCache(node);
return node;
}
@ -360,10 +364,10 @@ bool SkStrikeCache::desperationSearchForImage(const SkDescriptor& desc, SkGlyph*
targetSubY = glyph->getSubYFixed();
for (Node* node = internalGetHead(); node != nullptr; node = node->fNext) {
if (loose_compare(node->fCache.getDescriptor(), desc)) {
if (loose_compare(node->fStrike.getDescriptor(), desc)) {
auto targetGlyphID = SkPackedGlyphID(glyphID, targetSubX, targetSubY);
if (node->fCache.isGlyphCached(glyphID, targetSubX, targetSubY)) {
SkGlyph* fallback = node->fCache.getRawGlyphByID(targetGlyphID);
if (node->fStrike.isGlyphCached(glyphID, targetSubX, targetSubY)) {
SkGlyph* fallback = node->fStrike.getRawGlyphByID(targetGlyphID);
// This desperate-match node may disappear as soon as we drop fLock, so we
// need to copy the glyph from node into this strike, including a
// deep copy of the mask.
@ -372,7 +376,7 @@ bool SkStrikeCache::desperationSearchForImage(const SkDescriptor& desc, SkGlyph*
}
// Look for any sub-pixel pos for this glyph, in case there is a pos mismatch.
if (const auto* fallback = node->fCache.getCachedGlyphAnySubPix(glyphID)) {
if (const auto* fallback = node->fStrike.getCachedGlyphAnySubPix(glyphID)) {
targetCache->initializeGlyphFromFallback(glyph, *fallback);
return true;
}
@ -393,9 +397,9 @@ bool SkStrikeCache::desperationSearchForPath(
// This will have to search the sub-pixel positions too.
// There is also a problem with accounting for cache size with shared path data.
for (Node* node = internalGetHead(); node != nullptr; node = node->fNext) {
if (loose_compare(node->fCache.getDescriptor(), desc)) {
if (node->fCache.isGlyphCached(glyphID, 0, 0)) {
SkGlyph* from = node->fCache.getRawGlyphByID(SkPackedGlyphID(glyphID));
if (loose_compare(node->fStrike.getDescriptor(), desc)) {
if (node->fStrike.isGlyphCached(glyphID, 0, 0)) {
SkGlyph* from = node->fStrike.getRawGlyphByID(SkPackedGlyphID(glyphID));
if (from->fPathData != nullptr) {
// We can just copy the path out by value here, so no need to worry
// about the lifetime of this desperate-match node.
@ -518,7 +522,7 @@ void SkStrikeCache::forEachStrike(std::function<void(const SkStrike&)> visitor)
this->validate();
for (Node* node = this->internalGetHead(); node != nullptr; node = node->fNext) {
visitor(node->fCache);
visitor(node->fStrike);
}
}
@ -558,7 +562,7 @@ size_t SkStrikeCache::internalPurge(size_t minBytesNeeded) {
// Only delete if the strike is not pinned.
if (node->fPinner == nullptr || node->fPinner->canDelete()) {
bytesFreed += node->fCache.getMemoryUsed();
bytesFreed += node->fStrike.getMemoryUsed();
countFreed += 1;
this->internalDetachCache(node);
delete node;
@ -591,13 +595,13 @@ void SkStrikeCache::internalAttachToHead(Node* node) {
}
fCacheCount += 1;
fTotalMemoryUsed += node->fCache.getMemoryUsed();
fTotalMemoryUsed += node->fStrike.getMemoryUsed();
}
void SkStrikeCache::internalDetachCache(Node* node) {
SkASSERT(fCacheCount > 0);
fCacheCount -= 1;
fTotalMemoryUsed -= node->fCache.getMemoryUsed();
fTotalMemoryUsed -= node->fStrike.getMemoryUsed();
if (node->fPrev) {
node->fPrev->fNext = node->fNext;
@ -633,7 +637,7 @@ void SkStrikeCache::validate() const {
const Node* node = fHead;
while (node != nullptr) {
computedBytes += node->fCache.getMemoryUsed();
computedBytes += node->fStrike.getMemoryUsed();
computedCount += 1;
node = node->fNext;
}

View File

@ -56,18 +56,15 @@ sk_sp<GrTextBlob> GrTextBlob::Make(int glyphCount, int runCount, GrColor color)
return blob;
}
void GrTextBlob::Run::setupFont(const SkPaint& skPaint,
const SkFont& skFont,
const SkDescriptor& cacheDescriptor) {
fTypeface = skFont.refTypefaceOrDefault();
SkScalerContextEffects effects{skPaint};
fPathEffect = sk_ref_sp(effects.fPathEffect);
fMaskFilter = sk_ref_sp(effects.fMaskFilter);
void GrTextBlob::Run::setupFont(const SkStrikeSpec& strikeSpec) {
fTypeface = sk_ref_sp(&strikeSpec.typeface());
fPathEffect = sk_ref_sp(strikeSpec.effects().fPathEffect);
fMaskFilter = sk_ref_sp(strikeSpec.effects().fMaskFilter);
// if we have an override descriptor for the run, then we should use that
SkAutoDescriptor* desc =
fARGBFallbackDescriptor.get() ? fARGBFallbackDescriptor.get() : &fDescriptor;
// Set up the descriptor for possible cache lookups during regen.
desc->reset(cacheDescriptor);
desc->reset(strikeSpec.desc());
}
void GrTextBlob::Run::appendPathGlyph(const SkPath& path, SkPoint position,

View File

@ -445,9 +445,7 @@ private:
SkPoint origin,
SkScalar textScale);
void setupFont(const SkPaint& skPaint,
const SkFont& skFont,
const SkDescriptor& skCache);
void setupFont(const SkStrikeSpec& strikeSpec);
void setRunFontAntiAlias(bool aa) {
fAntiAlias = aa;