Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/core/SkGlyphCache.h

Issue 1194423004: Cleanup: Comment and ordering changes. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
5 * found in the LICENSE file.
6 */ 5 */
7 6
8 #ifndef SkGlyphCache_DEFINED 7 #ifndef SkGlyphCache_DEFINED
9 #define SkGlyphCache_DEFINED 8 #define SkGlyphCache_DEFINED
10 9
11 #include "SkBitmap.h" 10 #include "SkBitmap.h"
12 #include "SkChecksum.h" 11 #include "SkChecksum.h"
13 #include "SkChunkAlloc.h" 12 #include "SkChunkAlloc.h"
14 #include "SkDescriptor.h" 13 #include "SkDescriptor.h"
15 #include "SkGlyph.h" 14 #include "SkGlyph.h"
16 #include "SkScalerContext.h" 15 #include "SkScalerContext.h"
17 #include "SkTemplates.h" 16 #include "SkTemplates.h"
18 #include "SkTDArray.h" 17 #include "SkTDArray.h"
19 18
20 class SkPaint; 19 class SkPaint;
21 20
22 class SkGlyphCache_Globals; 21 class SkGlyphCache_Globals;
23 22
24 // Enable this locally to add stats for hash-table hit rates. It also extends th e dump() 23 // Enable this locally to add stats for hash-table hit rates. It also extends th e dump() output
25 // output to show those stats. 24 // to show those stats.
26 //#define SK_GLYPHCACHE_TRACK_HASH_STATS 25 //#define SK_GLYPHCACHE_TRACK_HASH_STATS
27 26
28 /** \class SkGlyphCache 27 /** \class SkGlyphCache
29 28
30 This class represents a strike: a specific combination of typeface, size, 29 This class represents a strike: a specific combination of typeface, size, ma trix, etc., and
31 matrix, etc., and holds the glyphs for that strike. Calling any of the 30 holds the glyphs for that strike. Calling any of the getUnichar.../getGlyphI D... methods will
32 getUnichar.../getGlyphID... methods will return the requested glyph, 31 return the requested glyph, either instantly if it is already cached, or by first generating
33 either instantly if it is already cached, or by first generating it and then 32 it and then adding it to the strike.
34 adding it to the strike.
35 33
36 The strikes are held in a global list, available to all threads. To interact 34 The strikes are held in a global list, available to all threads. To interact with one, call
37 with one, call either VisitCache() or DetachCache(). 35 either VisitCache() or DetachCache().
38 */ 36 */
39 class SkGlyphCache { 37 class SkGlyphCache {
40 public: 38 public:
41 /** Returns a glyph with valid fAdvance and fDevKern fields. 39 /** Returns a glyph with valid fAdvance and fDevKern fields. The remaining f ields may be
42 The remaining fields may be valid, but that is not guaranteed. If you 40 valid, but that is not guaranteed. If you require those, call getUnichar Metrics or
43 require those, call getUnicharMetrics or getGlyphIDMetrics instead. 41 getGlyphIDMetrics instead.
44 */ 42 */
45 const SkGlyph& getUnicharAdvance(SkUnichar); 43 const SkGlyph& getUnicharAdvance(SkUnichar);
46 const SkGlyph& getGlyphIDAdvance(uint16_t); 44 const SkGlyph& getGlyphIDAdvance(uint16_t);
47 45
48 /** Returns a glyph with all fields valid except fImage and fPath, which 46 /** Returns a glyph with all fields valid except fImage and fPath, which may be null. If they
49 may be null. If they are null, call findImage or findPath for those. 47 are null, call findImage or findPath for those. If they are not null, th en they are valid.
50 If they are not null, then they are valid.
51 48
52 This call is potentially slower than the matching ...Advance call. If 49 This call is potentially slower than the matching ...Advance call. If yo u only need the
53 you only need the fAdvance/fDevKern fields, call those instead. 50 fAdvance/fDevKern fields, call those instead.
54 */ 51 */
55 const SkGlyph& getUnicharMetrics(SkUnichar); 52 const SkGlyph& getUnicharMetrics(SkUnichar);
56 const SkGlyph& getGlyphIDMetrics(uint16_t); 53 const SkGlyph& getGlyphIDMetrics(uint16_t);
57 54
58 /** These are variants that take the device position of the glyph. Call 55 /** These are variants that take the device position of the glyph. Call thes e only if you are
59 these only if you are drawing in subpixel mode. Passing 0, 0 is 56 drawing in subpixel mode. Passing 0, 0 is effectively the same as callin g the variants
60 effectively the same as calling the variants w/o the extra params, tho 57 w/o the extra params, though a tiny bit slower.
61 a tiny bit slower.
62 */ 58 */
63 const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y); 59 const SkGlyph& getUnicharMetrics(SkUnichar, SkFixed x, SkFixed y);
64 const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y); 60 const SkGlyph& getGlyphIDMetrics(uint16_t, SkFixed x, SkFixed y);
65 61
66 /** Return the glyphID for the specified Unichar. If the char has already 62 /** Return the glyphID for the specified Unichar. If the char has already be en seen, use the
67 been seen, use the existing cache entry. If not, ask the scalercontext 63 existing cache entry. If not, ask the scalercontext to compute it for us .
68 to compute it for us.
69 */ 64 */
70 uint16_t unicharToGlyph(SkUnichar); 65 uint16_t unicharToGlyph(SkUnichar);
71 66
72 /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to 67 /** Map the glyph to its Unicode equivalent. Unmappable glyphs map to a char acter code of zero.
73 a character code of zero.
74 */ 68 */
75 SkUnichar glyphToUnichar(uint16_t); 69 SkUnichar glyphToUnichar(uint16_t);
76 70
77 /** Returns the number of glyphs for this strike. 71 /** Returns the number of glyphs for this strike.
78 */ 72 */
79 unsigned getGlyphCount(); 73 unsigned getGlyphCount();
80 74
81 /** Return the image associated with the glyph. If it has not been generated 75 /** Return the image associated with the glyph. If it has not been generated this will
82 this will trigger that. 76 trigger that.
83 */ 77 */
84 const void* findImage(const SkGlyph&); 78 const void* findImage(const SkGlyph&);
85 /** Return the Path associated with the glyph. If it has not been generated 79
86 this will trigger that. 80 /** Return the Path associated with the glyph. If it has not been generated this will trigger
81 that.
87 */ 82 */
88 const SkPath* findPath(const SkGlyph&); 83 const SkPath* findPath(const SkGlyph&);
89 84
90 /** Return the vertical metrics for this strike. 85 /** Return the vertical metrics for this strike.
91 */ 86 */
92 const SkPaint::FontMetrics& getFontMetrics() const { 87 const SkPaint::FontMetrics& getFontMetrics() const {
93 return fFontMetrics; 88 return fFontMetrics;
94 } 89 }
95 90
96 const SkDescriptor& getDescriptor() const { return *fDesc; } 91 const SkDescriptor& getDescriptor() const { return *fDesc; }
97 92
98 SkMask::Format getMaskFormat() const { 93 SkMask::Format getMaskFormat() const {
99 return fScalerContext->getMaskFormat(); 94 return fScalerContext->getMaskFormat();
100 } 95 }
101 96
102 bool isSubpixel() const { 97 bool isSubpixel() const {
103 return fScalerContext->isSubpixel(); 98 return fScalerContext->isSubpixel();
104 } 99 }
105 100
106 void dump() const; 101 void dump() const;
107 102
108 /* AuxProc/Data allow a client to associate data with this cache entry. 103 /* AuxProc/Data allow a client to associate data with this cache entry. Mul tiple clients can
109 Multiple clients can use this, as their data is keyed with a function 104 use this, as their data is keyed with a function pointer. In addition to serving as a
110 pointer. In addition to serving as a key, the function pointer is called 105 key, the function pointer is called with the data when the glyphcache ob ject is deleted,
111 with the data when the glyphcache object is deleted, so the client can 106 so the client can cleanup their data as well.
112 cleanup their data as well. NOTE: the auxProc must not try to access 107 NOTE: the auxProc must not try to access this glyphcache in any way, sin ce it may be in
113 this glyphcache in any way, since it may be in the process of being 108 the process of being deleted.
114 deleted.
115 */ 109 */
116 110
117 //! If the proc is found, return true and set *dataPtr to its data 111 //! If the proc is found, return true and set *dataPtr to its data
118 bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const; 112 bool getAuxProcData(void (*auxProc)(void*), void** dataPtr) const;
113
119 //! Add a proc/data pair to the glyphcache. proc should be non-null 114 //! Add a proc/data pair to the glyphcache. proc should be non-null
120 void setAuxProc(void (*auxProc)(void*), void* auxData); 115 void setAuxProc(void (*auxProc)(void*), void* auxData);
121 116
122 SkScalerContext* getScalerContext() const { return fScalerContext; } 117 SkScalerContext* getScalerContext() const { return fScalerContext; }
123 118
124 /** Find a matching cache entry, and call proc() with it. If none is found 119 /** Find a matching cache entry, and call proc() with it. If none is found c reate a new one.
125 create a new one. If the proc() returns true, detach the cache and 120 If the proc() returns true, detach the cache and return it, otherwise le ave it and return
126 return it, otherwise leave it and return NULL. 121 NULL.
127 */ 122 */
128 static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc, 123 static SkGlyphCache* VisitCache(SkTypeface*, const SkDescriptor* desc,
129 bool (*proc)(const SkGlyphCache*, void*), 124 bool (*proc)(const SkGlyphCache*, void*),
130 void* context); 125 void* context);
131 126
132 /** Given a strike that was returned by either VisitCache() or DetachCache() 127 /** Given a strike that was returned by either VisitCache() or DetachCache() add it back into
133 add it back into the global cache list (after which the caller should 128 the global cache list (after which the caller should not reference it an ymore.
134 not reference it anymore.
135 */ 129 */
136 static void AttachCache(SkGlyphCache*); 130 static void AttachCache(SkGlyphCache*);
137 131
138 /** Detach a strike from the global cache matching the specified descriptor. 132 /** Detach a strike from the global cache matching the specified descriptor. Once detached,
139 Once detached, it can be queried/modified by the current thread, and 133 it can be queried/modified by the current thread, and when finished, be reattached to the
140 when finished, be reattached to the global cache with AttachCache(). 134 global cache with AttachCache(). While detached, if another request is m ade with the same
141 While detached, if another request is made with the same descriptor, 135 descriptor, a different strike will be generated. This is fine. It does mean we can have
142 a different strike will be generated. This is fine. It does mean we 136 more than 1 strike for the same descriptor, but that will eventually get purged, and the
143 can have more than 1 strike for the same descriptor, but that will 137 win is that different thread will never block each other while a strike is being used.
144 eventually get purged, and the win is that different thread will never
145 block each other while a strike is being used.
146 */ 138 */
147 static SkGlyphCache* DetachCache(SkTypeface* typeface, 139 static SkGlyphCache* DetachCache(SkTypeface* typeface, const SkDescriptor* d esc) {
148 const SkDescriptor* desc) {
149 return VisitCache(typeface, desc, DetachProc, NULL); 140 return VisitCache(typeface, desc, DetachProc, NULL);
150 } 141 }
151 142
152 static void Dump(); 143 static void Dump();
153 144
154 #ifdef SK_DEBUG 145 #ifdef SK_DEBUG
155 void validate() const; 146 void validate() const;
156 #else 147 #else
157 void validate() const {} 148 void validate() const {}
158 #endif 149 #endif
(...skipping 11 matching lines...) Expand all
170 } 161 }
171 } 162 }
172 void forget() { 163 void forget() {
173 fCache = NULL; 164 fCache = NULL;
174 } 165 }
175 private: 166 private:
176 const SkGlyphCache* fCache; 167 const SkGlyphCache* fCache;
177 }; 168 };
178 169
179 private: 170 private:
180 // we take ownership of the scalercontext 171 friend class SkGlyphCache_Globals;
181 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*);
182 ~SkGlyphCache();
183 172
184 enum MetricsType { 173 enum MetricsType {
185 kJustAdvance_MetricsType, 174 kJustAdvance_MetricsType,
186 kFull_MetricsType 175 kFull_MetricsType
187 }; 176 };
188 177
189 // Return the SkGlyph* associated with MakeID. The id parameter is the combi ned glyph/x/y
190 // id generated by MakeID. If it is just a glyph id then x and y are assuemd to be zero.
191 SkGlyph* lookupByCombinedID(uint32_t id, MetricsType type);
192
193 // Return a SkGlyph* associated with unicode id and position x and y.
194 SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed y = 0);
195
196 // Return the index of id in the fGlyphArray. If it does
197 // not exist, create a new one using MetricsType.
198 uint16_t lookupMetrics(uint32_t id, MetricsType type);
199 static bool DetachProc(const SkGlyphCache*, void*) { return true; }
200
201 SkGlyphCache* fNext, *fPrev;
202 SkDescriptor* fDesc;
203 SkScalerContext* fScalerContext;
204 SkPaint::FontMetrics fFontMetrics;
205
206 enum { 178 enum {
207 kHashBits = 8, 179 kHashBits = 8,
208 kHashCount = 1 << kHashBits, 180 kHashCount = 1 << kHashBits,
209 kHashMask = kHashCount - 1 181 kHashMask = kHashCount - 1
210 }; 182 };
211 183
212 // A quick lookup to avoid the binary search looking for glyphs in fGlyphArr ay.
213 uint16_t fGlyphHash[kHashCount];
214 // Contains the SkGlyphs that are used by fGlyphHash and fCharToGlyphHash. T he zero element
215 // is reserved for a sentinel SkGlyph that reduces the logic to check for co llisions in the
216 // hash arrays. The zero element has an fID of SkGlyph::kImpossibleID which never matches
217 // any combined id generated for a char or a glyph.
218 SkTDArray<SkGlyph> fGlyphArray;
219 SkChunkAlloc fGlyphAlloc;
220
221 struct CharGlyphRec { 184 struct CharGlyphRec {
222 uint32_t fID; // unichar + subpixel 185 uint32_t fID; // unichar + subpixel
223 uint16_t fGlyphIndex; 186 uint16_t fGlyphIndex;
224 }; 187 };
225 188
226 // no reason to use the same kHashCount as fGlyphHash, but we do for now 189 struct AuxProcRec {
227 // Dynamically allocated when chars are encountered. 190 AuxProcRec* fNext;
228 SkAutoTArray<CharGlyphRec> fCharToGlyphHash; 191 void (*fProc)(void*);
192 void* fData;
193 };
194
195 // SkGlyphCache takes ownership of the scalercontext.
196 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*);
197 ~SkGlyphCache();
198
199 // Return the SkGlyph* associated with MakeID. The id parameter is the
200 // combined glyph/x/y id generated by MakeID. If it is just a glyph id
201 // then x and y are assumed to be zero.
202 SkGlyph* lookupByCombinedID(uint32_t id, MetricsType type);
203
204 // Return a SkGlyph* associated with unicode id and position x and y.
205 SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed y = 0);
206
207 // Return the index of id in the fGlyphArray. If it does not exist,
208 // create a new one using MetricsType.
209 uint16_t lookupMetrics(uint32_t id, MetricsType type);
210 static bool DetachProc(const SkGlyphCache*, void*) { return true; }
229 211
230 // The id arg is a combined id generated by MakeID. 212 // The id arg is a combined id generated by MakeID.
231 CharGlyphRec* getCharGlyphRec(uint32_t id); 213 CharGlyphRec* getCharGlyphRec(uint32_t id);
232 void adjustCaches(int insertion_index); 214 void adjustCaches(int insertion_index);
233 215
234 static inline unsigned ID2HashIndex(uint32_t h) { 216 static inline unsigned ID2HashIndex(uint32_t h) {
235 return SkChecksum::CheapMix(h) & kHashMask; 217 return SkChecksum::CheapMix(h) & kHashMask;
236 } 218 }
237 219
220 void invokeAndRemoveAuxProcs();
221
222 inline static SkGlyphCache* FindTail(SkGlyphCache* head);
223
224 SkGlyphCache* fNext, *fPrev;
225 SkDescriptor* fDesc;
226 SkScalerContext* fScalerContext;
227 SkPaint::FontMetrics fFontMetrics;
228
229 // A quick lookup to avoid the binary search looking for glyphs in fGlyphArr ay.
230 uint16_t fGlyphHash[kHashCount];
231
232 // Contains the SkGlyphs that are used by fGlyphHash and fCharToGlyphHash. T he ~0 element is
233 // reserved for a sentinel SkGlyph that reduces the logic to check for colli sions in the hash
234 // arrays. The ~0 element has an fID of SkGlyph::kImpossibleID which never m atches any
235 // combined id generated for a char or a glyph.
236 SkTDArray<SkGlyph> fGlyphArray;
237 SkChunkAlloc fGlyphAlloc;
238
239 // no reason to use the same kHashCount as fGlyphHash, but we do for now
240 // Dynamically allocated when chars are encountered.
241 SkAutoTArray<CharGlyphRec> fCharToGlyphHash;
242
238 // used to track (approx) how much ram is tied-up in this cache 243 // used to track (approx) how much ram is tied-up in this cache
239 size_t fMemoryUsed; 244 size_t fMemoryUsed;
240 245
241 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS 246 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
242 int fHashHitCount; 247 int fHashHitCount;
243 int fHashMissCount; 248 int fHashMissCount;
244 #endif 249 #endif
245 250
246 struct AuxProcRec {
247 AuxProcRec* fNext;
248 void (*fProc)(void*);
249 void* fData;
250 };
251 AuxProcRec* fAuxProcList; 251 AuxProcRec* fAuxProcList;
252 void invokeAndRemoveAuxProcs();
253
254 inline static SkGlyphCache* FindTail(SkGlyphCache* head);
255
256 friend class SkGlyphCache_Globals;
257 }; 252 };
258 253
259 class SkAutoGlyphCacheBase { 254 class SkAutoGlyphCacheBase {
260 public: 255 public:
261 SkGlyphCache* getCache() const { return fCache; } 256 SkGlyphCache* getCache() const { return fCache; }
262 257
263 void release() { 258 void release() {
264 if (fCache) { 259 if (fCache) {
265 SkGlyphCache::AttachCache(fCache); 260 SkGlyphCache::AttachCache(fCache);
266 fCache = NULL; 261 fCache = NULL;
267 } 262 }
268 } 263 }
269 264
270 protected: 265 protected:
271 // Hide the constructors so we can't create one of these directly. 266 // Hide the constructors so we can't create one of these directly. Create Sk AutoGlyphCache or
272 // Create SkAutoGlyphCache or SkAutoGlyphCacheNoCache instead. 267 // SkAutoGlyphCacheNoCache instead.
273 SkAutoGlyphCacheBase(SkGlyphCache* cache) : fCache(cache) {} 268 SkAutoGlyphCacheBase(SkGlyphCache* cache) : fCache(cache) {}
274 SkAutoGlyphCacheBase(SkTypeface* typeface, const SkDescriptor* desc) { 269 SkAutoGlyphCacheBase(SkTypeface* typeface, const SkDescriptor* desc) {
275 fCache = SkGlyphCache::DetachCache(typeface, desc); 270 fCache = SkGlyphCache::DetachCache(typeface, desc);
276 } 271 }
277 SkAutoGlyphCacheBase(const SkPaint& /*paint*/, 272 SkAutoGlyphCacheBase(const SkPaint& /*paint*/,
278 const SkSurfaceProps* /*surfaceProps*/, 273 const SkSurfaceProps* /*surfaceProps*/,
279 const SkMatrix* /*matrix*/) { 274 const SkMatrix* /*matrix*/) {
280 fCache = NULL; 275 fCache = NULL;
281 } 276 }
282 SkAutoGlyphCacheBase() { 277 SkAutoGlyphCacheBase() {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 const SkMatrix* matrix) { 315 const SkMatrix* matrix) {
321 fCache = paint.detachCache(surfaceProps, matrix, true); 316 fCache = paint.detachCache(surfaceProps, matrix, true);
322 } 317 }
323 318
324 private: 319 private:
325 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} 320 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {}
326 }; 321 };
327 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a) 322 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a)
328 323
329 #endif 324 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698