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

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

Issue 1216983003: Move the GlyphCache to use a hash table instead of doing its own ad-hoc (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address mtklein's comments Created 5 years, 5 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 | « src/core/SkGlyph.h ('k') | src/core/SkGlyphCache.cpp » ('j') | 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 found in the LICENSE file. 4 * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
5 */ 5 */
6 6
7 #ifndef SkGlyphCache_DEFINED 7 #ifndef SkGlyphCache_DEFINED
8 #define SkGlyphCache_DEFINED 8 #define SkGlyphCache_DEFINED
9 9
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
11 #include "SkChecksum.h"
12 #include "SkChunkAlloc.h" 11 #include "SkChunkAlloc.h"
13 #include "SkDescriptor.h" 12 #include "SkDescriptor.h"
14 #include "SkGlyph.h" 13 #include "SkGlyph.h"
14 #include "SkTHash.h"
15 #include "SkScalerContext.h" 15 #include "SkScalerContext.h"
16 #include "SkTemplates.h" 16 #include "SkTemplates.h"
17 #include "SkTDArray.h" 17 #include "SkTDArray.h"
18 18
19 class SkPaint; 19 class SkPaint;
20 20
21 class SkGlyphCache_Globals; 21 class SkGlyphCache_Globals;
22 22
23 // Enable this locally to add stats for hash-table hit rates. It also extends th e dump() output
24 // to show those stats.
25 //#define SK_GLYPHCACHE_TRACK_HASH_STATS
26
27 /** \class SkGlyphCache 23 /** \class SkGlyphCache
28 24
29 This class represents a strike: a specific combination of typeface, size, ma trix, etc., and 25 This class represents a strike: a specific combination of typeface, size, ma trix, etc., and
30 holds the glyphs for that strike. Calling any of the getUnichar.../getGlyphI D... methods will 26 holds the glyphs for that strike. Calling any of the getUnichar.../getGlyphI D... methods will
31 return the requested glyph, either instantly if it is already cached, or by first generating 27 return the requested glyph, either instantly if it is already cached, or by first generating
32 it and then adding it to the strike. 28 it and then adding it to the strike.
33 29
34 The strikes are held in a global list, available to all threads. To interact with one, call 30 The strikes are held in a global list, available to all threads. To interact with one, call
35 either VisitCache() or DetachCache(). 31 either VisitCache() or DetachCache().
36 */ 32 */
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 kJustAdvance_MetricsType, 170 kJustAdvance_MetricsType,
175 kFull_MetricsType 171 kFull_MetricsType
176 }; 172 };
177 173
178 enum { 174 enum {
179 kHashBits = 8, 175 kHashBits = 8,
180 kHashCount = 1 << kHashBits, 176 kHashCount = 1 << kHashBits,
181 kHashMask = kHashCount - 1 177 kHashMask = kHashCount - 1
182 }; 178 };
183 179
180 typedef uint32_t PackedGlyphID; // glyph-index + subpixel-pos
181 typedef uint32_t PackedUnicharID; // unichar + subpixel-pos
182
184 struct CharGlyphRec { 183 struct CharGlyphRec {
185 uint32_t fID; // unichar + subpixel 184 PackedUnicharID fPackedUnicharID;
186 uint16_t fGlyphIndex; 185 PackedGlyphID fPackedGlyphID;
187 }; 186 };
188 187
189 struct AuxProcRec { 188 struct AuxProcRec {
190 AuxProcRec* fNext; 189 AuxProcRec* fNext;
191 void (*fProc)(void*); 190 void (*fProc)(void*);
192 void* fData; 191 void* fData;
193 }; 192 };
194 193
195 // SkGlyphCache takes ownership of the scalercontext. 194 // SkGlyphCache takes ownership of the scalercontext.
196 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*); 195 SkGlyphCache(SkTypeface*, const SkDescriptor*, SkScalerContext*);
197 ~SkGlyphCache(); 196 ~SkGlyphCache();
198 197
199 // Return the SkGlyph* associated with MakeID. The id parameter is the 198 // 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 199 // 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. 200 // then x and y are assumed to be zero.
202 SkGlyph* lookupByCombinedID(uint32_t id, MetricsType type); 201 SkGlyph* lookupByPackedGlyphID(PackedGlyphID packedGlyphID, MetricsType type );
203 202
204 // Return a SkGlyph* associated with unicode id and position x and y. 203 // 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); 204 SkGlyph* lookupByChar(SkUnichar id, MetricsType type, SkFixed x = 0, SkFixed y = 0);
206 205
207 // Return the index of id in the fGlyphArray. If it does not exist, 206 // Return a new SkGlyph for the glyph ID and subpixel position id. Limit the amount
208 // create a new one using MetricsType. 207 // of work
209 uint16_t lookupMetrics(uint32_t id, MetricsType type); 208 // using type.
209 SkGlyph* allocateNewGlyph(PackedGlyphID packedGlyphID, MetricsType type);
210
210 static bool DetachProc(const SkGlyphCache*, void*) { return true; } 211 static bool DetachProc(const SkGlyphCache*, void*) { return true; }
211 212
212 // The id arg is a combined id generated by MakeID. 213 // The id arg is a combined id generated by MakeID.
213 CharGlyphRec* getCharGlyphRec(uint32_t id); 214 CharGlyphRec* getCharGlyphRec(PackedUnicharID id);
214 void adjustCaches(int insertion_index);
215
216 static inline unsigned ID2HashIndex(uint32_t h) {
217 return SkChecksum::CheapMix(h) & kHashMask;
218 }
219 215
220 void invokeAndRemoveAuxProcs(); 216 void invokeAndRemoveAuxProcs();
221 217
222 inline static SkGlyphCache* FindTail(SkGlyphCache* head); 218 inline static SkGlyphCache* FindTail(SkGlyphCache* head);
223 219
224 SkGlyphCache* fNext, *fPrev; 220 SkGlyphCache* fNext;
225 SkDescriptor* fDesc; 221 SkGlyphCache* fPrev;
226 SkScalerContext* fScalerContext; 222 SkDescriptor* const fDesc;
227 SkPaint::FontMetrics fFontMetrics; 223 SkScalerContext* const fScalerContext;
224 SkPaint::FontMetrics fFontMetrics;
228 225
229 // A quick lookup to avoid the binary search looking for glyphs in fGlyphArr ay. 226 // Map from a combined GlyphID and sub-pixel position to a SkGlyph.
230 uint16_t fGlyphHash[kHashCount]; 227 SkTHashTable<SkGlyph, PackedGlyphID, SkGlyph::HashTraits> fGlyphMap;
231 228
232 // Contains the SkGlyphs that are used by fGlyphHash and fCharToGlyphHash. T he ~0 element is 229 SkChunkAlloc fGlyphAlloc;
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 230
239 // no reason to use the same kHashCount as fGlyphHash, but we do for now 231 SkAutoTArray<CharGlyphRec> fPackedUnicharIDToPackedGlyphID;
240 // Dynamically allocated when chars are encountered.
241 SkAutoTArray<CharGlyphRec> fCharToGlyphHash;
242 232
243 // used to track (approx) how much ram is tied-up in this cache 233 // used to track (approx) how much ram is tied-up in this cache
244 size_t fMemoryUsed; 234 size_t fMemoryUsed;
245 235
246 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS 236 AuxProcRec* fAuxProcList;
247 int fHashHitCount;
248 int fHashMissCount;
249 #endif
250
251 AuxProcRec* fAuxProcList;
252 }; 237 };
253 238
254 class SkAutoGlyphCacheBase { 239 class SkAutoGlyphCacheBase {
255 public: 240 public:
256 SkGlyphCache* getCache() const { return fCache; } 241 SkGlyphCache* getCache() const { return fCache; }
257 242
258 void release() { 243 void release() {
259 if (fCache) { 244 if (fCache) {
260 SkGlyphCache::AttachCache(fCache); 245 SkGlyphCache::AttachCache(fCache);
261 fCache = NULL; 246 fCache = NULL;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 const SkMatrix* matrix) { 300 const SkMatrix* matrix) {
316 fCache = paint.detachCache(surfaceProps, matrix, true); 301 fCache = paint.detachCache(surfaceProps, matrix, true);
317 } 302 }
318 303
319 private: 304 private:
320 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {} 305 SkAutoGlyphCacheNoGamma() : SkAutoGlyphCacheBase() {}
321 }; 306 };
322 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a) 307 #define SkAutoGlyphCacheNoGamma(...) SK_REQUIRE_LOCAL_VAR(SkAutoGlyphCacheNoGamm a)
323 308
324 #endif 309 #endif
OLDNEW
« no previous file with comments | « src/core/SkGlyph.h ('k') | src/core/SkGlyphCache.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698