Remove accessor to the scalerContext on SkStrike
Also, the scaler is not implemented with multi-threaded code.
Protect it with the mutex.
Switch PathText viewer and benchmark over to using
SkBulkGlyphMetricsAndPaths.
Change-Id: I9a4be1afb22e5be68de0069de75eccc00ddb970c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/633177
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/bench/PathTextBench.cpp b/bench/PathTextBench.cpp
index fd1a4d0..238141d 100644
--- a/bench/PathTextBench.cpp
+++ b/bench/PathTextBench.cpp
@@ -48,14 +48,12 @@
void onDelayedSetup() override {
SkFont defaultFont;
SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(defaultFont);
- auto strike = strikeSpec.findOrCreateStrike();
- SkArenaAlloc alloc(1 << 12); // This is a mock SkStrikeCache.
+ SkBulkGlyphMetricsAndPaths pathMaker{strikeSpec};
for (int i = 0; i < kNumGlyphs; ++i) {
- SkPackedGlyphID id(defaultFont.unicharToGlyph(kGlyphs[i]));
- SkGlyph glyph = strike->getScalerContext()->makeGlyph(id, &alloc);
- strike->getScalerContext()->getPath(glyph, &alloc);
- if (glyph.path()) {
- fGlyphs[i] = *glyph.path();
+ SkGlyphID id(defaultFont.unicharToGlyph(kGlyphs[i]));
+ const SkGlyph* glyph = pathMaker.glyph(id);
+ if (glyph->path()) {
+ fGlyphs[i] = *glyph->path();
}
fGlyphs[i].setIsVolatile(fUncached);
}
diff --git a/src/core/SkStrike.cpp b/src/core/SkStrike.cpp
index bb8f3dd..94a438d 100644
--- a/src/core/SkStrike.cpp
+++ b/src/core/SkStrike.cpp
@@ -39,12 +39,12 @@
std::unique_ptr<SkScalerContext> scaler,
const SkFontMetrics* metrics,
std::unique_ptr<SkStrikePinner> pinner)
- : fScalerContext{std::move(scaler)}
- , fFontMetrics{use_or_generate_metrics(metrics, fScalerContext.get())}
- , fRoundingSpec{fScalerContext->isSubpixel(),
- fScalerContext->computeAxisAlignmentForHText()}
+ : fFontMetrics{use_or_generate_metrics(metrics, scaler.get())}
+ , fRoundingSpec{scaler->isSubpixel(),
+ scaler->computeAxisAlignmentForHText()}
, fStrikeSpec{strikeSpec}
, fStrikeCache{strikeCache}
+ , fScalerContext{std::move(scaler)}
, fPinner{std::move(pinner)} {
SkASSERT(fScalerContext != nullptr);
}
@@ -388,8 +388,8 @@
void SkStrike::dumpMemoryStatistics(SkTraceMemoryDump* dump) const {
SkAutoMutexExclusive lock{fMu};
- const SkTypeface* face = this->getScalerContext()->getTypeface();
- const SkScalerContextRec& rec = this->getScalerContext()->getRec();
+ const SkTypeface* face = fScalerContext->getTypeface();
+ const SkScalerContextRec& rec = fScalerContext->getRec();
SkString fontName;
face->getFamilyName(&fontName);
diff --git a/src/core/SkStrike.h b/src/core/SkStrike.h
index 7ab4483..50fe105 100644
--- a/src/core/SkStrike.h
+++ b/src/core/SkStrike.h
@@ -120,10 +120,6 @@
// Convert all the IDs into SkDrawables in the span.
void glyphIDsToDrawables(SkSpan<sktext::IDOrDrawable> idsOrDrawables) SK_EXCLUDES(fMu);
- SkScalerContext* getScalerContext() const {
- return fScalerContext.get();
- }
-
const SkStrikeSpec& strikeSpec() const {
return fStrikeSpec;
}
@@ -179,24 +175,29 @@
const SkGlyph** results) SK_REQUIRES(fMu);
// The following are const and need no mutex protection.
- const std::unique_ptr<SkScalerContext> fScalerContext;
- const SkFontMetrics fFontMetrics;
- const SkGlyphPositionRoundingSpec fRoundingSpec;
- const SkStrikeSpec fStrikeSpec;
- SkStrikeCache* const fStrikeCache;
+ const SkFontMetrics fFontMetrics;
+ const SkGlyphPositionRoundingSpec fRoundingSpec;
+ const SkStrikeSpec fStrikeSpec;
+ SkStrikeCache* const fStrikeCache;
// This mutex provides protection for this specific SkStrike.
mutable SkMutex fMu;
- // Map from a combined GlyphID and sub-pixel position to a SkGlyphDigest. The actual glyph is
+
+ // Maps from a combined GlyphID and sub-pixel position to a SkGlyphDigest. The actual glyph is
// stored in the fAlloc. The pointer to the glyph is stored fGlyphForIndex. The
// SkGlyphDigest's fIndex field stores the index. This pointer provides an unchanging
// reference to the SkGlyph as long as the strike is alive, and fGlyphForIndex
// provides a dense index for glyphs.
SkTHashMap<SkPackedGlyphID, SkGlyphDigest, SkPackedGlyphID::Hash>
fDigestForPackedGlyphID SK_GUARDED_BY(fMu);
+
+ // Maps from a glyphIndex to a glyph
std::vector<SkGlyph*> fGlyphForIndex SK_GUARDED_BY(fMu);
- // so we don't grow our arrays a lot
+ // Context that corresponds to the glyph information in this strike.
+ const std::unique_ptr<SkScalerContext> fScalerContext SK_GUARDED_BY(fMu);
+
+ // So, we don't grow our arrays a lot.
inline static constexpr size_t kMinGlyphCount = 8;
inline static constexpr size_t kMinGlyphImageSize = 16 /* height */ * 8 /* width */;
inline static constexpr size_t kMinAllocAmount = kMinGlyphImageSize * kMinGlyphCount;
diff --git a/tools/viewer/PathTextSlide.cpp b/tools/viewer/PathTextSlide.cpp
index 7f2c327..8135e64 100644
--- a/tools/viewer/PathTextSlide.cpp
+++ b/tools/viewer/PathTextSlide.cpp
@@ -39,17 +39,15 @@
SkFont defaultFont;
SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(defaultFont);
- auto strike = strikeSpec.findOrCreateStrike();
- SkArenaAlloc alloc(1 << 12); // This is a mock SkStrikeCache.
+ SkBulkGlyphMetricsAndPaths pathMaker{strikeSpec};
SkPath glyphPaths[52];
for (int i = 0; i < 52; ++i) {
// I and l are rects on OS X ...
char c = "aQCDEFGH7JKLMNOPBRZTUVWXYSAbcdefghijk1mnopqrstuvwxyz"[i];
- SkPackedGlyphID id(defaultFont.unicharToGlyph(c));
- SkGlyph glyph = strike->getScalerContext()->makeGlyph(id, &alloc);
- strike->getScalerContext()->getPath(glyph, &alloc);
- if (glyph.path()) {
- glyphPaths[i] = *glyph.path();
+ SkGlyphID id(defaultFont.unicharToGlyph(c));
+ const SkGlyph* glyph = pathMaker.glyph(id);
+ if (glyph->path()) {
+ glyphPaths[i] = *glyph->path();
}
}