1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
/*
* Copyright 2010 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkStrikeCache_DEFINED
#define SkStrikeCache_DEFINED
#include <unordered_map>
#include <unordered_set>
#include "SkDescriptor.h"
#include "SkSpinlock.h"
#include "SkTemplates.h"
class SkGlyphCache;
class SkTraceMemoryDump;
#ifndef SK_DEFAULT_FONT_CACHE_COUNT_LIMIT
#define SK_DEFAULT_FONT_CACHE_COUNT_LIMIT 2048
#endif
#ifndef SK_DEFAULT_FONT_CACHE_LIMIT
#define SK_DEFAULT_FONT_CACHE_LIMIT (2 * 1024 * 1024)
#endif
#ifndef SK_DEFAULT_FONT_CACHE_POINT_SIZE_LIMIT
#define SK_DEFAULT_FONT_CACHE_POINT_SIZE_LIMIT 256
#endif
///////////////////////////////////////////////////////////////////////////////
class SkStrikePinner {
public:
virtual ~SkStrikePinner() = default;
virtual bool canDelete() = 0;
};
class SkStrikeCache {
struct Node;
public:
SkStrikeCache() = default;
~SkStrikeCache();
class ExclusiveStrikePtr {
public:
explicit ExclusiveStrikePtr(Node*);
ExclusiveStrikePtr();
ExclusiveStrikePtr(const ExclusiveStrikePtr&) = delete;
ExclusiveStrikePtr& operator = (const ExclusiveStrikePtr&) = delete;
ExclusiveStrikePtr(ExclusiveStrikePtr&&);
ExclusiveStrikePtr& operator = (ExclusiveStrikePtr&&);
~ExclusiveStrikePtr();
SkGlyphCache* get() const;
SkGlyphCache* operator -> () const;
SkGlyphCache& operator * () const;
explicit operator bool () const;
friend bool operator == (const ExclusiveStrikePtr&, const ExclusiveStrikePtr&);
friend bool operator == (const ExclusiveStrikePtr&, decltype(nullptr));
friend bool operator == (decltype(nullptr), const ExclusiveStrikePtr&);
private:
Node* fNode;
};
static ExclusiveStrikePtr FindStrikeExclusive(const SkDescriptor&);
static bool DesperationSearchForImage(const SkDescriptor& desc,
SkGlyph* glyph,
SkGlyphCache* targetCache);
static bool DesperationSearchForPath(
const SkDescriptor& desc, SkGlyphID glyphID, SkPath* path);
static ExclusiveStrikePtr CreateStrikeExclusive(
const SkDescriptor& desc,
std::unique_ptr<SkScalerContext> scaler,
SkPaint::FontMetrics* maybeMetrics = nullptr,
std::unique_ptr<SkStrikePinner> = nullptr);
static ExclusiveStrikePtr FindOrCreateStrikeExclusive(
const SkDescriptor& desc,
const SkScalerContextEffects& effects,
const SkTypeface& typeface);
static ExclusiveStrikePtr FindOrCreateStrikeExclusive(
const SkPaint& paint,
const SkSurfaceProps* surfaceProps,
SkScalerContextFlags scalerContextFlags,
const SkMatrix* deviceMatrix);
static ExclusiveStrikePtr FindOrCreateStrikeExclusive(const SkPaint& paint);
static std::unique_ptr<SkScalerContext> CreateScalerContext(
const SkDescriptor&, const SkScalerContextEffects&, const SkTypeface&);
static void PurgeAll();
static void Validate();
static void Dump();
// Dump memory usage statistics of all the attaches caches in the process using the
// SkTraceMemoryDump interface.
static void DumpMemoryStatistics(SkTraceMemoryDump* dump);
// call when a glyphcache is available for caching (i.e. not in use)
void attachNode(Node* node);
ExclusiveStrikePtr findStrikeExclusive(const SkDescriptor&);
// Routines to find suitable data when working in a remote cache situation. These are
// suitable as substitutes for similar calls in SkScalerContext.
bool desperationSearchForImage(const SkDescriptor& desc,
SkGlyph* glyph,
SkGlyphCache* targetCache);
bool desperationSearchForPath(const SkDescriptor& desc, SkGlyphID glyphID, SkPath* path);
void purgeAll(); // does not change budget
int getCacheCountLimit() const;
int setCacheCountLimit(int limit);
int getCacheCountUsed() const;
size_t getCacheSizeLimit() const;
size_t setCacheSizeLimit(size_t limit);
size_t getTotalMemoryUsed() const;
int getCachePointSizeLimit() const;
int setCachePointSizeLimit(int limit);
#ifdef SK_DEBUG
void validate() const;
#else
void validate() const {}
#endif
private:
static void Attach(Node* node);
// The following methods can only be called when mutex is already held.
Node* internalGetHead() const { return fHead; }
Node* internalGetTail() const { return fTail; }
void internalDetachCache(Node*);
void internalAttachToHead(Node*);
// Checkout budgets, modulated by the specified min-bytes-needed-to-purge,
// and attempt to purge caches to match.
// Returns number of bytes freed.
size_t internalPurge(size_t minBytesNeeded = 0);
void forEachStrike(std::function<void(const SkGlyphCache&)> visitor) const;
mutable SkSpinlock fLock;
Node* fHead{nullptr};
Node* fTail{nullptr};
size_t fTotalMemoryUsed{0};
size_t fCacheSizeLimit{SK_DEFAULT_FONT_CACHE_LIMIT};
int32_t fCacheCountLimit{SK_DEFAULT_FONT_CACHE_COUNT_LIMIT};
int32_t fCacheCount{0};
int32_t fPointSizeLimit{SK_DEFAULT_FONT_CACHE_POINT_SIZE_LIMIT};
};
using SkExclusiveStrikePtr = SkStrikeCache::ExclusiveStrikePtr;
#endif // SkStrikeCache_DEFINED
|