aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2018-04-19 13:12:07 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-04-19 20:00:04 +0000
commite68c4fbf601e38fdab1e0ab4093647d5538fff11 (patch)
treefbc67e9f9593842288067640e86c809d0b00863b
parent33c442206af737d60b120e7acc0e2c0f4b786e2c (diff)
Adding pinning to the strike cache
Here is a simple API for the object that pins, and how it flows through the cache. BUG=skia:7515 Change-Id: I1b8304dc6f9d8652282300fc1e52d52debb5b6f4 Reviewed-on: https://skia-review.googlesource.com/122500 Reviewed-by: Mike Klein <mtklein@chromium.org> Commit-Queue: Herb Derby <herb@google.com>
-rw-r--r--src/core/SkStrikeCache.cpp169
-rw-r--r--src/core/SkStrikeCache.h10
2 files changed, 97 insertions, 82 deletions
diff --git a/src/core/SkStrikeCache.cpp b/src/core/SkStrikeCache.cpp
index 0c6cb83447..0fb36aaf14 100644
--- a/src/core/SkStrikeCache.cpp
+++ b/src/core/SkStrikeCache.cpp
@@ -30,12 +30,16 @@ static SkStrikeCache& get_globals() {
struct SkStrikeCache::Node {
Node(const SkDescriptor& desc,
- std::unique_ptr<SkScalerContext> scaler,
- const SkPaint::FontMetrics& metrics)
- : fCache{desc, std::move(scaler), metrics} {}
- Node* fNext{nullptr};
- Node* fPrev{nullptr};
- SkGlyphCache fCache;
+ std::unique_ptr<SkScalerContext> scaler,
+ const SkPaint::FontMetrics& metrics,
+ std::unique_ptr<SkStrikePinner> pinner)
+ : fCache{desc, std::move(scaler), metrics}
+ , fPinner{std::move(pinner)} {}
+
+ Node* fNext{nullptr};
+ Node* fPrev{nullptr};
+ SkGlyphCache fCache;
+ std::unique_ptr<SkStrikePinner> fPinner;
};
SkStrikeCache::ExclusiveStrikePtr::ExclusiveStrikePtr(SkStrikeCache::Node* node) : fNode{node} {}
@@ -114,6 +118,39 @@ std::unique_ptr<SkScalerContext> SkStrikeCache::CreateScalerContext(
return scaler;
}
+SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
+ const SkDescriptor& desc, const SkScalerContextEffects& effects, const SkTypeface& typeface)
+{
+ auto cache = FindStrikeExclusive(desc);
+ if (cache == nullptr) {
+ auto scaler = CreateScalerContext(desc, effects, typeface);
+ cache = CreateStrikeExclusive(desc, std::move(scaler));
+ }
+ return cache;
+}
+
+SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
+ const SkPaint& paint,
+ const SkSurfaceProps* surfaceProps,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix* deviceMatrix)
+{
+ SkAutoDescriptor ad;
+ SkScalerContextEffects effects;
+
+ auto desc = SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
+ paint, surfaceProps, scalerContextFlags, deviceMatrix, &ad, &effects);
+
+ auto tf = SkPaintPriv::GetTypefaceOrDefault(paint);
+
+ return FindOrCreateStrikeExclusive(*desc, effects, *tf);
+}
+
+SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(const SkPaint& paint) {
+ return FindOrCreateStrikeExclusive(
+ paint, nullptr, kFakeGammaAndBoostContrast, nullptr);
+}
+
void SkStrikeCache::PurgeAll() {
get_globals().purgeAll();
}
@@ -210,6 +247,22 @@ SkExclusiveStrikePtr SkStrikeCache::findStrikeExclusive(const SkDescriptor& desc
return SkExclusiveStrikePtr(nullptr);
}
+SkExclusiveStrikePtr SkStrikeCache::CreateStrikeExclusive(
+ const SkDescriptor& desc,
+ std::unique_ptr<SkScalerContext> scaler,
+ SkPaint::FontMetrics* maybeMetrics,
+ std::unique_ptr<SkStrikePinner> pinner)
+{
+ SkPaint::FontMetrics fontMetrics;
+ if (maybeMetrics != nullptr) {
+ fontMetrics = *maybeMetrics;
+ } else {
+ scaler->getFontMetrics(&fontMetrics);
+ }
+
+ return SkExclusiveStrikePtr(new Node(desc, std::move(scaler), fontMetrics, std::move(pinner)));
+}
+
void SkStrikeCache::purgeAll() {
SkAutoExclusive ac(fLock);
this->internalPurge(fTotalMemoryUsed);
@@ -327,17 +380,19 @@ size_t SkStrikeCache::internalPurge(size_t minBytesNeeded) {
size_t bytesFreed = 0;
int countFreed = 0;
- // we start at the tail and proceed backwards, as the linklist is in LRU
+ // Start at the tail and proceed backwards deleting; the list is in LRU
// order, with unimportant entries at the tail.
Node* node = this->internalGetTail();
- while (node != nullptr &&
- (bytesFreed < bytesNeeded || countFreed < countNeeded)) {
+ while (node != nullptr && (bytesFreed < bytesNeeded || countFreed < countNeeded)) {
Node* prev = node->fPrev;
- bytesFreed += node->fCache.getMemoryUsed();
- countFreed += 1;
- this->internalDetachCache(node);
- delete node;
+ // Only delete if the strike is not pinned.
+ if (node->fPinner == nullptr || node->fPinner->canDelete()) {
+ bytesFreed += node->fCache.getMemoryUsed();
+ countFreed += 1;
+ this->internalDetachCache(node);
+ delete node;
+ }
node = prev;
}
@@ -381,6 +436,27 @@ void SkStrikeCache::internalDetachCache(Node* node) {
node->fPrev = node->fNext = nullptr;
}
+#ifdef SK_DEBUG
+void SkStrikeCache::validate() const {
+ size_t computedBytes = 0;
+ int computedCount = 0;
+
+ const Node* node = fHead;
+ while (node != nullptr) {
+ computedBytes += node->fCache.getMemoryUsed();
+ computedCount += 1;
+ node = node->fNext;
+ }
+
+ SkASSERTF(fCacheCount == computedCount, "fCacheCount: %d, computedCount: %d", fCacheCount,
+ computedCount);
+ SkASSERTF(fTotalMemoryUsed == computedBytes, "fTotalMemoryUsed: %d, computedBytes: %d",
+ fTotalMemoryUsed, computedBytes);
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
size_t SkGraphics::GetFontCacheLimit() {
return get_globals().getCacheSizeLimit();
}
@@ -417,70 +493,3 @@ void SkGraphics::PurgeFontCache() {
get_globals().purgeAll();
SkTypefaceCache::PurgeAll();
}
-
-SkExclusiveStrikePtr SkStrikeCache::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 Node(desc, move(scaler), fontMetrics));
-}
-
-SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
- const SkDescriptor& desc, const SkScalerContextEffects& effects, const SkTypeface& typeface)
-{
- auto cache = FindStrikeExclusive(desc);
- if (cache == nullptr) {
- auto scaler = CreateScalerContext(desc, effects, typeface);
- cache = CreateStrikeExclusive(desc, move(scaler));
- }
- return cache;
-}
-
-SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(
- const SkPaint& paint,
- const SkSurfaceProps* surfaceProps,
- SkScalerContextFlags scalerContextFlags,
- const SkMatrix* deviceMatrix)
-{
- SkAutoDescriptor ad;
- SkScalerContextEffects effects;
-
- auto desc = SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
- paint, surfaceProps, scalerContextFlags, deviceMatrix, &ad, &effects);
-
- auto tf = SkPaintPriv::GetTypefaceOrDefault(paint);
-
- return FindOrCreateStrikeExclusive(*desc, effects, *tf);
-}
-
-SkExclusiveStrikePtr SkStrikeCache::FindOrCreateStrikeExclusive(const SkPaint& paint) {
- return FindOrCreateStrikeExclusive(
- paint, nullptr, kFakeGammaAndBoostContrast, nullptr);
-}
-
-#ifdef SK_DEBUG
-void SkStrikeCache::validate() const {
- size_t computedBytes = 0;
- int computedCount = 0;
-
- const Node* node = fHead;
- while (node != nullptr) {
- computedBytes += node->fCache.getMemoryUsed();
- computedCount += 1;
- node = node->fNext;
- }
-
- SkASSERTF(fCacheCount == computedCount, "fCacheCount: %d, computedCount: %d", fCacheCount,
- computedCount);
- SkASSERTF(fTotalMemoryUsed == computedBytes, "fTotalMemoryUsed: %d, computedBytes: %d",
- fTotalMemoryUsed, computedBytes);
-}
-#endif \ No newline at end of file
diff --git a/src/core/SkStrikeCache.h b/src/core/SkStrikeCache.h
index a98b508c15..cdaffb5688 100644
--- a/src/core/SkStrikeCache.h
+++ b/src/core/SkStrikeCache.h
@@ -29,6 +29,12 @@ class SkTraceMemoryDump;
///////////////////////////////////////////////////////////////////////////////
+class SkStrikePinner {
+public:
+ virtual ~SkStrikePinner() = default;
+ virtual bool canDelete() = 0;
+};
+
class SkStrikeCache {
struct Node;
@@ -36,7 +42,6 @@ public:
SkStrikeCache() = default;
~SkStrikeCache();
-
class ExclusiveStrikePtr {
public:
explicit ExclusiveStrikePtr(Node*);
@@ -64,7 +69,8 @@ public:
static ExclusiveStrikePtr CreateStrikeExclusive(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
- SkPaint::FontMetrics* maybeMetrics = nullptr);
+ SkPaint::FontMetrics* maybeMetrics = nullptr,
+ std::unique_ptr<SkStrikePinner> = nullptr);
static ExclusiveStrikePtr FindOrCreateStrikeExclusive(
const SkDescriptor& desc,