Introduce SkScopedStrike

A SkScopedStrike allows drawGlyphRunAsBMPWithPathFallback
to control the scope of SkStrikeInterface objects generated
by both RemoteGlyphCache and SkStrikeCache.

* introduce onAboutToExitScope() into the SkStrikeInterface

Change-Id: I87a1e623ee9a8375f4e063290d74a466f96c9933
Reviewed-on: https://skia-review.googlesource.com/c/191293
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2019-02-11 14:20:31 -05:00 committed by Skia Commit-Bot
parent 17593ae5aa
commit 49253648d4
7 changed files with 52 additions and 8 deletions

View File

@ -372,7 +372,7 @@ void SkGlyphRunListPainter::drawGlyphRunAsPathWithARGBFallback(
template <typename EmptiesT, typename MasksT, typename PathsT>
void SkGlyphRunListPainter::drawGlyphRunAsBMPWithPathFallback(
SkStrikeInterface* strike, const SkGlyphRun& glyphRun,
SkScopedStrike&& strike, const SkGlyphRun& glyphRun,
SkPoint origin, const SkMatrix& deviceMatrix,
EmptiesT&& processEmpties, MasksT&& processMasks, PathsT&& processPaths) {
ScopedBuffers _ = this->ensureBuffers(glyphRun);
@ -420,7 +420,7 @@ void SkGlyphRunListPainter::drawGlyphRunAsBMPWithPathFallback(
}
if (glyphCount > 0) {
mapping.mapPoints(fPositions, glyphCount);
processMasks(SkSpan<const GlyphAndPos>{fMasks, SkTo<size_t>(glyphCount)}, strike);
processMasks(SkSpan<const GlyphAndPos>{fMasks, SkTo<size_t>(glyphCount)}, strike.get());
}
if (!fPaths.empty()) {
processPaths(SkSpan<const GlyphAndPos>{fPaths});
@ -826,9 +826,18 @@ void GrTextBlob::generateFromGlyphRunList(GrStrikeCache* glyphCache,
// Ensure the blob is set for bitmaptext
this->setHasBitmap();
auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(
runFont, runPaint, props, scalerContextFlags, viewMatrix);
run->setupFont(runPaint, runFont, cache->getDescriptor());
SkScalerContextEffects effects;
SkAutoDescriptor ad;
SkScalerContext::CreateDescriptorAndEffectsUsingPaint(runFont, runPaint,props,
scalerContextFlags,viewMatrix, &ad, &effects);
SkTypeface* typeface = runFont.getTypefaceOrDefault();
auto strikeCache = SkStrikeCache::GlobalStrikeCache();
auto strike = strikeCache->findOrCreateScopedStrike(*ad.getDesc(), effects, *typeface);
run->setupFont(runPaint, runFont, strike->getDescriptor());
auto processEmpties = [](SkSpan<const SkGlyph*>glyphs) {};
@ -858,7 +867,7 @@ void GrTextBlob::generateFromGlyphRunList(GrStrikeCache* glyphCache,
};
glyphPainter->drawGlyphRunAsBMPWithPathFallback(
cache.get(), glyphRun, origin, viewMatrix,
std::move(strike), glyphRun, origin, viewMatrix,
std::move(processEmpties), std::move(processMasks), std::move(processPaths));
}
}
@ -942,6 +951,8 @@ void SkTextBlobCacheDiffCanvas::TrackLayerDevice::processGlyphRunForMask(
SkScalerContextFlags::kFakeGammaAndBoostContrast, &effects);
SkASSERT(glyphCacheState);
SkScopedStrike strike{glyphCacheState};
auto processEmpties = [] (SkSpan<const SkGlyph*>glyphs) { };
auto processMasks = [] (
@ -950,7 +961,7 @@ void SkTextBlobCacheDiffCanvas::TrackLayerDevice::processGlyphRunForMask(
auto processPaths = [] (SkSpan<const SkGlyphRunListPainter::GlyphAndPos> paths) { };
fPainter.drawGlyphRunAsBMPWithPathFallback(
glyphCacheState, glyphRun, origin, runMatrix,
std::move(strike), glyphRun, origin, runMatrix,
std::move(processEmpties), std::move(processMasks), std::move(processPaths));
}

View File

@ -26,8 +26,17 @@ public:
virtual const SkDescriptor& getDescriptor() const = 0;
virtual const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) = 0;
virtual bool decideCouldDrawFromPath(const SkGlyph& glyph) = 0;
virtual void onAboutToExitScope() = 0;
struct Deleter {
void operator()(SkStrikeInterface* ptr) const {
ptr->onAboutToExitScope();
}
};
};
using SkScopedStrike = std::unique_ptr<SkStrikeInterface, SkStrikeInterface::Deleter>;
class SkStrikeCommon {
public:
static SkVector PixelRounding(bool isSubpixel, SkAxisAlignment axisAlignment);
@ -80,7 +89,7 @@ public:
template <typename EmptiesT, typename MasksT, typename PathsT>
void drawGlyphRunAsBMPWithPathFallback(
SkStrikeInterface* cache, const SkGlyphRun& glyphRun,
SkScopedStrike&& strike, const SkGlyphRun& glyphRun,
SkPoint origin, const SkMatrix& deviceMatrix,
EmptiesT&& processEmpties, MasksT&& processMasks, PathsT&& processPaths);

View File

@ -41,6 +41,8 @@ public:
bool decideCouldDrawFromPath(const SkGlyph& glyph) override;
void onAboutToExitScope() override {}
private:
bool hasPendingGlyphs() const {
return !fPendingGlyphImages.empty() || !fPendingGlyphPaths.empty();

View File

@ -423,6 +423,8 @@ bool SkStrike::decideCouldDrawFromPath(const SkGlyph& glyph) {
return !glyph.isEmpty() && this->findPath(glyph) != nullptr;
}
void SkStrike::onAboutToExitScope() { }
#ifdef SK_DEBUG
void SkStrike::forceValidate() const {
size_t memoryUsed = sizeof(*this);

View File

@ -129,6 +129,7 @@ public:
const SkDescriptor& getDescriptor() const override;
void onAboutToExitScope() override;
/** Return the approx RAM usage for this cache. */
size_t getMemoryUsed() const { return fMemoryUsed; }

View File

@ -44,6 +44,10 @@ public:
return fCache.getDescriptor();
}
void onAboutToExitScope() override {
fStrikeCache->attachNode(this);
}
SkStrikeCache* const fStrikeCache;
Node* fNext{nullptr};
Node* fPrev{nullptr};
@ -165,6 +169,17 @@ auto SkStrikeCache::findOrCreateStrike(const SkDescriptor& desc,
return node;
}
SkScopedStrike SkStrikeCache::findOrCreateScopedStrike(const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface) {
Node* node = this->findAndDetachStrike(desc);
if (node == nullptr) {
auto scaler = CreateScalerContext(desc, effects, typeface);
node = this->createStrike(desc, std::move(scaler));
}
return SkScopedStrike{node};
}
SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
const SkFont& font,
const SkPaint& paint,

View File

@ -114,6 +114,10 @@ public:
SkStrike* targetCache);
bool desperationSearchForPath(const SkDescriptor& desc, SkGlyphID glyphID, SkPath* path);
SkScopedStrike findOrCreateScopedStrike(const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface);
static ExclusiveStrikePtr FindOrCreateStrikeExclusive(
const SkFont& font,
const SkPaint& paint,