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

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

Issue 877113002: use murmur3 finisher to improve font hash efficiency (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add CheapMix helper" Created 5 years, 10 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/SkGlyphCache.h ('k') | src/core/SkScalerContext.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1
2 /* 1 /*
3 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
4 * 3 *
5 * 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
6 * found in the LICENSE file. 5 * found in the LICENSE file.
7 */ 6 */
8 7
9
10 #include "SkGlyphCache.h" 8 #include "SkGlyphCache.h"
11 #include "SkGlyphCache_Globals.h" 9 #include "SkGlyphCache_Globals.h"
12 #include "SkGraphics.h" 10 #include "SkGraphics.h"
13 #include "SkLazyPtr.h" 11 #include "SkLazyPtr.h"
14 #include "SkPaint.h" 12 #include "SkPaint.h"
15 #include "SkPath.h" 13 #include "SkPath.h"
16 #include "SkTemplates.h" 14 #include "SkTemplates.h"
17 #include "SkTLS.h" 15 #include "SkTLS.h"
18 #include "SkTypeface.h" 16 #include "SkTypeface.h"
19 17
20 //#define SPEW_PURGE_STATUS 18 //#define SPEW_PURGE_STATUS
21 //#define RECORD_HASH_EFFICIENCY
22 19
23 namespace { 20 namespace {
24 21
25 SkGlyphCache_Globals* create_globals() { 22 SkGlyphCache_Globals* create_globals() {
26 return SkNEW_ARGS(SkGlyphCache_Globals, (SkGlyphCache_Globals::kYes_UseMutex )); 23 return SkNEW_ARGS(SkGlyphCache_Globals, (SkGlyphCache_Globals::kYes_UseMutex ));
27 } 24 }
28 25
29 } // namespace 26 } // namespace
30 27
31 SK_DECLARE_STATIC_LAZY_PTR(SkGlyphCache_Globals, globals, create_globals); 28 SK_DECLARE_STATIC_LAZY_PTR(SkGlyphCache_Globals, globals, create_globals);
32 29
33 // Returns the shared globals 30 // Returns the shared globals
34 static SkGlyphCache_Globals& getSharedGlobals() { 31 static SkGlyphCache_Globals& getSharedGlobals() {
35 return *globals.get(); 32 return *globals.get();
36 } 33 }
37 34
38 // Returns the TLS globals (if set), or the shared globals 35 // Returns the TLS globals (if set), or the shared globals
39 static SkGlyphCache_Globals& getGlobals() { 36 static SkGlyphCache_Globals& getGlobals() {
40 SkGlyphCache_Globals* tls = SkGlyphCache_Globals::FindTLS(); 37 SkGlyphCache_Globals* tls = SkGlyphCache_Globals::FindTLS();
41 return tls ? *tls : getSharedGlobals(); 38 return tls ? *tls : getSharedGlobals();
42 } 39 }
43 40
44 /////////////////////////////////////////////////////////////////////////////// 41 ///////////////////////////////////////////////////////////////////////////////
45 42
46 #ifdef RECORD_HASH_EFFICIENCY 43 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
47 static uint32_t gHashSuccess; 44 #define RecordHashSuccess() fHashHitCount += 1
48 static uint32_t gHashCollision; 45 #define RecordHashCollisionIf(pred) do { if (pred) fHashMissCount += 1; } while (0)
49
50 static void RecordHashSuccess() {
51 gHashSuccess += 1;
52 }
53
54 static void RecordHashCollisionIf(bool pred) {
55 if (pred) {
56 gHashCollision += 1;
57
58 uint32_t total = gHashSuccess + gHashCollision;
59 SkDebugf("Font Cache Hash success rate: %d%%\n",
60 100 * gHashSuccess / total);
61 }
62 }
63 #else 46 #else
64 #define RecordHashSuccess() (void)0 47 #define RecordHashSuccess() (void)0
65 #define RecordHashCollisionIf(pred) (void)0 48 #define RecordHashCollisionIf(pred) (void)0
66 #endif 49 #endif
67 #define RecordHashCollision() RecordHashCollisionIf(true) 50 #define RecordHashCollision() RecordHashCollisionIf(true)
68 51
69 /////////////////////////////////////////////////////////////////////////////// 52 ///////////////////////////////////////////////////////////////////////////////
70 53
71 // so we don't grow our arrays a lot 54 // so we don't grow our arrays a lot
72 #define kMinGlyphCount 16 55 #define kMinGlyphCount 16
73 #define kMinGlyphImageSize (16*2) 56 #define kMinGlyphImageSize (16*2)
74 #define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphC ount) 57 #define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphC ount)
75 58
(...skipping 11 matching lines...) Expand all
87 // init to 0 so that all of the pointers will be null 70 // init to 0 so that all of the pointers will be null
88 memset(fGlyphHash, 0, sizeof(fGlyphHash)); 71 memset(fGlyphHash, 0, sizeof(fGlyphHash));
89 // init with 0xFF so that the charCode field will be -1, which is invalid 72 // init with 0xFF so that the charCode field will be -1, which is invalid
90 memset(fCharToGlyphHash, 0xFF, sizeof(fCharToGlyphHash)); 73 memset(fCharToGlyphHash, 0xFF, sizeof(fCharToGlyphHash));
91 74
92 fMemoryUsed = sizeof(*this); 75 fMemoryUsed = sizeof(*this);
93 76
94 fGlyphArray.setReserve(kMinGlyphCount); 77 fGlyphArray.setReserve(kMinGlyphCount);
95 78
96 fAuxProcList = NULL; 79 fAuxProcList = NULL;
80
81 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
82 fHashHitCount = fHashMissCount = 0;
83 #endif
97 } 84 }
98 85
99 SkGlyphCache::~SkGlyphCache() { 86 SkGlyphCache::~SkGlyphCache() {
100 #if 0 87 #if 0
101 { 88 {
102 size_t ptrMem = fGlyphArray.count() * sizeof(SkGlyph*); 89 size_t ptrMem = fGlyphArray.count() * sizeof(SkGlyph*);
103 size_t glyphAlloc = fGlyphAlloc.totalCapacity(); 90 size_t glyphAlloc = fGlyphAlloc.totalCapacity();
104 size_t glyphHashUsed = 0; 91 size_t glyphHashUsed = 0;
105 size_t uniHashUsed = 0; 92 size_t uniHashUsed = 0;
106 for (int i = 0; i < kHashCount; ++i) { 93 for (int i = 0; i < kHashCount; ++i) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } else { 240 } else {
254 RecordHashSuccess(); 241 RecordHashSuccess();
255 if (glyph->isJustAdvance()) { 242 if (glyph->isJustAdvance()) {
256 fScalerContext->getMetrics(glyph); 243 fScalerContext->getMetrics(glyph);
257 } 244 }
258 } 245 }
259 SkASSERT(glyph->isFullMetrics()); 246 SkASSERT(glyph->isFullMetrics());
260 return *glyph; 247 return *glyph;
261 } 248 }
262 249
263 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, 250 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi xed y) {
264 SkFixed x, SkFixed y) {
265 VALIDATE(); 251 VALIDATE();
266 uint32_t id = SkGlyph::MakeID(glyphID, x, y); 252 uint32_t id = SkGlyph::MakeID(glyphID, x, y);
267 unsigned index = ID2HashIndex(id); 253 unsigned index = ID2HashIndex(id);
268 SkGlyph* glyph = fGlyphHash[index]; 254 SkGlyph* glyph = fGlyphHash[index];
269 255
270 if (NULL == glyph || glyph->fID != id) { 256 if (NULL == glyph || glyph->fID != id) {
271 RecordHashCollisionIf(glyph != NULL); 257 RecordHashCollisionIf(glyph != NULL);
272 glyph = this->lookupMetrics(id, kFull_MetricsType); 258 glyph = this->lookupMetrics(id, kFull_MetricsType);
273 fGlyphHash[index] = glyph; 259 fGlyphHash[index] = glyph;
274 } else { 260 } else {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 if (glyph.fPath == NULL) { 343 if (glyph.fPath == NULL) {
358 const_cast<SkGlyph&>(glyph).fPath = SkNEW(SkPath); 344 const_cast<SkGlyph&>(glyph).fPath = SkNEW(SkPath);
359 fScalerContext->getPath(glyph, glyph.fPath); 345 fScalerContext->getPath(glyph, glyph.fPath);
360 fMemoryUsed += sizeof(SkPath) + 346 fMemoryUsed += sizeof(SkPath) +
361 glyph.fPath->countPoints() * sizeof(SkPoint); 347 glyph.fPath->countPoints() * sizeof(SkPoint);
362 } 348 }
363 } 349 }
364 return glyph.fPath; 350 return glyph.fPath;
365 } 351 }
366 352
353 void SkGlyphCache::dump() const {
354 const SkTypeface* face = fScalerContext->getTypeface();
355 const SkScalerContextRec& rec = fScalerContext->getRec();
356 SkMatrix matrix;
357 rec.getSingleMatrix(&matrix);
358 matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize) );
359 SkString name;
360 face->getFamilyName(&name);
361
362 SkString msg;
363 msg.printf("cache typeface:%x %25s:%d size:%2g [%g %g %g %g] lum:%02X devG:% d pntG:%d cntr:%d glyphs:%3d",
364 face->uniqueID(), name.c_str(), face->style(), rec.fTextSize,
365 matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewX],
366 matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMScaleY],
367 rec.fLumBits & 0xFF, rec.fDeviceGamma, rec.fPaintGamma, rec.fCont rast,
368 fGlyphArray.count());
369 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
370 const int sum = SkTMax(fHashHitCount + fHashMissCount, 1); // avoid divide -by-zero
371 msg.appendf(" hash:%2d\n", 100 * fHashHitCount / sum);
372 #endif
373 SkDebugf("%s\n", msg.c_str());
374 }
375
367 /////////////////////////////////////////////////////////////////////////////// 376 ///////////////////////////////////////////////////////////////////////////////
368 377
369 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const { 378 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const {
370 const AuxProcRec* rec = fAuxProcList; 379 const AuxProcRec* rec = fAuxProcList;
371 while (rec) { 380 while (rec) {
372 if (rec->fProc == proc) { 381 if (rec->fProc == proc) {
373 if (dataPtr) { 382 if (dataPtr) {
374 *dataPtr = rec->fData; 383 *dataPtr = rec->fData;
375 } 384 }
376 return true; 385 return true;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 return cache; 522 return cache;
514 } 523 }
515 524
516 void SkGlyphCache::AttachCache(SkGlyphCache* cache) { 525 void SkGlyphCache::AttachCache(SkGlyphCache* cache) {
517 SkASSERT(cache); 526 SkASSERT(cache);
518 SkASSERT(cache->fNext == NULL); 527 SkASSERT(cache->fNext == NULL);
519 528
520 getGlobals().attachCacheToHead(cache); 529 getGlobals().attachCacheToHead(cache);
521 } 530 }
522 531
532 void SkGlyphCache::Dump() {
533 SkGlyphCache_Globals& globals = getGlobals();
534 SkAutoMutexAcquire ac(globals.fMutex);
535 SkGlyphCache* cache;
536
537 globals.validate();
538
539 SkDebugf("SkGlyphCache strikes:%d memory:%d\n",
540 globals.getCacheCountUsed(), (int)globals.getTotalMemoryUsed());
541
542 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
543 int hitCount = 0;
544 int missCount = 0;
545 #endif
546
547 for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext) {
548 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
549 hitCount += cache->fHashHitCount;
550 missCount += cache->fHashMissCount;
551 #endif
552 cache->dump();
553 }
554 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
555 SkDebugf("Hash hit percent:%2d\n", 100 * hitCount / (hitCount + missCount));
556 #endif
557 }
558
523 /////////////////////////////////////////////////////////////////////////////// 559 ///////////////////////////////////////////////////////////////////////////////
524 560
525 void SkGlyphCache_Globals::attachCacheToHead(SkGlyphCache* cache) { 561 void SkGlyphCache_Globals::attachCacheToHead(SkGlyphCache* cache) {
526 SkAutoMutexAcquire ac(fMutex); 562 SkAutoMutexAcquire ac(fMutex);
527 563
528 this->validate(); 564 this->validate();
529 cache->validate(); 565 cache->validate();
530 566
531 this->internalAttachCacheToHead(cache); 567 this->internalAttachCacheToHead(cache);
532 this->internalPurge(); 568 this->internalPurge();
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 return tls ? tls->getCacheSizeLimit() : 0; 737 return tls ? tls->getCacheSizeLimit() : 0;
702 } 738 }
703 739
704 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { 740 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) {
705 if (0 == bytes) { 741 if (0 == bytes) {
706 SkGlyphCache_Globals::DeleteTLS(); 742 SkGlyphCache_Globals::DeleteTLS();
707 } else { 743 } else {
708 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); 744 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes);
709 } 745 }
710 } 746 }
OLDNEW
« no previous file with comments | « src/core/SkGlyphCache.h ('k') | src/core/SkScalerContext.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698