Have SkStrikeCache track memory usage
Have the SkStrikeCache track all memory usage. This
moves all the validation code to the SkStrikeCache and
out of the SkScalerCache.
* Some header cleanup.
Change-Id: I9c0a3bb217299deed12223221e2bb5fd09eadb39
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/271740
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/src/core/SkScalerCache.cpp b/src/core/SkScalerCache.cpp
index 52fc5b1..7e8741a 100644
--- a/src/core/SkScalerCache.cpp
+++ b/src/core/SkScalerCache.cpp
@@ -10,11 +10,8 @@
#include "include/core/SkGraphics.h"
#include "include/core/SkPath.h"
#include "include/core/SkTypeface.h"
-#include "include/private/SkMutex.h"
-#include "include/private/SkOnce.h"
-#include "include/private/SkTemplates.h"
#include "src/core/SkEnumerate.h"
-#include <cctype>
+#include "src/core/SkScalerContext.h"
static SkFontMetrics use_or_generate_metrics(
const SkFontMetrics* metrics, SkScalerContext* context) {
@@ -39,12 +36,6 @@
SkASSERT(fScalerContext != nullptr);
}
-#ifdef SK_DEBUG
-#define VALIDATE() AutoValidate av(this)
-#else
-#define VALIDATE()
-#endif
-
// -- glyph creation -------------------------------------------------------------------------------
std::tuple<SkGlyph*, size_t> SkScalerCache::makeGlyph(SkPackedGlyphID packedGlyphID) {
SkGlyph* glyph = fAlloc.make<SkGlyph>(packedGlyphID);
@@ -53,7 +44,6 @@
}
std::tuple<SkGlyph*, size_t> SkScalerCache::glyph(SkPackedGlyphID packedGlyphID) {
- VALIDATE();
SkGlyph* glyph = fGlyphMap.findOrNull(packedGlyphID);
size_t bytes = 0;
if (glyph == nullptr) {
@@ -77,7 +67,6 @@
if (glyph->setPath(&fAlloc, path)) {
pathDelta = glyph->path()->approximateBytesUsed();
}
- fMemoryUsed += pathDelta;
return {glyph->path(), pathDelta};
}
@@ -127,7 +116,6 @@
if (glyph->setMetricsAndImage(&fAlloc, from)) {
imageDelta= glyph->imageSize();
}
- fMemoryUsed += delta + imageDelta;
return {glyph, delta + imageDelta};
}
@@ -135,7 +123,6 @@
SkSpan<const SkGlyphID> glyphIDs, const SkGlyph* results[]) {
SkAutoMutexExclusive lock{fMu};
auto [glyphs, delta] = this->internalPrepare(glyphIDs, kMetricsOnly, results);
- fMemoryUsed += delta;
return {glyphs, delta};
}
@@ -143,7 +130,6 @@
SkSpan<const SkGlyphID> glyphIDs, const SkGlyph* results[]) {
SkAutoMutexExclusive lock{fMu};
auto [glyphs, delta] = this->internalPrepare(glyphIDs, kMetricsAndPath, results);
- fMemoryUsed += delta;
return {glyphs, delta};
}
@@ -159,7 +145,6 @@
*cursor++ = glyph;
}
- fMemoryUsed += delta;
return {{results, glyphIDs.size()}, delta};
}
@@ -191,7 +176,6 @@
}
});
- fMemoryUsed += delta + imageDelta;
return delta + imageDelta;
}
@@ -207,7 +191,7 @@
rejects->reject(i);
}
});
- fMemoryUsed += delta;
+
return delta;
}
@@ -222,7 +206,7 @@
rejects->reject(i);
}
});
- fMemoryUsed += delta;
+
return delta;
}
@@ -247,7 +231,7 @@
rejects->reject(i, glyph->maxDimension());
}
});
- fMemoryUsed += delta + pathDelta;
+
return delta + pathDelta;
}
@@ -275,7 +259,7 @@
}
#ifdef SK_DEBUG
-void SkScalerCache::forceValidate() const {
+size_t SkScalerCache::recalculateMemoryUsed() const {
SkAutoMutexExclusive lock{fMu};
size_t memoryUsed = sizeof(*this);
fGlyphMap.foreach ([&memoryUsed](const SkGlyph* glyphPtr) {
@@ -287,15 +271,8 @@
memoryUsed += glyphPtr->path()->approximateBytesUsed();
}
});
- SkASSERT(fMemoryUsed == memoryUsed);
+ return memoryUsed;
}
-
-void SkScalerCache::validate() const {
-#ifdef SK_DEBUG_GLYPH_CACHE
- forceValidate();
-#endif
-}
-
#endif // SK_DEBUG
diff --git a/src/core/SkScalerCache.h b/src/core/SkScalerCache.h
index 5c2ab99..68b202b 100644
--- a/src/core/SkScalerCache.h
+++ b/src/core/SkScalerCache.h
@@ -9,17 +9,18 @@
#include "include/core/SkFontMetrics.h"
#include "include/core/SkFontTypes.h"
-#include "include/core/SkPaint.h"
+#include "include/private/SkMutex.h"
#include "include/private/SkTHash.h"
#include "include/private/SkTemplates.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkDescriptor.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkGlyphRunPainter.h"
-#include "src/core/SkScalerContext.h"
#include "src/core/SkStrikeForGPU.h"
#include <memory>
+class SkScalerContext;
+
// This class represents a strike: a specific combination of typeface, size, matrix, etc., and
// holds the glyphs for that strike.
@@ -80,42 +81,14 @@
size_t prepareForPathDrawing(
SkDrawableGlyphBuffer* drawables, SkSourceGlyphBuffer* rejects) SK_EXCLUDES(fMu);
- /** Return the approx RAM usage for this cache. */
- size_t getMemoryUsed() const SK_EXCLUDES(fMu) {
- SkAutoMutexExclusive lock{fMu};
- return fMemoryUsed;
- }
-
void dump() const SK_EXCLUDES(fMu);
SkScalerContext* getScalerContext() const { return fScalerContext.get(); }
#ifdef SK_DEBUG
- void forceValidate() const SK_EXCLUDES(fMu);
- void validate() const;
-#else
- void validate() const {}
+ size_t recalculateMemoryUsed() const SK_EXCLUDES(fMu);
#endif
- class AutoValidate : SkNoncopyable {
- public:
- AutoValidate(const SkScalerCache* cache) : fCache(cache) {
- if (fCache) {
- fCache->validate();
- }
- }
- ~AutoValidate() {
- if (fCache) {
- fCache->validate();
- }
- }
- void forget() {
- fCache = nullptr;
- }
- private:
- const SkScalerCache* fCache;
- };
-
private:
class GlyphMapHashTraits {
public:
@@ -170,9 +143,6 @@
static constexpr size_t kMinAllocAmount = kMinGlyphImageSize * kMinGlyphCount;
SkArenaAlloc fAlloc SK_GUARDED_BY(fMu) {kMinAllocAmount};
-
- // Tracks (approx) how much ram is tied-up in this strike.
- size_t fMemoryUsed SK_GUARDED_BY(fMu) {sizeof(SkScalerCache)};
};
#endif // SkStrike_DEFINED
diff --git a/src/core/SkStrikeCache.cpp b/src/core/SkStrikeCache.cpp
index 7c793fb..51d40c2 100644
--- a/src/core/SkStrikeCache.cpp
+++ b/src/core/SkStrikeCache.cpp
@@ -178,7 +178,7 @@
"%s/%s_%d/%p", gGlyphCacheDumpName, fontName.c_str(), rec.fFontID, &strike);
dump->dumpNumericValue(dumpName.c_str(),
- "size", "bytes", strike.fScalerCache.getMemoryUsed());
+ "size", "bytes", strike.fMemoryUsed);
dump->dumpNumericValue(dumpName.c_str(),
"glyph_count", "objects",
strike.fScalerCache.countCachedGlyphs());
@@ -196,7 +196,6 @@
SkAutoSpinlock ac(fLock);
this->validate();
- strike->fScalerCache.validate();
this->internalAttachToHead(strike);
this->internalPurge();
@@ -352,7 +351,7 @@
// Only delete if the strike is not pinned.
if (strike->fPinner == nullptr || strike->fPinner->canDelete()) {
- bytesFreed += strike->fScalerCache.getMemoryUsed();
+ bytesFreed += strike->fMemoryUsed;
countFreed += 1;
this->internalDetachStrike(strike);
strike->unref();
@@ -385,13 +384,13 @@
}
fCacheCount += 1;
- fTotalMemoryUsed += strike->fScalerCache.getMemoryUsed();
+ fTotalMemoryUsed += strike->fMemoryUsed;
}
void SkStrikeCache::internalDetachStrike(Strike* strike) {
SkASSERT(fCacheCount > 0);
fCacheCount -= 1;
- fTotalMemoryUsed -= strike->fScalerCache.getMemoryUsed();
+ fTotalMemoryUsed -= strike->fMemoryUsed;
if (strike->fPrev) {
strike->fPrev->fNext = strike->fNext;
@@ -415,8 +414,9 @@
#ifdef SK_DEBUG
void SkStrikeCache::validateGlyphCacheDataSize() const {
this->forEachStrike(
- [](const Strike& strike) { strike.fScalerCache.forceValidate();
- });
+ [](const Strike& strike) {
+ SkASSERT(strike.fMemoryUsed == strike.fScalerCache.recalculateMemoryUsed());
+ });
}
#endif
@@ -427,7 +427,7 @@
const Strike* strike = fHead;
while (strike != nullptr) {
- computedBytes += strike->fScalerCache.getMemoryUsed();
+ computedBytes += strike->fMemoryUsed;
computedCount += 1;
strike = strike->fNext;
}
diff --git a/src/core/SkStrikeCache.h b/src/core/SkStrikeCache.h
index 74ddd23..8a273a5 100644
--- a/src/core/SkStrikeCache.h
+++ b/src/core/SkStrikeCache.h
@@ -57,14 +57,14 @@
SkGlyph* mergeGlyphAndImage(SkPackedGlyphID toID, const SkGlyph& from) {
auto [glyph, delta] = fScalerCache.mergeGlyphAndImage(toID, from);
fMemoryUsed += delta;
- SkASSERT(fMemoryUsed = fScalerCache.getMemoryUsed());
+ SkASSERT(fScalerCache.recalculateMemoryUsed() == fMemoryUsed);
return glyph;
}
const SkPath* mergePath(SkGlyph* glyph, const SkPath* path) {
auto [glyphPath, delta] = fScalerCache.mergePath(glyph, path);
fMemoryUsed += delta;
- SkASSERT(fMemoryUsed = fScalerCache.getMemoryUsed());
+ SkASSERT(fScalerCache.recalculateMemoryUsed() == fMemoryUsed);
return glyphPath;
}
@@ -85,7 +85,7 @@
const SkGlyph* results[]) {
auto [glyphs, delta] = fScalerCache.metrics(glyphIDs, results);
fMemoryUsed += delta;
- SkASSERT(fMemoryUsed = fScalerCache.getMemoryUsed());
+ SkASSERT(fScalerCache.recalculateMemoryUsed() == fMemoryUsed);
return glyphs;
}
@@ -93,7 +93,7 @@
const SkGlyph* results[]) {
auto [glyphs, delta] = fScalerCache.preparePaths(glyphIDs, results);
fMemoryUsed += delta;
- SkASSERT(fMemoryUsed = fScalerCache.getMemoryUsed());
+ SkASSERT(fScalerCache.recalculateMemoryUsed() == fMemoryUsed);
return glyphs;
}
@@ -101,14 +101,14 @@
const SkGlyph* results[]) {
auto [glyphs, delta] = fScalerCache.prepareImages(glyphIDs, results);
fMemoryUsed += delta;
- SkASSERT(fMemoryUsed = fScalerCache.getMemoryUsed());
+ SkASSERT(fScalerCache.recalculateMemoryUsed() == fMemoryUsed);
return glyphs;
}
void prepareForDrawingMasksCPU(SkDrawableGlyphBuffer* drawables) {
size_t delta = fScalerCache.prepareForDrawingMasksCPU(drawables);
fMemoryUsed += delta;
- SkASSERT(fMemoryUsed = fScalerCache.getMemoryUsed());
+ SkASSERT(fScalerCache.recalculateMemoryUsed() == fMemoryUsed);
}
const SkGlyphPositionRoundingSpec& roundingSpec() const override {
@@ -123,21 +123,21 @@
SkDrawableGlyphBuffer* drawbles, SkSourceGlyphBuffer* rejects) override {
size_t delta = fScalerCache.prepareForMaskDrawing(drawbles, rejects);
fMemoryUsed += delta;
- SkASSERT(fMemoryUsed = fScalerCache.getMemoryUsed());
+ SkASSERT(fScalerCache.recalculateMemoryUsed() == fMemoryUsed);
}
void prepareForSDFTDrawing(
SkDrawableGlyphBuffer* drawbles, SkSourceGlyphBuffer* rejects) override {
size_t delta = fScalerCache.prepareForSDFTDrawing(drawbles, rejects);
fMemoryUsed += delta;
- SkASSERT(fMemoryUsed = fScalerCache.getMemoryUsed());
+ SkASSERT(fScalerCache.recalculateMemoryUsed() == fMemoryUsed);
}
void prepareForPathDrawing(
SkDrawableGlyphBuffer* drawbles, SkSourceGlyphBuffer* rejects) override {
size_t delta = fScalerCache.prepareForPathDrawing(drawbles, rejects);
fMemoryUsed += delta;
- SkASSERT(fMemoryUsed = fScalerCache.getMemoryUsed());
+ SkASSERT(fScalerCache.recalculateMemoryUsed() == fMemoryUsed);
}
void onAboutToExitScope() override {
@@ -149,7 +149,7 @@
Strike* fPrev{nullptr};
SkScalerCache fScalerCache;
std::unique_ptr<SkStrikePinner> fPinner;
- size_t fMemoryUsed{0};
+ size_t fMemoryUsed{sizeof(SkScalerCache)};
}; // Strike
class ExclusiveStrikePtr {